Skip to main content

Configuring match rulesets

Last updated on March 22, 2024

Overview

Match Rulesets define the logic that the Matchmaking service will use to determine if and when match tickets can be paired together. It is important that these are configured thoughtfully to prevent your players from having sub-optimal experiences either due to long queue wait times or poor match quality. In this guide, you will learn how to configure rules to enable team-based, skill-based, and custom parameter matching between players. You will also learn how to flex those rules over time to help reduce wait times in situations where there may be low player traffic or a large skill variance between players.

Before reading the rest of this guide, here are some key terms to become familiar with:

  • Attributes: also referred to as statistics, are numeric values, such as MMR, that can be used to compare tickets to determine the fitness of a match. These values must be stored in AccelByte's Statistics service to be used during matchmaking.

  • Custom Parameters: key-value pairs that represent player preferences passed to the Matchmaking service from the game client as part of the match request. Examples include map, language, and crossplay player preferences.

  • Rule Flexing: the process by which a configured rule will be relaxed over time. Configuring rule flexing can help prevent players from experiencing long queue wait times.

Goals

The goals of this guide are to provide:

  • An overview of Match Rulesets and how to configure them in the Admin Portal.
  • An understanding of the different types of behaviors that can be enabled as part of a ruleset.
  • An understanding of how to enable flexing of the defined behavior to prevent players from waiting in a queue too long.

Prerequisites

Team-based matchmaking

Many games support team-based gameplay, with players placed into teams to compete against each other until the Game Mode objectives are satisfied. To configure team-based matching, you will need to define the number of teams and number of players per team that should be targeted for a match in the JSON as shown in the example below. This example configuration specifies that there needs to be two teams, with no less than five players for the match to start.

NOTE

alliance in the JSON block defines the team configuration that will be followed during evaluation.

{
"auto_backfill": true,
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 5,
"player_max_number": 5
}
}
  • Auto backfill: specifies that the session will automatically backfill open spots until the match is full and can start.
  • Min number: specifies the minimum number of required teams for the match to start.
  • Max number: specifies the maximum number of teams that can participate in the match.
  • Player min number: specifies the minimum number of players required per team for the match to start.
  • Player max number: specifies the maximum number of players that can participate in a team during the match.

Rule flexing for teams

In the case that the minimum number of players required to start a match can't be found, you can configure rule flexing to allow for the match to start with fewer players. This example configuration specifies that the minimum number of players per team required will reduce from five to three after 60 seconds of the match ticket entering the queue.

Note that alliance_flexing_rule in the JSON block defines how the rule will be relaxed after the specified duration. To add additional flexing rules for teams, add them as their own comma-separated blocks within alliance_flexing_rule.

Recommendation

We highly recommend using alliance flexing rules to elevate your overall gaming experience. This optimization allows your game to start quicker with just a few players as it significantly improve your players' chances of being matched up in the same session rather than ending up in separate lobbies.

{
"auto_backfill": true,
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 5,
"player_max_number": 5
},
"alliance_flexing_rule": [
{
"duration": 60,
"min_number": 2,
"max_number": 2,
"player_min_number": 3,
"player_max_number": 5
}
]
}
  • Duration: specifies the amount of time (in seconds) that must pass before the service will start flexing the rule.
  • Min number: specifies the updated minimum number of required teams for the match to start.
  • Max number: specifies the updated maximum number of teams that can participate in the match.
  • Player min number: specifies the updated minimum number of players required per team for the match to start.
  • Player max number: specifies the updated maximum number of players that can participate during the match.

Skill-based matchmaking

Matching on the player skill level or scores, like MMR, is a common practice that helps ensure players are equally matched when playing competitive games. To configure skill-based matching, you will need to configure statistics to track a skill to represent a player's proficiency at your game. Once the statistic is defined, it can be used to compare the distance between players to determine if they should match together. This example configuration specifies a match should contain two teams of five players, with a +/- 200 MMR variance allowed between players.

NOTE

matching_rule in the JSON block defines which statistic will be compared during evaluation. To add additional rules for more statistics, add them as their own comma separated block within matching_rule.

{
"auto_backfill": true,
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 5,
"player_max_number": 5
},
"matching_rule": [
{
"attribute": "mmr",
"criteria": "distance",
"reference": 200
}
]
}
  • Attribute: specifies the statistic that will be used to compare players for match fitness.
  • Criteria: specifies the criteria that will be used to compare the statistic.
    • Distance: currently only distance between is supported out of the box.
  • Reference: specifies the variance between statistics allowed, in this example players must be +/- 200 to be matched.

Rule flexing for statistics

In the case that there aren't enough players with a statistic value within the specified range, you can configure rule flexing to allow players to match at a larger variance. This example configuration specifies for every 15 seconds of waiting, the allowed variance will expand by 100 points, maxing out at 500 points.

NOTE

flexing_rule in the JSON block defines how the rule will be relaxed after the specified duration. To add additional flexing rules for statistics, add them as their own comma separated block within flexing_rule.

