Skip to main content

Use X-Ray for custom matchmaking

Last updated on October 24, 2024

This article walks you through how to use the AccelByte Gaming Services (AGS) matchmaking X-Ray tool for custom matchmaking in your game.

Prerequisites

  • An understanding of Matchmaking customization.
  • An environment with AGS version 3.76 or later.
  • For the matchmaking X-Ray to be able to track the ticket, add the "ticket_observability_enable": true parameter into your matchmaking ruleset.

Send matchmaking process data

To enable the X-Ray feature to scrape the data of matchmaking tickets in your custom matchmaking, your custom matchmaking apps should call this endpoint:

POST <baseURL>/sessionhistory/v2/admin/namespaces/<namespace>/xray/tickets

There are several actions that you can use when sending the matchmaking process data. Each action shares the same payload structure, aside from the action below if the ticket is started, canceled, or expired is already sent to the session history as default.

  • matchFound: use this action to track the data of a matched ticket.
  • matchNotFound: use this action to track the data of a ticket that is still in the queue and not is yet to be matched before the timeout period.
  • flexed: use this action to track the data of a ticket that is in flexed state.

Matchmaking process

This diagram shows when you should call the POST <baseURL>/sessionhistory/v2/admin/namespaces/<namespace>/xray/tickets endpoint during the matchmaking process.

Call endpoint diagram

Sample code

The following pseudocode shows a common scenario of when the POST <baseURL>/sessionhistory/v2/admin/namespaces/<namespace>/xray/tickets endpoint is called.

Pseudocode

function MakeMatches():
if isRuleFlexed == "yes":
callEndpoint("Publish ticket observability", "Flexed")

if IsMatched == "yes":
callEndpoint("Publish ticket observability", "matchFound")
else:
callEndpoint("Publish ticket observability", "matchNotFound")
note

X-Rays only scrape and expose data sent by the custom matchmaking. If there are fields that are not filled, they will not be displayed in the X-Ray.

Ensure that you call the endpoint every time you want to send the ticket data. In each iteration of the matchmaking process (referred to as a "loop"), you can send data multiple times within a single matchmaking ticket since the flexed and matchNotFound actions are sent once every loop.

Sample scenario

Here's a sample scenario for logging events the X-Ray based on 5v5 matchmaking mode.

Initiate the matchmaking process

Players enter the queue for a match, and the system begins searching for other players who meet specific criteria, such as:

  • Skill level (based on ranking or past performance)
  • Geographical location (to ensure low latency)
  • Preferred roles (e.g., tank, support, or damage)

The system performs multiple matchmaking cycles as new players join the queue.

Flexing Rules

In this scenario, isRuleFlexed is set to yes (isRuleFlexed = "yes"). After a designated waiting period (e.g., two minutes), if there are not enough players that meet the exact criteria, the system may flex certain rules to reduce wait times. For example:

  • Expanding skill range: Instead of restricting matches to a narrow skill range, the system allows a broader range of skill levels to participate.
  • Broadening regions: The system may relax geographical restrictions, enabling players from nearby regions with acceptable latency to join.

At this stage, custom matchmaking systems using X-Ray should log an event by calling the endpoint with the flexed action.

Match is found

After flexing the rules, the system successfully matches two teams of five players each, meeting the relaxed criteria and resulting to a match is found scenario (isMatched = "yes"). At this point, the custom matchmaking system should log an event by calling the endpoint with the matchFound action.

Match not found

If no match is found (isMatched = "no")within a reasonable timeframe—possibly due to low player activity or an unusual time of day—the custom matchmaking system should log an event by calling the endpoint with the matchNotFound action.

Sample request body template

{
"action": "matchFound",
"activeAllianceRule": {
"max_number": 2,
"min_number": 2,
"player_max_number": 5,
"player_min_number": 5
},
"activeMatchingRule": [
{
"attribute": "mmr",
"criteria": "distance",
"reference": 100
}
],
"function": "extend",
"gameMode": "5v5",
"isBackfillMatch": true,
"isRuleSetFlexed": true,
"iteration": 7,
"matchID": "d8140d69de02465b934281050dc0d69b",
"namespace": "GameAB",
"partyID": "0cc0cb97804b4ffd9fd8130f6e2622bb",
"remainingPlayersPerTicket": [
0
],
"remainingTickets": 0,
"sessionTickID": "3c29c2df8a0a44ac9a00afa69c14e8f7",
"tickID": 1727664260471,
"timeToMatchSec": 4.71937726,
"timestamp": "2024-07-23T07:07:56.067Z",
"unbackfillReason": "unbackfill_blocked_player_exist",
"unmatchReason": "not_enough_players"
}

This table describes each parameter in the request body.

Field nameField descriptionRequiredValue formatSample Value
timestampTimestamp when calling the endpointNoTime2024-07-23T07:07:56.067Z
partyIDTicket Party IDNoString0cc0cb97804b4ffd9fd8130f6e2622bb
matchIDID of the match, which is only filled only when a match is foundNoStringd8140d69de02465b934281050dc0d69b
NamespaceCurrent namespace of the ticketNoStringGameAB
gameModeCurrent matchpool of the ticketNoString5v5
activeAllianceRuleCurrent active alliance rulesetNoJSON(See sample value.)
activeMatchingRuleCurrent active matching rulesetNoJSON(See sample value.)
functionName of the function that called the endpointNoStringextend
iterationTotal iteration before match is foundNoInteger7
TimeToMatchSecTime to match (in seconds), which is only filled when match is foundNoFloat644.71937726
unmatchReasonReason when unable to find matchNoStringnot_enough_players
remainingTicketsRemaining ticket when unable to find matchNoInteger0
remainingPlayersPerTicketRemaining players when unable to find matchNoInteger0
UnbackfillReasonReason when unable to backfillNoStringunbackfill_blocked_player_exist
IsBackfillMatchFlag to distinguish between new match and backfill matchNoBooleantrue
IsRuleSetFlexedFlag if ruleset is getting flexedNoBooleanfalse
tickIDTicket ID for the matchmaking ticketNoInt641727664260471
sessionTickIDSession ticket ID to differentiate session when doing matchesNoString3c29c2df8a0a44ac9a00afa69c14e8f7

You can find the data sent by your custom matchmaking in Multiplayer > Diagnostics and Utilities > Matchmaking X-Ray on the AGS Admin Portal.

note

Although all of the fields in the request body are optional, they are still captured by the X-Ray. No other fields will be exposed or captured. For example, if you have a matchingRules field that depends on a specific composition for matching, you will need to inject its value into activeAllianceRule.

Sample ActiveAllianceRule value

[
{
"max_number": 0,
"min_number": 0,
"player_max_number": 0,
"player_min_number": 0
}
]

Sample ActiveMatchingRule value

[
{
"attribute": "string",
"criteria": "string",
"reference": 0
}
]