Skip to main content

Integrate matchmaking into your Unity game client

Last updated on September 18, 2023

Overview

Matchmaking is the process by which two or more players can be evaluated for a match, and joined to a game session so they can play together. In this guide, you will learn how to integrate the AccelByte Gaming Services (AGS) Matchmaking service into your game client using the Unity SDK plugin. This includes how to start matchmaking, how to listen for match results, and how to join a game session when matching is successful.

There are several components that the matchmaking service interacts with during the matchmaking process.

  • Session Template: defines the characteristics a session will be created with. This includes joinability, what game server deployment to use, player requirements, team composition, etc.
  • Match Ticket: defines a request for matchmaking, either by a solo player or a party, with the player information attached for evaluation.
  • Backfill Ticket: similar to a match ticket, but it is only created if auto-backfill is enabled in the match ruleset. In which case, when two or more players are matched, they will be joined to the session and a backfill ticket will be submitted to the Matchmaking service to continue to find matches until the minimum number of players have connected to the session.
  • Match Pool: defines a collection of match tickets that can be evaluated by the service for valid matches. Tickets end up in the same pool based on the selected game mode and preferences if applicable.
  • Match Ruleset: defines the attributes and comparison criteria that will be used by the default match function to determine if tickets make a valid match. In the case that the match function has been overridden, the ruleset will still need to be configured with any attributes that are stored in the Statistics service that are required for evaluation.
  • Match Function: defines the logic that the service will use to evaluate match tickets. By default, the service will use the criteria defined in the associated match ruleset.

Goals

After you complete this guide, you should have an understanding of the following:

  • The matchmaking flow players will experience.
  • How to start matchmaking for solo players and parties.
  • How to cancel matchmaking before a match is found.
  • How to listen for and handle match results.
  • How to listen for game session invites and join the session.

Prerequisites

Before you begin this guide, you should have an understanding of the following:

  • The AGS Lobby, Session, and Matchmaking services.
  • Unity scripting.
  • How to install AccelByte Unity SDK to a Unity project.
  • How to gain access to the game namespace in your AGS Admin Portal.
  • How to configure a session template, match ruleset, and match pool for your game mode.

You will also need to have set up the following:

  • You will need to set up the Unity SDK with its required client ID.
  • Your game client must have authenticated users with the AccelByte backend and connected to the Lobby service.

Matchmaking flow

In this section you will get an understanding of the matchmaking flow for both solo players and parties.

The AccelByte Unity SDK matchmaking flow diagram

  1. A player creates a party and invites friends to participate. Next, they select the desired game mode and set any preferences available.
  2. Once the player(s) are ready to start playing, the solo player or party leader initiates matchmaking, which creates a match ticket and queues it into a match pool. If a party leader initiates matchmaking, one match ticket is submitted with all the players in the party attached.
  3. The service evaluates the ticket based on the logic defined in the associated match ruleset in order to find optimal matches.
  4. When a match is found, the service requests a game session from the Session service and attaches the ticket information to the session.
  5. The service creates a backfill ticket for the game session if auto-backfill is enabled in the match ruleset (by setting auto_backfill to true) so additional matches can continue to be found until the max player setting is satisfied for that ruleset.
  6. Players receive an invite to join the game session once they are selected as a match and can be connected.
var apiClient = MultiRegistry.GetApiClient();
var lobby = apiClient.GetLobby();
var matchmaking = apiClient.GetMatchmakingV2();
var session = apiClient.GetSession();

// Registering matchmaking related notification
Result<MatchmakingV2MatchFoundNotification> MatchFoundNotif;
lobby.MatchmakingV2MatchFound += result =>
{
MatchFoundNotif = result;

if (MatchFoundNotif.IsError)
{
// Handle error
}

Debug.Log($"Received match found notification {MatchFoundNotif.Value.id}, {MatchFoundNotif.Value.teams}");
};

Result<MatchmakingV2MatchmakingStartedNotification> MatchmakingStartedNotif;
lobby.MatchmakingV2MatchmakingStarted += result =>
{
MatchmakingStartedNotif = result;

if (MatchmakingStartedNotif.IsError)
{
// Handle error
return;
}

Debug.Log($"Matchmaking started {MatchmakingStartedNotif.Value.ticketId}");
};

