Specialized components
Matchmaking system
Match profile
21 min
overview the match profile is a configuration structure within the ir engine's matchmaking system that defines the criteria and requirements for creating valid game matches it serves as a blueprint that specifies what constitutes a complete and balanced game session for a particular mode or type by providing parameters such as team sizes, player counts, and filtering criteria, match profiles guide the matchmaking process in grouping appropriate players together this chapter explores the structure, implementation, and role of match profiles within the matchmaking architecture core concepts game session definition a match profile defines the parameters of a valid game session game mode specifies the type of game being created (e g , "capturetheflag") player requirements defines how many players are needed for a complete match team structure specifies how players should be organized (e g , two teams of five) selection criteria determines which match tickets are eligible for this game type custom parameters provides additional game specific configuration this structured approach ensures that matches are created according to the game's design requirements ticket filtering match profiles use pools and filters to select appropriate tickets pools collections of tickets that meet specific criteria filters rules that determine which tickets belong in a pool tag filters select tickets based on their tags (e g , game mode) range filters select tickets based on numerical values within ranges string filters select tickets based on exact string matches these filtering mechanisms ensure that only compatible tickets are considered for matching implementation profile structure match profiles are defined using a specific structure // from open match custom pods/director/profile go import ( "open match dev/open match/pkg/pb" "lagunalabs/matchmaking/common" "google golang org/protobuf/types/known/anypb" ) // match profile structure type matchprofile struct { // unique identifier for the profile name string // collections of tickets that meet specific criteria pools \[] pool // custom data for the profile extensions map\[string] anypb any } // pool structure for filtering tickets type pool struct { // name of the pool name string // filters for selecting tickets based on tags tagpresentfilters \[] tagpresentfilter // other filter types (doublerangefilters, stringequalsfilters, etc ) } // filter for selecting tickets with specific tags type tagpresentfilter struct { // tag that must be present in the ticket tag string } this structure provides a name for identifying the profile contains pools for grouping tickets by criteria includes extensions for custom game specific data uses filters to select appropriate tickets profile generation match profiles are generated programmatically based on game modes // simplified from open match custom pods/director/profile go func generateprofiles(modes \[]string, teamsizes map\[string]uint32) \[] pb matchprofile { var profiles \[] pb matchprofile // create a profile for each game mode for , mode = range modes { // create custom profile data profiledata = \&common profiledatamessage{ mode mode, // e g , "capturetheflag" teamsize teamsizes\[mode], // e g , 5 (for a 5v5 game) } // marshal the profile data marshalledprofiledata, err = anypb new(profiledata) if err != nil { // handle error continue } // create the match profile profile = \&pb matchprofile{ // name based on the game mode name "mode based profile " + mode, // define pools for filtering tickets pools \[] pb pool{{ name "pool mode " + mode, // filter for tickets with the specific game mode tag tagpresentfilters \[] pb tagpresentfilter{ {tag mode}, // e g , tag "capturetheflag" }, // additional filters could be added here }}, // store custom data in extensions extensions map\[string] anypb any{ "profiledata" marshalledprofiledata, }, } // add the profile to the list profiles = append(profiles, profile) } return profiles } this function takes a list of game modes and their corresponding team sizes creates a profile for each game mode sets up a pool with a tag filter for the specific mode stores mode and team size information in the profile extensions returns a list of profiles ready for use in matchmaking custom profile data game specific parameters are stored in profile extensions // from open match custom pods/ common/profilemessage pb go // profiledatamessage contains custom data for match profiles type profiledatamessage struct { // game mode (e g , "capturetheflag") mode string // number of players per team teamsize uint32 // other game specific parameters could be added here } this custom data specifies the game mode for the profile defines the team size for the game can be extended with additional parameters as needed is accessible to the match function for creating balanced matches profile usage workflow the complete workflow for using match profiles follows this sequence sequencediagram participant director as director participant profiles as match profiles participant mmf as match function participant tickets as ticket pool director >>profiles generate profiles for game modes note over profiles profiles created with mode specific parameters loop for each profile periodically director >>mmf request matches using profile mmf >>profiles extract profile parameters (mode, team size) mmf >>tickets query tickets matching profile pools tickets >>mmf return matching tickets mmf >>mmf group tickets according to profile requirements mmf >>director return proposed matches director >>director process and assign matches end this diagram illustrates the director generates profiles for each game mode for each profile, the director periodically requests matches the match function extracts parameters from the profile the match function queries for tickets matching the profile's pools the match function groups tickets according to the profile requirements the match function returns proposed matches to the director the director processes and assigns the matches profile components name each profile has a unique identifier // example of profile naming profile = \&pb matchprofile{ name "mode based profile capturetheflag", // other profile properties } the name typically identifies the specific game mode or type provides a reference for logging and debugging helps distinguish between different match configurations is used when requesting matches from the match function pools pools define collections of tickets that meet specific criteria // example of pool definition pool = \&pb pool{ name "pool mode capturetheflag", // filter for tickets with the "capturetheflag" tag tagpresentfilters \[] pb tagpresentfilter{ {tag "capturetheflag"}, }, // filter for tickets with skill rating in a specific range doublerangefilters \[] pb doublerangefilter{ { doublearg "skill rating", min 1000, max 2000, }, }, // filter for tickets with a specific role stringequalsfilters \[] pb stringequalsfilter{ { stringarg "attributes role", value "support", }, }, } pools can use various filter types tagpresentfilters select tickets with specific tags doublerangefilters select tickets with numerical values in ranges stringequalsfilters select tickets with exact string matches these filters can be combined to create precise selection criteria extensions extensions store custom data for the profile // example of profile extensions extensions = map\[string] anypb any{ "profiledata" marshalledprofiledata, "matchoptions" marshalledmatchoptions, "regioninfo" marshalledregioninfo, } extensions typically store game mode information team size and structure match duration or round settings map rotation or selection rules other game specific configuration this custom data is used by the match function to create appropriate matches director integration the director uses profiles to request matches // simplified from open match custom pods/director/main go func main() { // generate profiles for all game modes modes = \[]string{"capturetheflag", "deathmatch", "kingofthehill"} teamsizes = map\[string]uint32{ "capturetheflag" 5, // 5v5 "deathmatch" 4, // 4v4 "kingofthehill" 6, // 6v6 } profiles = generateprofiles(modes, teamsizes) // periodically request matches for each profile for range time tick(time second 5) { for , profile = range profiles { go func(p pb matchprofile) { // request matches using this profile matches, err = fetchmatches(backendclient, p, mmfhost, mmfport) if err != nil { // handle error return } // process the matches for , match = range matches { // assign the match assignmatch(backendclient, match) } }(profile) } } } this integration generates profiles for all supported game modes periodically requests matches for each profile processes and assigns the resulting matches runs concurrently for multiple profiles match function integration the match function uses profiles to create matches // simplified from open match custom pods/mmf/main go func makematches(tickets \[] pb ticket, profile pb matchprofile) \[] pb match { // extract profile data profiledata = \&common profiledatamessage{} if ext, ok = profile extensions\["profiledata"]; ok { ext unmarshalto(profiledata) } // get mode and team size mode = profiledata mode teamsize = int(profiledata teamsize) // create matches based on profile parameters var matches \[] pb match // group tickets into matches for i = 0; i+2 teamsize <= len(tickets); i += 2 teamsize { // create two teams team1 = tickets\[i\ i+teamsize] team2 = tickets\[i+teamsize\ i+2 teamsize] // create a match match = \&pb match{ matchid uuid new() string(), matchprofile profile name, tickets append(team1, team2 ), extensions map\[string] anypb any{ "teams" createteamsextension(team1, team2), }, } matches = append(matches, match) } return matches } this integration extracts custom data from the profile uses the mode and team size to structure matches groups tickets according to the profile requirements creates matches with appropriate team assignments returns the proposed matches to the director benefits of match profiles the match profile system provides several key advantages standardization creates a consistent format for defining game requirements flexibility supports various game types with different parameters separation of concerns decouples match definition from match creation logic configurability allows for easy adjustment of game parameters extensibility accommodates custom data for specialized game types reusability enables the same matching logic to be used for different game modes clarity provides a clear contract between the director and match function these benefits make match profiles an essential component for creating a robust and flexible matchmaking system next steps with an understanding of how match profiles define the requirements for valid matches, the next chapter explores how the match function uses these profiles to create balanced game sessions next match function (mmf) docid\ x7r1j0xjlflhfqsxn8uny