Specialized components
Matchmaking system
Match ticket
25 min
overview the match ticket is a fundamental data structure within the ir engine's matchmaking system that represents a player's or group's request to join a game it contains essential information about the desired game type, player attributes, and timing details that the matchmaking system uses to find appropriate matches by serving as a standardized format for game requests, match tickets enable the system to efficiently process and fulfill player matchmaking needs this chapter explores the structure, creation, and lifecycle of match tickets within the matchmaking architecture core concepts request representation a match ticket serves as a formal representation of a matchmaking request identification each ticket has a unique identifier for tracking and reference game criteria the ticket specifies what type of game the player wants to join player information details about the player or group making the request timing data information about when the request was made additional attributes optional parameters for more specific matching requirements this structured approach ensures that all necessary information is captured for effective matchmaking ticket lifecycle match tickets follow a defined lifecycle within the system creation generated when a player requests to join a game queuing added to a pool of active tickets awaiting matching processing evaluated against match profiles by the match function assignment associated with a game server when a suitable match is found fulfillment completed when the player joins the assigned game expiration/cancellation removed if the player cancels or the ticket times out this lifecycle ensures proper tracking and handling of matchmaking requests from submission to completion implementation ticket structure the match ticket is defined with a specific schema // from src/match ticket schema ts export interface matchtickettype { // unique identifier for the ticket id string; // fields used for matchmaking searchfields? { // tags for categorical matching (e g , game modes) tags? string\[]; // numerical values for range based matching doubleargs? record\<string, number>; // string values for exact matching stringargs? record\<string, string>; }; // additional custom data extensions? record\<string, any>; // timestamp when the ticket was created createtime? string; } this structure provides a unique id for tracking the ticket contains searchfields for specifying match criteria supports extensions for custom data includes creation time for queue management creating search fields when creating a ticket, search fields are prepared to specify the match criteria // from src/functions ts / prepares search fields for a match ticket @param gamemode the desired game mode @param attributes additional matching attributes @returns structured search fields for the ticket / function preparesearchfieldsforticket( gamemode string, attributes? record\<string, string> ) any { // initialize search fields with game mode and timestamp const searchfields any = { tags \[gamemode], doubleargs { 'time enterqueue' date now() // when the player started searching } }; // add optional attributes if provided if (attributes) { searchfields stringargs = {}; // prefix attribute keys for namespace clarity for (const key in attributes) { searchfields stringargs\['attributes ' + key] = attributes\[key]; } } return searchfields; } this function takes a game mode parameter (e g , "capturetheflag") adds the game mode as a tag for categorical matching records the current timestamp to track queue time incorporates optional attributes for more specific matching returns a structured object ready for inclusion in a match ticket creating a match ticket the complete process of creating a match ticket involves // from src/functions ts import { matchtickettype } from ' /match ticket schema'; import axios from 'axios'; // other imports const frontend service url = process env frontend service url || 'http //localhost 51504/v1/frontendservice'; / creates a match ticket for the specified criteria @param gamemode the desired game mode @param attributes optional additional matching attributes @returns a promise resolving to the created match ticket / async function createticket( gamemode string, attributes? record\<string, string> ) promise\<matchtickettype> { console log(`creating ticket for game mode ${gamemode}`); try { // prepare the search fields const searchfields = preparesearchfieldsforticket(gamemode, attributes); // send the request to create a ticket const response = await axios post(`${frontend service url}/tickets`, { searchfields }); // log success and return the ticket const ticket = response data as matchtickettype; console log(`ticket created with id ${ticket id}`); return ticket; } catch (error) { console error('failed to create match ticket ', error); throw new error('failed to create match ticket'); } } this function prepares search fields using the helper function sends an http post request to the frontend service includes the search fields in the request body returns the created ticket with its assigned id handles errors that might occur during ticket creation ticket creation workflow the complete workflow for ticket creation follows this sequence sequencediagram participant player as player participant client as game client participant frontend as frontend service participant backend as matchmaking backend player >>client requests to find a game client >>client prepares search fields client >>frontend creates ticket (post /tickets) frontend >>backend registers ticket in system backend >>backend assigns ticket id backend >>backend stores ticket in active pool backend >>frontend returns ticket details frontend >>client returns ticket with id client >>player shows "searching for game " this diagram illustrates the player initiates a request to find a game the client prepares search fields based on the desired game type the client sends a request to create a ticket the frontend service forwards this to the matchmaking backend the backend assigns an id and stores the ticket the ticket details are returned to the client the client indicates to the player that matchmaking is in progress ticket components tags tags are string identifiers used for categorical matching // example of tags in search fields const searchfields = { tags \['capturetheflag', 'competitive'] }; tags typically represent game modes (e g , "deathmatch", "capturetheflag") game types (e g , "casual", "competitive") region preferences (e g , "na", "eu", "asia") the matchmaking system uses tags to group players who want similar game experiences double arguments double arguments are numerical values used for range based matching // example of double arguments in search fields const searchfields = { doubleargs { 'time enterqueue' 1678886400000, // timestamp 'skill rating' 1850, // player skill rating 'latency region us west' 45 // ping to us west servers } }; double arguments typically represent queue entry time for wait time prioritization skill ratings for balanced matchmaking latency measurements for connection quality player counts for party size considerations the matchmaking system can use these values to find players within acceptable ranges string arguments string arguments are text values used for exact matching // example of string arguments in search fields const searchfields = { stringargs { 'attributes map' 'desertruins', 'attributes skilltier' 'gold', 'attributes role' 'support' } }; string arguments typically represent map preferences character or role selections skill tiers or divisions other categorical preferences that aren't tags the matchmaking system uses these for exact matching requirements group tickets match tickets can represent either individual players or pre formed groups // example of creating a group ticket async function creategroupticket( groupid string, playerids string\[], gamemode string ) promise\<matchtickettype> { // prepare search fields const searchfields = preparesearchfieldsforticket(gamemode); // add group information const extensions = { group { id groupid, players playerids } }; // create the ticket const response = await axios post(`${frontend service url}/tickets`, { searchfields, extensions }); return response data as matchtickettype; } group tickets keep players together in the same match ensure friends can play on the same team are treated as a single unit during matchmaking may have special handling for team balancing ticket pool all active tickets are stored in a pool for processing // conceptual representation from open match custom pods/director/main go func fetchtickets(ctx context context, client pb frontendserviceclient) (\[] pb ticket, error) { // query for all active tickets req = \&pb queryticketsrequest{ pool \&pb pool{ filter \[] pb filter{ { tag "capturetheflag", }, }, }, } // get tickets from the pool resp, err = client querytickets(ctx, req) if err != nil { return nil, err } return resp tickets, nil } the ticket pool contains all active tickets awaiting matches is queried by the match function to form potential matches can be filtered by specific criteria (e g , game mode) is continuously updated as new tickets are created and existing ones are fulfilled integration with other components the match ticket integrates with several other components of the matchmaking system frontend service the frontend service creates and manages tickets // example of frontend service integration import { createticket, deleteticket } from ' /functions'; // create a ticket when the player clicks "find game" async function handlefindgameclick() { const gamemode = getselectedgamemode(); // e g , "capturetheflag" const attributes = getselectedattributes(); // e g , { map "desertruins" } try { // create the ticket const ticket = await createticket(gamemode, attributes); // store the ticket id for later reference setcurrentticketid(ticket id); // start polling for assignment startassignmentpolling(ticket id); } catch (error) { console error('failed to find game ', error); showerrormessage('failed to start matchmaking'); } } // cancel the ticket when the player clicks "cancel" async function handlecancelclick() { const ticketid = getcurrentticketid(); if (ticketid) { try { // delete the ticket await deleteticket(ticketid); // stop polling for assignment stopassignmentpolling(); // clear the ticket id setcurrentticketid(null); } catch (error) { console error('failed to cancel matchmaking ', error); } } } this integration creates tickets when players request matches manages ticket lifecycle from the client perspective handles cancellation when players no longer want to match provides feedback to players about the matchmaking process match function the match function processes tickets to form matches // conceptual representation from open match custom pods/mmf/main go func makematches(tickets \[] pb ticket, profile pb matchprofile) \[] pb match { // group tickets by game mode ticketsbymode = groupticketsbytag(tickets) // process each game mode separately var matches \[] pb match for mode, modetickets = range ticketsbymode { // sort tickets by wait time sortticketsbyenterqueue(modetickets) // form matches based on profile requirements for len(modetickets) >= profile getminplayers() { // take enough tickets for a match matchtickets = modetickets\[ profile getmaxplayers()] modetickets = modetickets\[profile getmaxplayers() ] // create a match match = \&pb match{ matchid uuid new() string(), tickets matchtickets, // additional match properties } matches = append(matches, match) } } return matches } this integration processes tickets based on their search fields groups tickets by common criteria (e g , game mode) forms potential matches according to match profiles prioritizes tickets based on wait time or other factors benefits of match tickets the match ticket system provides several key advantages standardization creates a consistent format for matchmaking requests flexibility supports various game types and matching criteria traceability enables tracking of individual matchmaking requests prioritization allows for fair handling based on wait time grouping supports pre formed parties staying together extensibility accommodates custom data for specialized matching cancellation provides a mechanism for players to withdraw requests these benefits make match tickets an essential component for creating a robust and flexible matchmaking system next steps with an understanding of how match tickets represent player requests, the next chapter explores how the system defines the rules for forming valid matches next match profile docid\ n6zowggyxos4 nx4qrccc