Skip to main content

Configure match rulesets

Last updated on October 24, 2024

Overview

Match rulesets define the logic that AccelByte Gaming Services (AGS) Matchmaking will use to determine if and when match tickets can be paired together. Here are some key terms associated with rulesets:

  • Attributes: also referred to as statistics, these are numeric values, such as matchmaking rating (MMR), that can be used to compare tickets to determine how fit they are to be matched together. These values must be stored in AGS Statistics to be used during matchmaking.

  • Custom Parameters: key-value pairs that represent player preferences passed to AGS Matchmaking 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 times.

This article will show you how to configure rules to enable team-based, skill-based, and custom parameter matching between players. It will also show you 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.

Goals

This article aims to provide you with an overview of match rulesets and an understanding of:

  • Configuring rulesets in the AGS Admin Portal.
  • The different types of behaviors that can be enabled as part of a ruleset.
  • Enabling flexing of the defined behavior to prevent players from waiting in a queue too long.

Prerequisites

To complete all the steps in this article, you will need:

Team-based matchmaking

To configure team-based matchmaking, 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. The example configuration below specifies that there needs to be two teams, with no less than five players in the game 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. The example configuration below 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

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.

tip

It is highly recommended to use 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 improves 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

To configure skill-based matching, you will need to configure AGS Statistics to track metrics that represent a player's skill. Once a statistic is defined, it can be used to compare the distance between players to determine if they should match together. The example configuration below specifies a match should contain two teams of five players, with a +/- 200 matchmaking rating (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,
"max": 3000
}
]
}
  • 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. NOTE: "distance" is the only criterion currently supported.
  • Reference: specifies the variance between statistics allowed. In this example, players must be +/- 200 to be matched.
  • Max: specifies the maximum value for the statistic attributes. This will be used for the matching and rebalancing process.

Rule flexing for statistics

In the event 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. The example configuration below specifies that 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. NOTE: "distance" is the only criterion currently supported.
  • 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 to participate in crossplay. The example configuration below 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.

Add 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. IMPORTANT: 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 AGS Matchmaking.
CurrentMatchmakingSearchHandle = MatchmakingSearchHandle;
}

Region expansion ruleset

Since you want to provide the best matchmaking experience, the 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 would 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 the example below, 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 milliseconds (ms) will be added to the pivot latency on each matchmaking tick.
  • region_expansion_rate_ms: specifies how many ms rates 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 example above will work as follows:

  1. "region_latency_initial_range_ms": 50 means:
    • If a player has less than 50 ms of latency, the ticket search doesn't need to be expanded. For example, if two players each have less than 50 ms, they will be matched to each other immediately.
    • If a player has greater than 50 ms of latency, the ticket search will expand depending on how much latency the player has. For example, if two players each have 90 ms of 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 after every 10000 ms (10 seconds), the ticket search is expanded.
  3. "region_expansion_range_ms": 50 means when a ticket search is expanded (every 10 seconds in this example), it will increase the latencies by 50 ms.
  4. "region_latency_max_ms": 200 means a player who has greater than 200 latency will be unable to match.

Bidirectional Region or Latency Match

When filtering the matching player candidates (match tickets), matchmaking will apply the region expansion logic based on the age of each player's match ticket. The search for a match will only allow candidate players who have the same region as the pivot player (match ticket) or have already expanded to the same region with the pivot players.

For each {region} in [pivot player's regions]
For each candidate tickets:
apply region expansion logic based on candidate ticket's age
include candidate ticket only if it has expanded to {region}

Here's a sample scenario of two tickets with a specific ruleset:

  • Tickets:

    • player 1 latencies: us-east-1: 50ms, us-east-2: 50ms, us-west-2: 80ms, eu-west-1: 100ms, eu-central-1: 102ms, ap-southeast-1: 200ms
    • player 2 latencies: us-east-1: 150ms, us-east-2: 100ms, us-west-2: 122ms, eu-west-1: 30ms, eu-central-1: 55ms, ap-southeast-1: 200ms
  • Ruleset:

    {
    "alliance": {
    "min_number": 2,
    "max_number": 2,
    "player_min_number": 1,
    "player_max_number": 1
    },
    "auto_backfill": false,
    "region_latency_initial_range_ms": 30,
    "region_expansion_range_ms": 50,
    "region_expansion_rate_ms": 10000,
    "region_latency_max_ms": 350
    }

Assuming that matchmaking is set to tick every 10 seconds and Player 1 is a pivot. The player 1 will search for eu-west-1 and eu-central-1 on the third expansion, which is at 130 milliseconds (ms ). If Player 3 submits a match ticket when Player 1 has already expanded to 110ms, Player 2 will not be matched to Player 1 since Player 2 is not on the region expansion yet and is still searching within the eu-west-1 region.

However, at some point, you may want to allow tickets that are too old to skip the bi-directionality and find a match with tickets that are in its expansion range. To do this, you can use the disable_bidirectional_latency_after_ms (in milliseconds) option in the ruleset. By default, it is disabled (0 or negative), which means it will always adhere to bi-directionality. But, if set, any pivot ticket older than disable_bidirectional_latency_after_ms will skip the step of filtering candidate tickets.

Rebalance of matched teams with multiple attributes

Rebalance is a process where the matchmaking will arrange players who already matched together into a balanced team. In a competitive game, the rebalance process is important to make sure that the gameplay is fair and the overall MMR is similar among match teams. Matchmaking will always put players with a party in the same team.

By default, the attribute that will be used for the rebalance process is the first configuration in the matching rule. For example:

{
"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
},
{
"attribute": "elo",
"criteria": "distance",
"reference": 100
},
]
}

In the sample ruleset above, only the attribute mmr will be used for the rebalance process. However, we can set both attributes to be considered in the rebalancing process using the is_for_balancing flag.

{
"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,
"is_for_balancing": true
},
{
"attribute": "elo",
"criteria": "distance",
"reference": 100,
"is_for_balancing": true
},
]
}

AccelByte recommends defining the max value for any statistic code that will be used in the matching rule config. By configuring the maximum stats value, the matchmaking can normalize the stats attribute and put a better weight for the matching and rebalance process.

{
"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,
"max": 2000,
"is_for_balancing": true
},
{
"attribute": "elo",
"criteria": "distance",
"reference": 100,
"max": 3000,
"is_for_balancing": true
},
]
}

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 AGS Admin Portal, navigate to your desired namespace and go to Multiplayer > Matchmaking > Matchmaking Configuration.

  3. On the Match Ruleset tab, click + Create Rulesets. The Create Match Ruleset page will appear.

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

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

  6. If there are no validation errors, click Create.

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 players aren't working together.
  • There must be 25 players before the match can start.
  • Matchmaking will attempt to find 25 players within 200 matchmaking rating (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"
}
]
}
}