Matchmaking#
Matchmaking is the server-side process of finding users with similar skill to play against or with. In Xsolla Backend, this process allows for various user-defined criteria to find more accurate matches.
Matchmaking starts with a Ticket object. Tickets are how Xsolla Backend defines the criteria to find a match.
To find a match, a Ticket object should be created defining:
NumTeams: The number of teams required for a match
TeamSize: The number of people on a team
HostUid: local user id
NumUsers: Number of users submitted with this ticket
Users: A List of Users submitted with the ticket
Criteria: A List of Criteria objects representing matching conditions
Statistics - A List of Statistic objects representing the local users matching values
Though all of these properties are required the Criteria and Statistic object lists are inherent to the process.
Criteria#
The criteria object is used to handle the conditions that must be met for a match to be made.
Criteria Objects have two properties Name and Value:
Name: A string of the name of the variable being compared.
Value: An AXR Object representing the conditional to be compared.
The value of a Criteria Object can be defined in-line or as a separate object. In Chess, it is defined as a separate object that uses a range of the local users xp as its base value:
1AXRObject critValue = new AXRObject();
2
3// GTE = Greater Than or Equal to
4critValue["gte"] = xp - range;
5
6// LTE = Less Than or Equal to
7critValue["lte"] = xp + range;
This is, in turn, used as the value of the Criteria Object.
Criteria criteria = new Criteria() { Name = "xp", Value = critValue };
Statistic#
The statistic object is used to define the local users value in matchmaking.
Statistic Objects have two properties Name and Value:
Name: A string of the name of the variable being compared (Must match the Criteria Name property)
Value: The local users value used in the Criteria comparison
new Statistic() { Name = "xp", Value = xp };
Putting it all together, Ticket creation is a quick process:
1ticket = new Ticket()
2 {
3 // Number of teams in this game, There are only 2 opposing players so there are 2 teams
4 NumTeams = 2,
5 // Number of players on a team
6 TeamSize = 1,
7 // Search Criteria
8 // Name: represents the Statistic label to search for
9 // Value: the search parameters/criteria
10 Criteria = new List<Criteria>()
11 {
12 new Criteria()
13 {
14 Name = "xp",
15 Value = critValue
16 }
17 },
18
19 // Local user Statistics used for matching
20 // Other players are looking for matches with players who have a criteria that matches their local xp range
21 // This defines whether you fit their criteria for a match
22 Statistics = new List<Statistic>()
23 {
24 new Statistic()
25 {
26 Name = "xp",
27 Value = xp
28 }
29 },
30 // user Id of the Submitter of the ticket, it is the local user
31 HostUid = _sdk.Instance.LoggedInUser.Uid,
32 NumUsers = 1,
33 Users = new List<Guid>() { _sdk.Instance.LoggedInUser.Uid },
34 };
Once the ticket is created, it can be submitted to the TicketService for matchmaking.
TicketService#
The TicketService is a Xsolla Backend service used to process update and delete tickets from the Server. A reference to the TicketService can be pulled from the ServiceFactory:
CoreSDK.ServiceFactory.GetService<TicketService>();
In Chess we store a reference to the ServiceFactory, as it is used repeatedly through out the WebServices class.
To start the Matchmaking process a ticket must be created on the server using the locally created Ticket object:
ticket = await ticketService.Create(ticket);
The TicketService.Create call will return a copy of the ticket generated on the server.
This local copy of the Ticket can then be listened to through the EntityWatchdog for changes.
EntityWatchdog#
The Entity Watchdog is an utility that listens to entity changes on the server. It allows for local responses to those entity changes through a callback system.
A reference to the EntityWatchdog can be pulled from the CoreSDK object.
EntityWatchdog watchdog = CoreSDK.EntityWatchdog;
In Chess, like the TicketService, we also store a reference to the EntityWatchdog. To listen to an entity; it is a single line call:
_watchdog.Watch(ticket, OnTicketChange);
The first parameter being the entity listened to, in this case the returned ticket object.
The Second parameter being the listener function:
1private void OnTicketChange(Ticket ticket)
2{
3 try
4 {
5 TicketService ticketService = _serviceFactory.GetService<TicketService>();
6
7 // If a ticket status changes to match found
8 if (ticket.Status.Equals(Ticket.STATUS_MATCH_FOUND))
9 {
10 // Invoke a session ready event
11 _callbacks.Add(new WebCallback(val => _sessionReadyEvent?.Invoke()));
12
13 // Stop listening the to ticket changes
14 _watchdog.Unwatch(ticket, OnTicketChange);
15 return;
16 }
17 }
18 catch(Exception e)
19 {
20 Debug.LogException(e);
21 }
22}
Here in the listener function, the status of a ticket can be compared. If the ticket.status equals Ticket.STATUS_MATCH_FOUND; a match has been found and in-game operations surrounding that match can be performed.
The Ticket Listener, in this case OnTicketChange, has a Ticket object as a parameter. This is the latest copy of the ticket from the server.
If a match is found, the server returned copy of the ticket contains a populated SessionUid property:
Guid sessionId = ticket.SessionUid;
This should be stored off for interacting with the Session object.