{
"auto_backfill": true,
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 5,
"player_max_number": 5
},
"matching_rule": [
{
"attribute": "mmr",
"criteria": "distance",
"reference": 200
}
],
"flexing_rule": [
{
"duration": 15,
"attribute": "mmr",
"criteria": "distance",
"reference": 300
},
{
"duration": 30,
"attribute": "mmr",
"criteria": "distance",
"reference": 400
},
{
"duration": 45,
"attribute": "mmr",
"criteria": "distance",
"reference": 500
}
]
}
  • Duration: specifies the amount of time (in seconds) that must pass before the service will start flexing the rule.
  • Attribute: specifies the statistic that will be used to compare players for match fitness.
  • Criteria: specifies the criteria that will be used to compare the statistic.
    • Distance: currently only distance between is supported out of the box.
  • Reference: specifies the new variance between statistics allowed, in this example it increases over time to +/-500 to be matched.

Custom parameter matchmaking

In some cases, it may be preferable to allow the game client to pass custom parameters, containing player preferences, as part of the match request to be used as matching criteria, some examples include map selection, language, or if they want participate in crossplay. This example configuration specifies that players can only match if they have both specified at least one matching map as their preference to play.

NOTE

matching_options in the JSON block defines which customer parameters passed in from the game client will be used during evaluation. To add additional rules for more custom parameters, add them as their own comma separated block within options .

{
"auto_backfill": true,
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 5,
"player_max_number": 5
},
"match_options": {
"options": [
{
"name": "map_names",
"type": "any"
}
]
}
}
  • Name: specifies the name (key) of the parameter that will be passed in from the game client.
  • Type: specifies how the custom parameter should be evaluated during matching.
    • All: indicates players must be matched with others who have the same parameters and values.
    • Any: indicates players must be matched with others who have the same option parameter name and at least have one matching value.
    • Unique: indicates players must be matched with others who have the same option parameter name, but different values.

Adding custom parameters to the matchmaking request in the game client

To pass custom parameters from the game client, you will need to implement a way for players to select their preferences that can then be passed as part of the match request. Then, using the example below, you can implement adding those preferences as custom parameters to include in the request.

NOTE

The name specified for the parameter must match what is configured in the match ruleset JSON.

const IOnlineSubsystem* Subsystem = Online::GetSubsystem(GetWorld());
if (!ensure(Subsystem != nullptr))
{
return;
}

const FOnlineSessionAccelBytePtr SessionInterface = StaticCastSharedPtr<FOnlineSessionV2AccelByte>(Subsystem->GetSessionInterface());
if (!ensure(SessionInterface.IsValid()))
{
return;
}
const FUniqueNetIdPtr LocalPlayerId = GetUniquePlayerId();
if (!ensure(LocalPlayerId.IsValid()))
{
return false;
}

// Create a new search handle instance for matchmaking. Importantly, you will need to set the match pool that you are searching for with SETTING_SESSION_MATCHPOOL, as shown below.
TSharedRef<FOnlineSessionSearch> MatchmakingSearchHandle = MakeShared<FOnlineSessionSearch>();
MatchmakingSearchHandle->QuerySettings.Set(SETTING_SESSION_MATCHPOOL, FString(TEXT("YOUR_MATCHPOOL_NAME_GOES_HERE")), EOnlineComparisonOp::Equals);

// Add the map names as values for the custom parameter
MatchmakingSearchHandle->QuerySettings.Set(
FName(TEXT("map_names")),
TEXT("map_01"), EOnlineComparisonOp::Equals);

// Bind a function that has a return type of void and these parameters:
// FName SessionName, bool bWasSuccessful
const FOnMatchmakingCompleteDelegate OnMatchmakingCompleteDelegate = /* Bind to lambda or class method */;
SessionInterface->AddOnMatchmakingCompleteDelegate_Handle(OnMatchmakingCompleteDelegate);

if (SessionInterface->StartMatchmaking(USER_ID_TO_MATCHMAKING_USER_ARRAY(LocalPlayerId.ToSharedRef()), NAME_GameSession, FOnlineSessionSettings(), MatchmakingSearchHandle, OnStartMatchmakingCompleteDelegate))
{
// Update the current search result handle class member with the search handle passed to the matchmaking service.
CurrentMatchmakingSearchHandle = MatchmakingSearchHandle;
}

Region expansion ruleset

Since we want to provide the best matchmaking experience, our matchmaking logic has strict rules when it comes to matching players based on latency. However, there are times when a game has a small player base, so it's difficult for them to find a match if they are only looking in their region. The region expansion ruleset is specifically for games that support players that are spread across multiple regions. In this case, players will be able to request matchmaking based on their preference and on the regions provided by the game. This configuration can be used to match players in different regions based on player latencies, which will flex over time based on the value that has been set in the match ruleset.

