Matchmaking Around Blocked Users #

Nakama’s matchmaker can be used to bring users together for any type of social gameplay or interaction available in your application. As with any community, some users will get along and some will not.

When a user has blocked another, ideally these two users should not be placed in the same match, group, or other such social feature by the matchmaker.

This guide provides one approach you can use to ensure no user is matched with someone they have blocked. This involves:

  • Looking up each user’s list of blocked users
  • Using that list as part of their respective matchmaker properties
  • Adding a clause to their matchmaker query to avoid matching blocked users

Listing blocked users #

Use the Friends Listing API, filtering only users in a blocked state, to get a complete list of all users this player has blocked.

Client
1
2
var blockedState = 3;
var blockedFriendsResult = await client.ListFriendsAsync(session, blockedState, 100, null);
Client
1
2
const blockedState = 3;
const blockedFriendsResult = await client.listFriends(session, null, blockedState);
Client
1
2
3
4
5
6
7
int blockedState = 3;
auto successCallback = [](NFriendsPtr blockedFriendsResult)
{
  // Blocked friends available as blockedFriendsResult->friends
};

client->listFriends(session, {}, blockedState, {}, successCallback);
Client
1
2
var blocked_state = 3
var blocked_friends_result : NakamaAPI.ApiFriendList = yield(client.list_friends_async(session, blocked_state), "completed")
Client
1
2
var blocked_state = 3
var blocked_friends_result : NakamaAPI.ApiFriendList = await client.list_friends_async(session, blocked_state)
Client
1
2
3
local limit = 100
local blocked_state = 3
local blocked_friends_result = client.list_friends(limit, blocked_state)

Code snippet for this language Java/Android has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.

You need to write the complete list of blocked user IDs into a space-separated string (e.g. user-id-1 user-id-2 user-id-3) that will be part of the user’s matchmaker properties.

Client
1
var blockedFriendIds = string.Join(" ", blockedFriendsResult.Friends.Select(x => x.User.Id));
Client
1
const blockedFriendIds = blockedFriendsResult.friends.map(friend => friend.userId).join(' ');
Client
1
2
3
4
5
6
7
auto successCallback = [](NFriendListPtr blockedFriendsResult)
{
  string blockedFriendIds = "";
  for (NFriend friend : blockedFriendsResult->friends) {
    blockedFriendIdsString += friend.user.id + " ";
  }
};
Client
1
2
3
4
var blocked_friend_ids = ""

for friend in blocked_friends_result.friends:
  blocked_friend_ids += friend.user.id + " "
Client
1
2
3
4
var blocked_friend_ids = ""

for friend in blocked_friends_result.friends:
  blocked_friend_ids += friend.user.id + " "
Client
1
2
3
4
local blocked_friend_ids = ""
for i,friend in ipairs(blocked_friends_result.friends) do
  blocked_friend_ids = blocked_friend_ids .. friend.user.id .. " "
end

Code snippet for this language Java/Android has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.

Matchmaker criteria #

Each user’s matchmaker criteria will now include an additional property, using the key blocked, of the concatenated string of blocked users created above.

Client
1
2
3
4
var stringProperties = new Dictionary<string, string>
{
    { "blocked", blockedFriendIds }
}; 
Client
1
2
3
const stringProperties = {
  "blocked": blockedFriendIds
};
Client
1
2
NStringMap stringProperties;
stringProperties.emplace("blocked", blockedFriendIds);
Client
1
var string_properties = { "blocked", blocked_friend_ids }
Client
1
var string_properties = { "blocked", blocked_friend_ids }
Client
1
local string_properties = { blocked = blocked_friend_ids }

Code snippet for this language Java/Android has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.

Along with the new property, each user’s matchmaker query will also have a new must not clause in the form -properties.blocked:/.*my\-user\-id.*/.

By using the player’s own ID, this clause ensure that the searching player does not appear in the blocked list of any potential match - i.e. that this player is not matched with any player that has blocked them and, ultimately, no player is matched with anyone they have blocked.

The complete matchmaker request would look like:

Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var blockedState = 3;
var blockedFriendsResult = await client.ListFriendsAsync(session, blockedState, 100, null);
var blockedFriendIds = string.Join(" ", blockedFriendsResult.Friends.Select(x => x.User.Id));]

var stringProperties = new Dictionary<string, string>
{
    { "blocked", blockedFriendIds }
};

var ticket =
    await socket.AddMatchmakerAsync($"-properties.blocked:/.*{session.UserId}.*/", 2, 4, stringProperties, null);
Client
1
2
3
4
5
6
7
8
9
const blockedState = 3;
const blockedFriendsResult = await client.listFriends(session, null, blockedState);
const blockedFriendIds = blockedFriendsResult.friends.map(friend => friend.userId).join(' ');

const stringProperties = {
  "blocked": blockedFriendIds
};

const ticket = await socket.addMatchmaker(`-properties.blocked:/.*${session.userId}.*/`, 2, 4, stringProperties, null);
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
int blockedState = 3;
auto successCallback = [](NFriendsPtr blockedFriendsResult)
{
  string blockedFriendIds = "";
  for (NFriend friend : blockedFriendsResult->friends) {
    blockedFriendIds += friend.user.id + " ";
  }

  NStringMap stringProperties;
  NStringDoubleMap numericProperties;
  stringProperties.emplace("blocked", blockedFriendIds);

  string query = "-properties.blocked:/.*" + blockedFriendIds + ".*/";
  rtClient->addMatchmaker(2, 4, query, stringProperties, numericProperties, matchmakerSuccessCallback);
};

client->listFriends(session, {}, blockedState, {}, successCallback);
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var blocked_state = 3
var blocked_friends_result : NakamaAPI.ApiFriendList = yield(client.list_friends_async(session, blocked_state), "completed")
var blocked_friend_ids = ""

for friend in blocked_friends_result.friends:
  blocked_friend_ids += friend.user.id + " "

var string_properties = { "blocked", blocked_friend_ids }

var query = "-properties.blocked:/.*%s.*/" % [blocked_friend_ids]
var ticket : NakamaRTAPI.MatchmakerTicket = yield(socket.add_matchmaker_async(query, 2, 4, string_properties, null), "completed")
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var blocked_state = 3
var blocked_friends_result : NakamaAPI.ApiFriendList = await client.list_friends_async(session, blocked_state)
var blocked_friend_ids = ""

for friend in blocked_friends_result.friends:
  blocked_friend_ids += friend.user.id + " "

var string_properties = { "blocked", blocked_friend_ids }

var query = "-properties.blocked:/.%s./" % [blocked_friend_ids]
var ticket : NakamaRTAPI.MatchmakerTicket = await socket.add_matchmaker_async(query, 2, 4, string_properties, null)
Client
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
local limit = 100
local blocked_state = 3
local blocked_friends_result = client.list_friends(limit, blocked_state)

local blocked_friend_ids = ""
for i,friend in ipairs(blocked_friends_result.friends) do
  blocked_friend_ids = blocked_friend_ids .. friend.user.id .. " "
end

local min_players = 2
local max_players = 4
local query = ("-properties.blocked:/.*%s.*/"):format(blocked_friend_ids)
local string_properties = { blocked = blocked_friend_ids}
local ticket = socket.matchmaker_add(min_players, max_players, query, string_properties)

Code snippet for this language Java/Android has not been found. Please choose another language to show equivalent examples.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.
Code snippet for this language cURL has not been found. Please choose another language to show equivalent examples.