The Nakama matchmaker feature enables users to search for, and be matched with, other users - whether as teammates or opponents - to form matches, groups, or participate in any other social features built into your project.
The matchmaker maintains a pool of users and their matchmaking requests (“tickets”), and places them together whenever a good match is found. The definition of a “good match” for any particular user is based upon the criteria defined in their matchmaker ticket. The length of time before a match is found is highly variable, depending on how narrowly defined the criteria is and the amount of users currently in the matchmaking pool. If matchmaking duration is too long, or matches are not being found at all, consider expanding the criteria.
Note that matchmaking is for active players only - users with an open socket connection. Once they have submitted a matchmaker ticket - adding themselves to the matchmaker pool of available players - users remain there until a match is found or they cancel their request. If a user disconnects, any pending matchmaking requests they had are also cancelled.
Offline Matchmaking
If your use case requires offline matchmaking, please check the following section for assistance.
Matchmaking is distinct from Nakama’s match listing feature. Where the matchmaker is used to place users together to start a new match, match listing is used to show users existing matches that they can join immediately. Deciding between using matchmaking or match listing is a design consideration (rather than a technical one) based on your project goals and requirements.
There are several parameters available in your Nakama configuration that affect how the matchmaker functions.
You can prevent users from submitting abusive amounts of tickets, and never cancelling old ones, by setting a maximum number of concurrent tickets a user can have at any one time.
By setting the time interval the matchmaker attempts to find a user’s “ideal” (size) match, and the number of intervals before allowing a less ideal (in size) match, you can adjust how long your users are waiting and balance finding the ideal match versus getting into a match more quickly.
The reverse matching precision and threshold flags are used to dictate if, and for how long, reverse matching precision is active. If enabled (rev_precision set to true), the matchmaker will validate matches bidirectionally (i.e. when Player A matches with Player B, it will also check that Player B matches with Player A). If the match is not bidirectional, the matchmaker will continue to search for a bidirectional match for the duration of the rev_threshold intervals. If no bidirectional match is found within number of intervals (1 by default), the matchmaker will return to unidirectional matching.
To begin matchmaking users add themselves to the matchmaking pool. As part of their matchmaker ticket there are optional criteria that can be included to describe the desired match: Properties, Minimum count and Maximum count, Count multiple, and a Query.
Matchmaker Override
In addition to any criteria defined in the matchmaker ticket, you can also register a matchmaker override function to further refine the matchmaking process.
Properties are key-value pairs, either string or numeric, that describe the user submitting a matchmaking ticket. Some common examples of what can be provided in properties include the user’s game rank/level, their skill rating, the connecting region, or selected match types (e.g. Free for All, Capture the Flag, etc.).
Code snippet for this language cURL 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.
These properties are submitted by the user when they begin the matchmaking process, and can be different for each ticket. The server merges all included properties to form the overall properties that are part of the matchmaker ticket.
When matchmaking completes these properties are visible to all matched users. You can store extra information without affecting the matchmaking process itself if it’s useful to clients - just submit properties that aren’t queried for as part of the matchmaking process.
You can also authoritatively control the properties using a before hook when adding the user to the matchmaker:
var(errInternal=runtime.NewError("internal server error",13))funcInitModule(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,initializerruntime.Initializer)error{initializer.RegisterBeforeRt("MatchmakerAdd",func(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,in*rtapi.Envelope)(*rtapi.Envelope,error){message,ok:=in.Message.(*rtapi.Envelope_MatchmakerAdd)if!ok{returnnil,errInternal}// If the string properties contains a region value of "europe", modify it to "europe-west"
ifvalue,ok:=message.MatchmakerAdd.StringProperties["region"];ok&&value=="europe"{message.MatchmakerAdd.StringProperties["region"]="europe-west"}returnin,nil})returnnil}
Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
functionInitModule(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,initializer: nkruntime.Initializer){initializer.registerRtBefore("MatchmakerAdd",beforeMatchmakerAdd)}constbeforeMatchmakerAdd : nkruntime.RtBeforeHookFunction<nkruntime.EnvelopeMatchmakerAdd>=function(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,envelope: nkruntime.EnvelopeMatchmakerAdd):nkruntime.EnvelopeMatchmakerAdd|void{constregion=envelope.matchmakerAdd.stringProperties["region"];// If the string properties contain a region value of "europe", modify it to "europe-west"
if(region&®ion=="europe"){envelope.matchmakerAdd.stringProperties["region"]="europe-west";}returnenvelope;}
Server
1
2
3
4
5
6
7
8
9
10
nk.register_rt_before(function(context,payload)localregion=payload.matchmaker_add.string_properties["region"]-- If the string properties contain a region value of "europe", modify it to "europe-west"ifregion=="europe"thenpayload.matchmaker_add.string_properties["region"]="europe-west"endreturnpayloadend,"MatchmakerAdd")
When submitting a matchmaker request users must specify both a minimum and maximum count, where the minCount represents the smallest acceptable match size and maxCount represents the largest acceptable match size, with both being inclusive of the player submitting the request.
The matchmaker will always try to match at the provided maximum count. If there aren’t enough users, then the closest possible size to the maximum count will be returned as the match so long as it is above the minimum count.
For example, if using a minimum count of 2 and maximum count of 4, the matchmaker will try to find 3 other players to match the user with. If there are not 3 matching players available, the matchmaker will try to match 2 others, and finally just 1 other player if 2 are not available.
If there are not enough available users to meet even the minimum count, no match is returned and the user remains in the pool.
var(errInternal=runtime.NewError("internal server error",13))funcInitModule(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,initializerruntime.Initializer)error{initializer.RegisterBeforeRt("MatchmakerAdd",func(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,in*rtapi.Envelope)(*rtapi.Envelope,error){message,ok:=in.Message.(*rtapi.Envelope_MatchmakerAdd)if!ok{returnnil,errInternal}// Force min count to be 4 and max count to be 8
message.MatchmakerAdd.MinCount=4message.MatchmakerAdd.MaxCount=8returnin,nil})returnnil}
Server
1
2
3
4
5
6
7
8
9
10
11
functionInitModule(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,initializer: nkruntime.Initializer){initializer.registerRtBefore("MatchmakerAdd",beforeMatchmakerAdd)}constbeforeMatchmakerAdd : nkruntime.RtBeforeHookFunction<nkruntime.EnvelopeMatchmakerAdd>=function(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,envelope: nkruntime.EnvelopeMatchmakerAdd):nkruntime.EnvelopeMatchmakerAdd|void{// Force min count to be 4 and max count to be 8
envelope.matchmakerAdd.minCount=4envelope.matchmakerAdd.maxCount=8returnenvelope;}
Server
1
2
3
4
5
6
7
nk.register_rt_before(function(context,payload)-- Force min count to be 4 and max count to be 8payload.matchmaker_add.min_count=4payload.matchmaker_add.max_count=8returnpayloadend,"MatchmakerAdd")
The countMultiple parameter can be used when you need to enforce a specific multiplier for the acceptable match sizes (i.e. results must be in multiples of 5).
Code snippet for this language cURL 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.
The matchmaker will only return results containing a total number of matched players that is a multiple of 5, first trying to return the maximum count of 25, then 20, 15, and so forth. Even if there are 23 matching players available, the returned result will be 20 players.
You can also authoritatively control the count multiple using a before hook when adding the user to the matchmaker:
Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var(errInternal=runtime.NewError("internal server error",13))funcInitModule(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,initializerruntime.Initializer)error{initializer.RegisterBeforeRt("MatchmakerAdd",func(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,in*rtapi.Envelope)(*rtapi.Envelope,error){message,ok:=in.Message.(*rtapi.Envelope_MatchmakerAdd)if!ok{returnnil,errInternal}// Force the count multiple to be in multiples of 5
message.MatchmakerAdd.CountMultiple=&wrapperspb.Int32Value{Value:5}returnin,nil})returnnil}
Server
1
2
3
4
5
6
7
8
9
10
functionInitModule(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,initializer: nkruntime.Initializer){initializer.registerRtBefore("MatchmakerAdd",beforeMatchmakerAdd)}constbeforeMatchmakerAdd : nkruntime.RtBeforeHookFunction<nkruntime.EnvelopeMatchmakerAdd>=function(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,envelope: nkruntime.EnvelopeMatchmakerAdd):nkruntime.EnvelopeMatchmakerAdd|void{// Force the count multiple to be in multiples of 5
envelope.matchmakerAdd.countMultiple=5;returnenvelope;}
Server
1
2
3
4
5
6
nk.register_rt_before(function(context,payload)-- Force the count multiple to be in multiples of 5payload.matchmaker_add.count_multiple=5returnpayloadend,"MatchmakerAdd")
Where properties describes the user searching for other players, the query describes what properties they are searching for in other users.
Every user’s matchmaker properties are available in queries under the properties prefix. You can find opponents based on a mix of property filters with exact matches or ranges of values.
See Query Syntax to learn about the grammar and operators available for your queries.
This example searches for opponents that must be in europe and must have a rank between 5 and 10, inclusive:
Code snippet for this language cURL 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.
You can also authoritatively control the query using a before hook when adding the user to the matchmaker:
Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var(errInternal=runtime.NewError("internal server error",13))funcInitModule(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,initializerruntime.Initializer)error{initializer.RegisterBeforeRt("MatchmakerAdd",func(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,in*rtapi.Envelope)(*rtapi.Envelope,error){message,ok:=in.Message.(*rtapi.Envelope_MatchmakerAdd)if!ok{returnnil,errInternal}// Force the matchmaking request to use the * query
message.MatchmakerAdd.Query="*"returnin,nil})returnnil}
Server
1
2
3
4
5
6
7
8
9
10
functionInitModule(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,initializer: nkruntime.Initializer){initializer.registerRtBefore("MatchmakerAdd",beforeMatchmakerAdd)}constbeforeMatchmakerAdd : nkruntime.RtBeforeHookFunction<nkruntime.EnvelopeMatchmakerAdd>=function(ctx: nkruntime.Context,logger: nkruntime.Logger,nk: nkruntime.Nakama,envelope: nkruntime.EnvelopeMatchmakerAdd):nkruntime.EnvelopeMatchmakerAdd|void{// Force the matchmaking request to use the * query
envelope.matchmakerAdd.query="*";returnenvelope;}
Server
1
2
3
4
5
6
nk.register_rt_before(function(context,payload)-- Force the matchmaking request to use the * querypayload.matchmaker_add.query="*"returnpayloadend,"MatchmakerAdd")
The success of a matchmaking request, or the length of time needed to find a match, cannot be guaranteed as both are dependent on the pool of users active in the matchmaker and the specific criteria sought for in a match.
Repeatedly submitting identical requests will not yield different results. For this reason, placing any artificial time limit on a matchmaker request is not advised.
Based on the number of active users and the respective criteria used in matchmaking, it can sometimes be difficult or impossible to find the exact match desired.
To effectively “loosen” the criteria being used players should submit multiple tickets, each with a more permissive query than those before it.
For example, if a player wants to be matched with others that are in their region and at exactly the same skill level but is not getting any results, the subsequent tickets can expand to include other regions and allow for a range of skill levels close to the player’s own.
Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
letquery="+properties.region:europe +properties.rank:5";constminCount=2;constmaxCount=4;conststringProperties={region:"europe"};constnumericProperties={rank:8};varticket=awaitsocket.addMatchmaker(query,minCount,maxCount,stringProperties,numericProperties);// ... if no match is found within a certain time, request a new ticket with looser criteria
query="+properties.region:europe +properties.rank:>=3 +properties.rank:<=7";varnewTicket=awaitsocket.addMatchmaker(query,minCount,maxCount,stringProperties,numericProperties);
Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
varquery="+properties.region:europe +properties.rank:5";varstringProperties=newDictionary<string,string>(){{"region","europe"}};varnumericProperties=newDictionary<string,int>(){{"rank",8}};varmatchmakerTicket=awaitsocket.AddMatchmakerAsync(query,2,4,stringProperties,numericProperties);// ... if no match is found within a certain time, request a new ticket with looser criteriaquery="+properties.region:europe +properties.rank:>=3 +properties.rank:<=7";varnewMatchmakerTicket=awaitsocket.AddMatchmakerAsync(query,2,4,stringProperties,numericProperties);
Client
1
2
3
4
5
6
7
8
9
varquery="+properties.region:europe +properties.rank:5"letstringProperties=["region":"europe"]letnumericProperties:[String:Double]=["rank":8]letticket=tryawaitsocket.addMatchmaker(query:query,minCount:2,maxCount:4,stringProperties:stringProperties,numericProperties:numericProperties)// ... if no match is found within a certain time, request a new ticket with looser criteriaquery="+properties.region:europe +properties.rank:>=3 +properties.rank:<=7"letnewTicket=tryawaitsocket.addMatchmaker(query:query,minCount:2,maxCount:4,stringProperties:stringProperties,numericProperties:numericProperties)
varquery='+properties.region:europe +properties.rank:5';conststringProperties={'region':'europe',};constMap<String,double>numericProperties={'rank':8,};finalticket=awaitsocket.addMatchmaker(query,minCount:2,maxCount:4,stringProperties:stringProperties,numericProperties:numericProperties,countMultiple:5,);// ... if no match is found within a certain time, request a new ticket with looser criteria
query='+properties.region:europe +properties.rank:>=3 +properties.rank:<=7';finalnewTicket=awaitsocket.addMatchmaker(query,minCount:2,maxCount:4,stringProperties:stringProperties,numericProperties:numericProperties,countMultiple:5,);
Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
autosuccessCallback=[](constNMatchmakerTicket&ticket){std::cout<<"Matchmaker ticket: "<<ticket.ticket<<std::endl;};int32_tminCount=2;int32_tmaxCount=4;stringquery="+properties.region:europe +properties.rank:5";NStringMapstringProperties;NStringDoubleMapnumericProperties;stringProperties.emplace("region","europe");numericProperties.emplace("rank",8.0);rtClient->addMatchmaker(minCount,maxCount,query,stringProperties,numericProperties,successCallback);// ... if no match is found within a certain time, request a new ticket with looser criteria
query="+properties.region:europe +properties.rank:>=3 +properties.rank:<=7";rtClient->addMatchmaker(minCount,maxCount,query,stringProperties,numericProperties,successCallback);
Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Stringquery="+properties.region:europe +properties.rank:5";intminCount=2;intmaxCount=4;Map<String,String>stringProperties=newHashMap<String,String>(){{put("region","europe");}};Map<String,Double>numericProperties=newHashMap<String,Double>(){{put("rank",8.0);}};MatchmakerTicketmatchmakerTicket=socket.addMatchmaker(query,minCount,maxCount,stringProperties,numericProperties).get();// ... if no match is found within a certain time, request a new ticket with looser criteriaquery="+properties.region:europe +properties.rank:>=3 +properties.rank:<=7";MatchmakerTicketnewMatchmakerTicket=socket.addMatchmaker(query,minCount,maxCount,stringProperties,numericProperties).get();
Each time a user is added to the matchmaker pool they receive a ticket, a unique identifier representing their state in the matchmaker.
A user can have multiple matchmaker tickets at any given time, each representing a different set of criteria. For example one ticket seeking any available opponents for a Free for All match, and another seeking players in their local region to play in a Capture the Flag match.
This ticket is used when the server notifies the client on matching success. It distinguishes between multiple possible matchmaker operations for the same user. A successful match on one ticket does not automatically cancel any other tickets the user had open.
The user can cancel a ticket at any time before the ticket has been fulfilled.
Code snippet for this language cURL 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.
This will only cancel the specified ticket and does not affect any other requests the user may have in the matchmaking pool.
Remember that if a user disconnects during matchmaking any open tickets are automatically cancelled. The user immediately reconnecting, no matter how quickly, does not restore their previous tickets.
You can optionally further refine the matchmaker results - for example utilizing OpenSkill or your own custom logic - by registering a MatchmakerOverride function.
When RegisterMatchmakerOverride is used, the functioning of the matchmaker is altered as follows:
Using the provided criteria and existing matchmaker logic, the matchmaker compiles a list of all possible matches that could be formed, in order of preference, but does not yet create any matches.
This list is passed to the MatchmakerOverride function. Using any additional criteria or logic desired, this function returns a list of matches, in order of preference, that should be created.
The matchmaker then creates the matches in the order provided by the MatchmakerOverride function.
Keep in mind that the list of all potential matches will, by necessity, include matches that are not possible to create. For example, given a match size of 2 and a pool of 3 players, the list of all possible matches will include 3 matches, but only 1 of those matches can actually be created.
Matchmaking is not always an instant process. Depending on the currently connected users the matchmaker may take time to complete and will return the resulting list of opponents asynchronously.
Clients should register an event handler that triggers when the server sends them a matchmaker result.
func_ready():# First, setup the socket as explained in the authentication section.socket.connect("received_matchmaker_matched",self,"_on_matchmaker_matched")func_on_matchmaker_matched(p_matched:NakamaRTAPI.MatchmakerMatched):print("Received MatchmakerMatched message: %s"%[p_matched])print("Matched opponents: %s"%[p_matched.users])
Client
1
2
3
4
5
6
7
func_ready():# First, setup the socket as explained in the authentication section.socket.received_matchmaker_matched.connect(self._on_matchmaker_matched)func_on_matchmaker_matched(p_matched:NakamaRTAPI.MatchmakerMatched):print("Received MatchmakerMatched message: %s"%[p_matched])print("Matched opponents: %s"%[p_matched.users])
Code snippet for this language cURL 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.
The matchmaker result will include all of the matched users and their respective properties.
The result also includes either a token or match ID that can be used to join the new match for this group of matched players. Which is included depends on the type of match: for client relayed matches a token is provided, while for server authoritative matches a match ID is provided.
In the case of authoritative matches, you can use a server hook to create a new match on the server when matchmaker results are returned:
Server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var(errUnableToCreateMatch=runtime.NewError("unable to create match",13))funcInitModule(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,initializerruntime.Initializer)error{iferr:=initializer.RegisterMatchmakerMatched(func(ctxcontext.Context,loggerruntime.Logger,db*sql.DB,nkruntime.NakamaModule,entries[]runtime.MatchmakerEntry)(string,error){matchId,err:=nk.MatchCreate(ctx,"lobby",map[string]interface{}{"invited":entries})iferr!=nil{return"",errUnableToCreateMatch}returnmatchId,nil});err!=nil{logger.Error("unable to register matchmaker matched hook: %v",err)returnerr}returnnil}
In client relayed multiplayer it is common to use the matchmaker result event as a way to join a new match with the matched opponents. The matched users do not automatically join the match they are assigned to.
Each matchmaker result event carries either a token, used to join a client relayed match, or a match ID, used to join an authoritative match. These can be used to join a match together with the matched opponents.
In the case of client relayed multiplayer, the token enables the server to know that these users wanted to play together and will create a match dynamically for them.
Tokens are short-lived and must be used to join a match as soon as possible. The match token is also used to prevent unwanted users from attempting to join a match they were not matched into. When a token expires it can no longer be used or refreshed.
The standard client-side “match join” operation can be used to join the new match:
Nakama’s real-time parties enables users to band together into short-lived teams - lasting only as long as a given session - and play together. Once grouped into a party, these players can matchmake together, ensuring that they all are ultimately assigned to the same match.
Each party has a designated leader, typically the user that created the party. This leader sets the criteria that will be used for matchmaking and adds the party to the matchmaker pool:
Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Register the matchmaker matched handler (the party leader and party members should all do this)
socket.onmatchmakermatched=(matched)=>{socket.joinMatch(null,matched.token);};// Create a party as the party leader
constparty=awaitsocket.createParty(true,2);// Accept any incoming party requests
socket.onpartyjoinrequest=(request)=>{request.presences.forEach(presence=>{awaitsocket.acceptPartyMember(request.party_id,presence);});};// As the leader of the party, add the entire party to the matchmaker
constticket=awaitsocket.addMatchmakerParty(party.party_id,"*",3,4,null,null);
Client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Register the matchmaker matched handler (the party leader and party members should all do this)socket.ReceivedMatchmakerMatched+=asyncmatched=>awaitsocket.JoinMatchAsync(matched);// Create a party as the party leadervarparty=awaitsocket.CreatePartyAsync(true,2);// Accept any incoming party requestssocket.ReceivedPartyJoinRequest+=asyncrequest=>{foreach(varpresenceinrequest.Presences){awaitsocket.AcceptPartyMemberAsync(request.PartyId,presence);}};// As the leader of the party, add the entire party to the matchmakervarticket=awaitsocket.AddMatchmakerPartyAsync(party.Id,"*",3,4);
// Register the matchmaker matched handler (the party leader and party members should all do this)socket.onMatchmakerMatched={matchedinprint("Received MatchmakerMatched message: \(matched)")print("Matched opponents: \(matched.users)")}// Create a party as the party leaderletparty=tryawaitsocket.createParty(open:true,maxSize:2)// Accept any incoming party requestssocket.onPartyJoinRequest={requestinforpresenceinrequest.presences{Task{tryawaitself.socket.acceptPartyMember(partyId:request.partyID,presence:presence.toUserPresence())}}}// As the leader of the party, add the entire party to the matchmakerletticket=tryawaitsocket.addMatchmakerParty(partyId:party.partyID,query:"*",minCount:3,maxCount:4)
// Register the matchmaker matched handler (the party leader and party members should all do this)
socket.onMatchmakerMatched.listen((event){print('Received MatchmakerMatched message: $event');print('Matched opponents: ${event.users}');});finalparty=awaitsocket.createParty(open:true,maxSize:2);// Accept any incoming party requests
socket.onPartyJoinRequest.listen((event)async{for(varpresenceinevent.presences){awaitsocket.acceptPartyMember(event.partyId,presence);}});// As the leader of the party, add the entire party to the matchmaker
finalticket=awaitsocket.addMatchmakerParty(partyId:party.partyId,minCount:3,maxCount:4,query:'*',);
-- Register the matchmaker matched handler (the party leader and party members should all do this)socket.on_matchmaker_matched(function(matched)pprint("Received:",matched);socket.match_join(matched.token)end)-- Accept any incoming party requestssocket.on_party_join_request(function(request)fori,presenceinipairs(request.presences)dosocket.party_accept(request.party_id,presence)endend)-- Create a party as the party leaderlocalopen=truelocalmax_players=2localparty=socket.party_create(open,max_players)-- As the leader of the party, add the entire party to the matchmakerlocalmin_players=3localmax_players=4localquery="*"localticket=socket.party_matchmaker_add(party.party_id,min_players,max_players,query)
Code snippet for this language Java/Android 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.
Code snippet for this language REST has not been found. Please choose another language to show equivalent examples.
As part of the matchmaking process, the party members will always be kept together in any returned result. Parties can be matched both with other parties and individual users to ultimately form a match, there is no preference for either in the matchmaker.
For example, given a maximum count of 10, a party of 5 could be matched with another party of 3 and then two individual users to form a complete match.
Upon successful matchmaking, all party members receive the matchmaker result callback, not just the party leader.