Matchmaking Tasks #
Matchmaking features are built and customized using a combination of calls and plugin methods. This page describes common matchmaking operations, along with descriptions of SDK actions and related Matchmaking plugin methods.
Common matchmaking operations include:
- Initialize the matchmaking process
- Match parties
- Move parties between Matchables
- Add custom behavior after a matchmaking loop
- Start or update a game instance
- Continue matchmaking after creating or updating a game
- Leave matchmaking
For a full list of all available Matchmaking service SDK calls and events, see Matchmaking SDK and Events. For Matchmaking Plugin methods, see the MatchmakingPlugin reference pages.
Initialize the matchmaking process #
Perform any validation logic or party/player transformations before adding the party to a matchmaking queue.
The matchmaking process starts when parties enter the Matchmaking service from the Party service. The initialize
method is called every time a new party enters the Matchmaking service via MatchmakingService.enterMatchmaking
, which is called as part of PartyService.enterMatchmaking
.
interface MatchmakingPlugin {
fun initialize(
queueKey: MatchmakingQueueKey,
party: Matchmaking.Party
): NewGameInstance? {
// Custom logic to run before adding this party to a queue
}
}
Add custom logic to the initialize
method to determine one of the following outcomes:
- Party is added to the matchmaking queue
- Party is fast-tracked to the game instance
- Party is prevented from joining the queue
If a party is successfully added to the matchmaking queue, the initialize method returns null
and a Matchable is created for that party. This Matchable is like a train car, where there’s space for other parties to join until the car is full.
If a party contains all the players needed for a game instance, and the developer wants to enable fast-tracking the game instance and ignore any mismatches that would typically invalidate a matchup (such as skill disparity), initialize
can generate a NewGameInstance
directly. For example, custom games for events like in-house tournaments may want to skip matchmaking and place players directly in a game instance regardless of skill level or other standard matchmaking data.
If the party cannot join the matchmaking queue due to validation errors, an ExtException
is thrown. The party leader will receive the PartyService_FailedToEnterMatchmaking
error.
Match parties #
Design logic to compare parties and form or update game instances.
The primary methods in the Matchmaking Plugin are matchParties
and matchPartiesWithGame
, which are used to perform matchmaking operations such as comparing players and moving them between Matchables.
Compare parties in the Matchmaking queue #
As part of the matchParties
method, Matchables are compared using a set of developer-defined matchmaking data, such as skill level or preferred game server zones. Only two Matchables can be compared at once. One is considered the anchor
Matchable, and the other is considered the other
Matchable.
interface MatchmakingPlugin {
fun matchParties(
queueKey: MatchmakingQueueKey,
anchor: Matchable,
other: Matchable
): NewGameInstance? {
// Custom matchmaking logic
}
}
Build logic in the matchParties
method to compare parties in the Matchables. The method can be used to do the following:
- if a match is found, create and return a
NewGameInstance
. See Start a new game instance. - if moving parties between the
anchor
andother
Matchable would result in a better match, calltakePartiesFrom
to move the parties. See Move parties between Matchables. - no match is found, call
endOfLoop
to advance theanchor
to the next-oldest queue member. See Add custom behavior after matchmaking loop.
Compare parties with an active game instance #
The Matchmaking service uses Matchmaking Game Instances to allow game instances that have already been sent to a game server to accept new parties by entering matchmaking. When a game instance enters matchmaking to receive more parties, the Matchmaking Plugin’s matchPartiesWithGame
method is called.
interface MatchmakingPlugin {
fun matchPartiesWithGame(
queueKey: MatchmakingQueueKey,
anchor: Matchable,
game: Matchmaking.GameInstance
): GameInstanceUpdate? {
// Custom matchmaking logic for active game instances
}
}
Build logic in the matchPartiesWithGame
method to determine if a party should be added to the game instance. The method can be used to do the following:
- if a match is found, create and return a
GameInstanceUpdate
. See Start or update a new game instance. - if moving parties from the
anchor
to thegame
Matchable would result in a better match, add the parties to thegame
Matchable. See Move parties between Matchables. You cannot take parties from a game instance.
When adding new players to a Matchmaking Game Instance, an OnAddPlayers
event is sent via WebSocket connection. To use this feature, your game server must be using WebSockets instead of HTTP to connect to Pragma Engine.
Comparison data #
When comparing Matchables, the following information is available to the Matchmaking Plugin for consideration in your matchmaking logic. This data is stored on the Matchable object.
parties
- list of matchmaking partiespartyId
: UUIDext
: ExtMatchmakingPartypreferredGameServerZones
: Listplayers
: List<Matchmaking.Player> - details for all players within that matchmaking partyplayerCount
: Int - count of players in this partysecondsInQueue()
: Int
players
- list of all players in match partiesplayerId
: UUIDsocialId
: UUIDdisplayName
: PragmaDisplayNameteamNumber
: IntpartyId
: UUIDgameServerZoneToPing
: Map<String, Int>
matchmakingKey
: ExtMatchmakingKey - theext
data associated with the queuegameServerVersion
: String - the version of the game server the match would be played on
Move parties #
Take parties from one Matchable and move them to another Matchable or Matchmaking.GameInstance.
Move parties between Matchables #
When the logic in the matchParties
method determines that parties should be moved from one Matchable to another, they can be moved by invoking the Matchable.takePartiesFrom
method. Both the anchor
Matchable and the other
Matchable can take parties from one another.
interface Matchable {
fun takePartiesFrom(matchable: Matchable, parties: List<Matchmaking.Party>)
}
Add parties to a game instance #
When the logic in the matchPartiesWithGame
method determines that additional parties should be moved into the Matchmaking.GameInstance, they can be moved by invoking the GameInstanceUpdate.addParties
method. Only the game
MatchakingGameInstance can gain parties; the anchor
Matchable cannot take parties from the Matchmaking.GameInstance
.
interface GameInstanceUpdate {
fun addParties(parties: List<Matchmaking.Party>, teamNumber: Int = 0) {
setTeamByPlayers(parties.flatMap { it.players }, teamNumber)
internalParties.addAll(parties.map { it as MatchmakingPartyImpl })
}
Moving parties between Matchables does not automatically update team numbers. For existing game instances you can use theteamNumber
parameter in theaddParties
method. Otherwise, use the functions in the Assign Teams section to change team numbers as necessary.
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:
fun endOfLoop(
queueKey: MatchmakingQueueKey,
anchor: Matchable
): NewGameInstance?
Example: Use this function to examine data such as match queue time and create a NewGameInstance
immediately, even if the matchmaking process failed to build an ideal complete Matchable. This capability can be leveraged to build matches with a limited matchmaking pool, such as during testing.
Start or update a game instance #
Create a new game instance or update an existing game instance and send data to the game server.
After successfully matching parties using the matchParties
or matchPartiesWithGame
methods, the game instance data needs to be communicated to the game server. This information is sent when creating and returning a NewGameInstance
of GameInstanceUpdate
.
When returning a NewGameInstance
or a GameInstanceUpdate
:
- Add parties to the game instance using
addParties
- Set team numbers using
setTeamByPlayers
(optional; default 0) - Use
setExtGameParty
to set/update theExtGameParty
payload for a given party in the game instance update. This data will be set on theGameInstance
for the specified party. - Use setExtGamePlayer to set/update the
ExtGamePlayer
payload for a given player in the game instance update. This data will be set on theGameInstance
for the specified player. - Call the
continueMatchmaking
method with aMatchmakingQueueKey
if the NewGameInstance/GameInstanceUpdate should continue to find players
In addition, if creating a new game instance, set the NewGameInstance.ext
(ExtGameInstance
) and NewGameInstance.gameServerZone
values using the constructor.
Continue matchmaking #
Continue matchmaking process after creating or updating a game.
After you create a NewGameInstance
or GameInstanceUpdate
from the matchmaking process, you have the option to keep the game instance in the matchmaking queue to continue accepting new players/parties. Game instances remain in matchmaking as long as their continueMatchmaking
property is true
.
By default, NewGameInstance.continueMatchmaking
is false
, meaning the new game instance will exit the matchmaking process as soon as it is created. If you want a new game instance to continue accepting new players/parties, call NewGameInstance.continueMatchmaking
with the appropriate matchmaking queue key. When called, the continueMatchmaking
boolean is set to true
and the game instance will be added to the matchmaking queue.
Because GameInstanceUpdate
objects are created with the express purpose of entering matchmaking, the GameInstanceUpdate.continueMatchmaking
value defaults to true
.
Leave matchmaking #
Exit the matchmaking process.
Leave matchmaking as a player #
Players can request to leave matchmaking by invoking GameLoopApi.LeaveMatchmaking
. This action removes their whole party from the matchmaking service.
Player->GameLoopApi()->LeaveMatchmaking(
OnComplete
)
player.GameLoopApi.LeaveMatchmaking(
OnComplete
)
{
"requestId": 15,
"type": "matchmakingRpc.LeaveMatchmakingV2Request",
"payload": {
}
}
After the player and their party are removed from matchmaking, players receive a OnLeftMatchmaking
event. The GameLoopApi LeaveMatchmaking
method also triggers the Party Plugin’s returnFromMatchmaking
method, which provides a way to handle players and parties leaving matchmaking. See Party Service Tasks: Return from Matchmaking for more information.
Leave matchmaking as a game instance #
If, after creating a Game Instance Update object, you want the Matchmaking Game Instance to leave matchmaking, use GameInstanceUpdate.stopMatchmaking
.
interface GameInstanceUpdate {
fun stopMatchmaking() {
continueMatchmaking = false
}
}
Game servers can also directly request to leave matchmaking by invoking MatchApi.LeaveMatchmaking
.
Player->MatchApi()->LeaveMatchmaking(
gameInstanceId,
Delegate
)
player.MatchApi.LeaveMatchmaking(
gameInstanceId,
callback
)
{
"requestId": 16,
"type": "matchmakingRpc.LeaveMatchmakingV2Request",
"payload": {
}
}
Examples #
Example: Party enters matchmaking service #
When a party enters the matchmaking service it joins the matchmaking queue as a Matchable object. The matchmaking service uses logic defined in the Matchmaking Plugin’s matchParties
method to compare Matchable objects. During this matchmaking process, parties may be added to or removed from Matchable objects. If the matchParties
method determines that two Matchables are a match, a NewGameInstance
is generated and the Matchable is sent to the game server.
Example: Game Instance enters matchmaking #
Depending on your settings, a game instance can enter the matchmaking service and accept additional parties. For example, a battle royale mode may keep all players in a pre-game lobby where they can interact with each other before the full game has been built. This lobby exists on a game server, and this game requires the use of a Matchmaking Game Instance. The matchPartiesWithGame
method is called when a Matchmaking Game Instance enters the matchmaking process. Like the matchParties
function compares a queued Matchable to an anchor Matchable, the matchPartiesWithGame
function compares an anchor
Matchable with the Matchmaking.GameInstance
.