{
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 1,
"player_max_number": 1
},
"auto_backfill": false,
"region_latency_initial_range_ms": 50,
"region_expansion_range_ms": 50,
"region_expansion_rate_ms": 10000,
"region_latency_max_ms": 200
}
  • region_latency_initial_range_ms: specifies the initial ticket latency that determines whether a player's ticket search needs to be expanded or not.
  • region_expansion_range_ms: specifies how many ms will be added to pivot latency on each MM tick.
  • region_expansion_rate_ms: specifies how many ms rate for the additional region_expansion_range_ms will be added to the pivot ticket.
  • region_latency_max_ms: specifies he maximum limitation of latency that can be expanded.

The match ruleset above will work as follows:

  1. "region_latency_initial_range_ms": 50 means:
    • If a player has <50ms latency, the ticket search doesn't need to be expanded. For example, if two players each have <50ms, they will be matched to each other immediately.
    • If a player has >50ms latency, the ticket search will expand depending on how much latency the player has. For example, if two players each have 90ms latency, they will need to wait for 10 seconds (first search expansion) to be matched to each other.
  2. "region_expansion_rate_ms": 10000 means every 10 seconds, ticket search is expanded.
  3. "region_expansion_range_ms": 50 means each ticket search is expanded every 10 seconds and it will increase the latencies by 50ms.
  4. "region_latency_max_ms": 200 means a player who has >200 latency will be unable to match.

Configure rulesets in the Admin Portal

  1. First, determine the desired logic you want the ruleset to use when comparing players for a match. Once the JSON has been defined, continue with creating the ruleset.

  2. In the Admin Portal, select your desired Namespace. In the left-hand menu, navigate to Game Management, click New Matchmaking, and select Match Configuration.

    Select match config

  3. Select + Create Rulesets in the top right-hand corner.

    Select ruleset

  4. The Create Match Ruleset page will appear.

    Create match ruleset

  5. In the Ruleset Name field, enter the name for this ruleset.

  6. In the Configuration (JSON) field, replace the body with your desired JSON.

  7. If there are no validation errors, click the Create button.

Example: Team 8 vs. 8

In this example, the JSON will configure matchmaking to function with this criteria:

  • Auto-backfill is disabled.
  • There must be two teams before the match can start.
  • There can't be more than two teams.
  • There must be at least four players on each team before the match can start.
  • There can't be more than eight players per team.
{
"auto_backfill": false,
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 4,
"player_max_number": 8
}
}

Example: 4 player co-op with player level and rating matching

In this example, the JSON will configure matchmaking to function with this criteria:

  • Auto-backfill is enabled.
  • There will only be one team as this is a co-op match.
  • There must be four players before the match can start.
  • Matchmaking will attempt to find four players within two levels and 20 rating points of the pivot player.
    • In this example, rating specifies a players rating according to others they have played with.
{
"auto_backfill": true,
"alliance": {
"min_number": 1,
"max_number": 1,
"player_min_number": 4,
"player_max_number": 4
},
"matching_rule": [
{
"attribute": "level",
"criteria": "distance",
"reference": 2
},
{
"attribute": "rating",
"criteria": "distance",
"reference": 20
}
]
}

Example: 25 player free for all with MMR flexing

In this example, the JSON will configure matchmaking to function with this criteria:

  • Auto-backfill is enabled.
  • There will only be one team as this is a free for all match.
    • Note: there will always need to be one underlying team even if they players aren't working together.
  • There must be 25 players before the match can start.
  • Matchmaking will attempt to find 25 players within 200 MMR of the pivot player.
  • If after 15 seconds 25 players haven't been matched, matchmaking will attempt to find additional players within 300 MMR of the pivot player.
  • If after 30 seconds 25 players haven't been matched, matchmaking will attempt to find additional players within 400 MMR of the pivot player.
  • If after 45 seconds 25 players haven't been matched, matchmaking will attempt to find additional players within 500 MMR of the pivot player.
{
"auto_backfill": true,
"alliance": {
"min_number": 1,
"max_number": 1,
"player_min_number": 25,
"player_max_number": 25
},
"matching_rule": [
{
"attribute": "mmr",
"criteria": "distance",
"reference": 200
}
],
"flexing_rule": [
{
"duration": 15,
"attribute": "mmr",
"criteria": "distance",
"reference": 300
},
{
"duration": 30,
"attribute": "mmr",
"criteria": "distance",
"reference": 400
},
{
"duration": 45,
"attribute": "mmr",
"criteria": "distance",
"reference": 500
}
]
}

Example: Team 4 vs 4 with crossplay preference validation

In this example, the JSON will configure matchmaking to function with this criteria:

  • Auto-backfill is disabled.
  • There must be two teams before the match can start.
  • There can't be more than two teams.
  • There must be at least four players on each team before the match can start.
  • There can't be more than four players per team.
  • Only players who select to crossplay on the same platforms will be matched.
{
"auto_backfill": false,
"alliance": {
"min_number": 2,
"max_number": 2,
"player_min_number": 4,
"player_max_number": 4
},
"match_options": {
"options": [
{
"name": "cross_platform",
"type": "all"
}
]
}
}