Define Matchmaking Logic #

This topic provides instructions on how develop logic for matching parties with other parties, or matching parties with existing game instances, to create suitable matches.

Match parties in the matchmaking queue #

Design logic to compare parties to send to a game instance

Match parties

Parties enter the matchmaking process, comparing themselves until a suitable match is found and a new game instance is created

You can customize the matchParties() method to compare two Matchables in the matchmaking queue with the goal of creating a set of parties that should be sent to a game instance together. matchParties() compares a specific anchor Matchable with all other Matchables in the queue before changing anchor to the next-oldest queue member.

interface MatchmakingPlugin {
    fun matchParties(
        queueKey: MatchmakingQueueKey,
        anchor: Matchable,
        other: Matchable
    ): NewGameInstance? {
        return null
    }
}

Within matchParties(), do the following:

  • Compare parties in the anchor Matchable to parties in the other Matchable using a set of developer-defined matchmaking data, such as skill level or preferred game server zones.
  • Move parties between the two Matchables to work toward creating a set of parties to send to a new game instance. Both anchor and other can take parties from one another using takePartiesFrom(). When parties move between Matchables, that change persists for the life of the party unless the party is deliberately moved elsewhere.
  • If a complete match is not found using parties in the anchor and other Matchable, return null to continue the matching parties with a new anchor.
  • If a complete match is found, send appropriate parties to a new game instance together. See Create Game Instance from Matchmaking.
If the matchParties() method throws an exception, the Matchmaking service logs an error and removes both the anchor Matchable and the other Matchable from the queue to allow for debugging. Players are notified via a SessionChangedV1Notification. The anchor position is then reset to the oldest Matchable in the queue.

Match parties with an active game instance #

Design logic to add parties to an existing game instances

Add to game instance

Game instance enters the matchmaking process, analyzing other parties to find suitable players to add to the game instance

When a game instance enters matchmaking to receive more parties, the Game Instance Matchmaking Plugin builds customized data about the game instance (ExtMatchmakingGameInstance) and the players within it (ExtMatchmakingGamePlayer). The data in these ext payloads will be made available to the Matchmaking Plugin’s matchPartiesWithGame() function via the Matchmaking.GameInstance object when comparing game instances.

If game instance data (player list, ext payloads, etc.) is updated while the game instance is in matchmaking, the changes are automatically sent matchmaking to ensure the matchmaking representation of the game instance is up to date.
suspend fun buildExtMatchmakingGameInstance(
    gameInstance: GameInstance.GameInstance
): ExtMatchmakingGameInstance

suspend fun buildExtMatchmakingGamePlayer(
    gameInstance: GameInstance.GameInstance,
    player: GameInstance.GamePlayer
): ExtMatchmakingGamePlayer

Use matchPartiesWithGame() to determine whether parties in a Matchable should be added to the existing game instance. The Matchmaking Plugin’s matchPartiesWithGame() method is called for each anchor Matchable in the specified matchmaking queue until stopMatchmaking() is called.

interface MatchmakingPlugin {
    fun matchPartiesWithGame(
        queueKey: MatchmakingQueueKey,
        anchor: Matchable,
        game: Matchmaking.GameInstance
    ): GameInstanceUpdate? {
        return null
    }
}

Within matchPartiesWithGame(), do the following:

  • Use developer-defined matchmaking data, such as skill level or preferred game server zones, to determine if a party or parties in the anchor should be added to the current game instance.

  • If parties in the anchor Matchable should not added to the game instance:

    • Return null to advance the anchor Matchable.
  • If parties in the Matchable should be added to the game instance. See [Add More Players to a Game Instance].

Moving parties between Matchables does not automatically update team numbers. For existing game instances you can use the teamNumber parameter in the addParties() method.

Add custom behavior after matchmaking loop #

Define what happens after an anchor Matchable exhausts the matchmaking queue

If an anchor Matchable makes it through the entire queue without forming a complete match, the default behavior is that the anchor position is moved to the next oldest Matchable in the queue. Custom behavior can be added before the anchor position is moved by defining logic in the endOfLoop() method. This method gives the plugin a chance to start a new game instance even if ideal matches were not made during the iteration. For example, when building matches with a limited matchmaking pool, such as during testing.

interface MatchmakingPlugin {
    fun endOfLoop(
        queueKey: MatchmakingQueueKey,
        anchor: Matchable
    ): NewGameInstance?
    return null
}
The endOfLoop() method is also called if there is only one item in the matchmaking queue.

Customize queue names for reporting #

Customize queue names for metrics/logging

For purposes of viewing metrics and logs, you might want to group various matchmaking queues into one metric/log entry. You can generate a queue name using the Matchmaking Plugin’s getQueueName() method, which is called during instantiation of a new matchmaking queue or when a metric/log requires a queue name and doesn’t already have access to the queue.

For example, say your ExtMatchmakingKey contains a game mode, along with various other parameters needed for matchmaking purposes (region, difficulty, etc.). For reporting purposes, you might want matchmaking queues with the same game mode to appear as one metric. To do so, customize the getQueueName() function in your implementation of the Matchmaking Plugin:

override fun getQueueName(extMatchmakingKey: ExtMatchmakingKey): String {
    return extMatchmakingKey.gameMode;
}

If you don’t customize getQueueName(), the function returns “undefinedqueueName” by default.