Result<MatchmakingV2TicketExpiredNotification> MatchmakingTicketExpired;
lobby.MatchmakingV2TicketExpired += result =>
{
MatchmakingTicketExpired = result;

if (MatchmakingTicketExpired.IsError)
{
// Handle error
return;
}

Debug.Log($"Matchmaking ticket expired {MatchmakingTicketExpired.Value.ticketId}");
};

Start matchmaking

// Start Matchmaking
string matchPool = "a-match-pool";

// add any optional parameters if needed
var optionalParams = new MatchmakingV2CreateTicketRequestOptionalParams
{
// Set custom attributes you need for matchmaking. Matchmaking will try to match the attributes.
// In this example the map names as values for the custom parameter for matchmaking only to specified maps.
attributes = new Dictionary<string, object>()
{
{ "map_names", "map_01" }
},

// Latencies are used to give matchmaking service more information about the game clients latencies to all available servers region.
// It will only matchmake to specified region, to get all latencies please use QosManager::GetAllServerLatencies,
latencies = new Dictionary<string, int>()
{
{"ap", 100},
{"eu", 90}
},

// If matchmaking is performed by party leader fill this with party session ID.
// It will make all user in the party to be included in matchmaking and later will be notified when
// the match is found
sessionId = "party-session-id"
};

string matchTicketId = "";
matchmaking.CreateMatchmakingTicket(matchPool, optionalParams, result =>
{
if (!result.IsError)
{
matchTicketId = result.Value.matchTicketId;
}
});

Join a game session

After matchmaking is completed, the game client will receive a game session invitation and can join the matched game session.

Result<SessionV2GameInvitationNotification> InvitedToGameSessionNotif;
lobby.SessionV2InvitedUserToGameSession += result =>
{
InvitedToGameSessionNotif = result;

if (InvitedToGameSessionNotif.IsError)
{
// handle error
return;
}

Debug.Log($"Invited to game session {InvitedToGameSessionNotif.Value.sessionId}");
// Here game client can decide to join a game session or not
session.JoinGameSession(InvitedToGameSessionNotif.Value.sessionId, joinGameSessionResult =>
{
if (joinGameSessionResult.IsError)
{
// handle error
return;
}

Debug.Log($"Successfully joined a game session {joinGameSessionResult.Value.id}");

if (joinGameSessionResult.Value.dsInformation.status == SessionV2DsStatus.AVAILABLE)
{
string serverIP = joinGameSessionResult.Value.dsInformation.server.ip;
Debug.Log($"DS Ready, IP: {serverIP}");
}

});
};

Connect to a dedicated server

Game clients need to listen to the dedicated server (DS) update notification to check if the DS is ready or not. Alternatively, game clients can also check DS information after joining a game session.

lobby.SessionV2DsStatusChanged += result =>
{
if (result.IsError)
{
// handle error
return;
}

var status = result.Value.session.dsInformation.status;
if (status == SessionV2DsStatus.AVAILABLE)
{
string serverIP = result.Value.session.dsInformation.server.ip;
Debug.Log($"DS Ready, IP: {serverIP}");
}
};

Cancel matchmaking

If you need to cancel matchmaking before the process completes or timeout occurs, you can call following API:

// Cancel Matchmaking
string matchTicketId = "match-ticket-id";
matchmaking.DeleteMatchmakingTicket(matchTicketId, result =>
{
if (!result.IsError)
{
Debug.Log($"Matchmaking canceled");
}
});

Troubleshoot issues

In this section, you can find common errors and issues that may occur when using the service, along with recommendations on how to resolve them.

OnMatchmakingTicketExpired notification from the Lobby service

If you receive the OnMatchmakingTicketExpired notification from the Lobby service, that means that the ticket reached the timeout limit and the player has been removed from matchmaking. This often happens if the timeout defined in the match pool configuration is too short or the match ruleset doesn't allow enough rule flexing to enable the player to match with others. To resolve:

  • Review the match pool configuration to determine if the match or backfill ticket timeout is too short.
  • Review the match ruleset to make sure if the minimum player/team requirements have been set correctly.