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.