Game Instance Tasks #
Game Instance features are built and customized using a combination of calls and plugin methods. This page describes common game instance operations, along with descriptions of SDK actions and related plugin methods.
Common game instance operations include:
For a full list of all available Game Instance service SDK calls and events, see Game Instance SDK and Events. For Game Instance Plugin methods, see the GameInstancePlugin and GameInstanceMatchmakingPlugin reference pages.
Add players and parties to a game instance #
Add players and parties to a new or existing game instance.
Players and parties are added to game instances via the NewGameInstance
object (for newly created game instances) or the GameInstanceUpdate
object (for existing games accepting new players/parties). These objects are returned by Matchmaking Plugin methods and initialize/update a GameInstance
object in the Game Instance service.
See Compare parties with an active game instance and Start or update a game instance for more information on adding parties to game instances.
Assign teams #
Assign players to teams.
Team numbers are assigned to players when their party is added to a NewGameInstance
(NewGameInstance.addParties
). If the team number is not specified, all players default to team 0.
To assign team numbers by player, use the NewGameInstance
or GameInstanceUpdate
setTeamByPlayers
method and specify one or more players to add to a team.
fun setTeamByPlayers(
players: List<Matchmaking.Player>,
teamNumber: Int
)
Send custom game data to the game server #
Send game and player data to the game server
When a game server is allocated a game, the game server SDK calls getGameStartDataV1
to get the game start data.
The getGameStartDataV1
function invokes the Game Instance Plugin’s buildExtGameStart
plugin method once. This method builds the ExtGameStart
payload, which declares custom data to start the game instance.
suspend fun buildExtGameStart(
gameInstance: GameInstance.GameInstance
): ExtGameStart
The getGameStartDataV1
function also invokes the Game Instance Plugin’s buildExtGameServerPlayer
plugin method for each player in the game. This method builds the ExtGameServerPlayer
payload, which declares custom data to send to the game server for a player.
suspend fun buildExtGameServerPlayer(
gameInstance: GameInstance.GameInstance,
player: GameInstance.GamePlayer
): ExtGameServerPlayer
Send custom game data to players #
Send custom game data to players
When a player is added to a game, the OnAddedToGame
event triggers with the ExtAddedToGame
payload.
public event Action<PragmaId, ExtAddedToGame> OnAddedToGame;
The buildExtAddedToGame
function allows for customization of ExtAddedToGame
data to send to the player when they are added to a new game. This data will be sent to the players immediately, even if a game server is still preparing to host the game instance.
suspend fun buildExtAddedToGame(
gameInstance: GameInstance.GameInstance,
player: GameInstance.GamePlayer
): ExtAddedToGame
Update custom data for a game instance #
Update game data for a running game instance
The game server can call the UpdateGameInstance
SDK method to trigger an update of the custom data held within the platform for a game instance.
Server->MatchApi()->UpdateGameInstance(
gameInstanceId,
extUpdateGameInstanceRequest,
Delegate
);
Server.MatchApi.UpdateGameInstance(
gameInstanceId,
extUpdateGameInstanceRequest,
callback
);
{
"requestId": 17,
"type": "gameInstanceRpc.UpdateGameInstanceV1Request",
"payload": {
"game_instance_id": "1",
"request_ext":{}
}
}
When called, the UpdateGameInstance
SDK method will trigger the Game Instance plugin method updateGameInstance
. This plugin function provides full access to the desired game instance and the ExtUpdateGameInstancRequest
payload that the game server sent. By defining custom data in the ExtUpdateGameInstanceRequest
payload, users can describe how the running game instance should be updated. All of the ext
payloads held on the GameInstance (ExtGameInstance
, ExtGameParty
for each party, and ExtGamePlayer
for each player) are stored as variables and may be replaced with new payloads containing updated data, allowing users to update those ext
payloads during the game.
suspend fun updateGameInstance(
gameInstance: GameInstance.GameInstance,
requestExt: ExtUpdateGameInstanceRequest
)
For example, you may have a currently running game instance whose matchmaking needs change depending on the game’s state. If a game disproportionately favors one team, you might want to adjust what skill level you are looking for in a new player. You can specify this information in the ExtUpdateGameInstanceRequest
ext
.
If the game instance being updated is currently in matchmaking, all of the matchmaking ext
payloads for this game instance will be recalculated and sent to matchmaking to ensure the matchmaking representation of the game instance is up to date. See Enter matchmaking to connect more players for more information about which plugins are invoked during this operation.
Verify players #
Set up a player/host verification process
Pragma Engine can use connection tokens to verify the correct players join a game instance. The player verification process is optional, but recommended for competitive games.
Once a game server calls MatchApi.ConnectPlayers
to indicate that it’s ready for players to join the game instance, players receive a OnHostConnectionDetailsReceived
notification, which includes the host connection details. Host connection details include host name, port, game instance ID, the ExtPlayerConnectionDetails
payload (which can be used to define custom game server host information), and a connection token.
The player client needs to provide the connection token to the game server upon joining the game instance. The game server then sends the connection token to the engine via MatchApi.VerifyPlayer
so the engine can validate the token. If the engine determines the token is valid, players can join the game instance.
A player who disconnects and reconnects to the same game instance will receive the same connection token on the OnGameInstanceReconnect
notification.
Enter matchmaking to connect more players #
Connect more players to your game instance
Game instances can enter matchmaking to accept more players. When a game instance enters matchmaking, the Game Instance Matchmaking Plugin builds customized data about the game instance (ExtMatchmakingGameInstance
), the parties within it (ExtMatchmakingGameParty
), or the players within it (ExtMatchmakingGamePlayer
).
suspend fun buildExtMatchmakingGameInstance(
gameInstance: GameInstance.GameInstance
): ExtMatchmakingGameInstance
suspend fun buildExtMatchmakingGameParty(
gameInstance: GameInstance.GameInstance,
party: GameInstance.GameParty
): ExtMatchmakingGameParty
suspend fun buildExtMatchmakingGamePlayer(
gameInstance: GameInstance.GameInstance,
party: GameInstance.GameParty,
player: GameInstance.GamePlayer
): 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. (See Add parties and players to active game instances).
Reconnect players #
Reconnect disconnected players to the same game instance
Pragma Engine provides a way to reconnect players who disconnect during a game instance. This feature can be configured via the GameInstanceServiceConfig.reconnect
config value with the following options in the GameInstanceReconnect
enum: OFF
, REQUIRED
, and OPTIONAL
. The default value is OFF
.
value | description |
---|---|
OFF | When the player reconnects to the engine, no reconnect to the game instance is attempted. |
OPTIONAL | When the player reconnects to the engine, the game instance reconnect flow is triggered, and the player can accept or decline the game instance. |
REQUIRED | When the player reconnects to the engine, the game instance reconnect flow is triggered, and the player must reconnect to the game instance. |
When the configuration is set to OPTIONAL
or REQUIRED
and the game instance reconnect flow is triggered, the engine sends a OnGameInstanceReconnect
to the player’s client with the game instance details. If the game instance is still active (and if the player accepts the reconnect when the OPTIONAL
value is set), the client uses these connection details to reconnect the player to the active game instance.
When the configuration is set to OPTIONAL
and the player declines the reconnect with DeclineReconnect
, the game server receives a OnPlayerDeclinedReconnect
notification to inform the game server that the player is no longer expected to return to the game instance. At this point, the game server can invoke removePlayers
for the departing player to provide any details it would like to record about the player’s performance.
Player->GameLoopApi().DeclineReconnect(OnComplete);
Player.GameLoopApi.DeclineReconnect(onComplete);
{
"requestId": 18,
"type": "gameInstanceRpc.DeclineReconnectV1Request",
"payload": {
"game_instance_id": "1"
}
}
Connection details #
The service endpoint matchReconnectV1
is called automatically if a player logs in while their session indicates they’re in an existing game instance. This results in a OnGameInstanceReconnect
being sent to the player’s client, and includes the host connection details. These details can also be requested from a player client using the matchConnectionDetailsV1
endpoint.
Remove players from a game instance #
Remove one or more players from the current game instance
The game server can call MatchApi.removePlayers
to remove one or more players from an active game instance. Game results and metrics can be stored in the ExtRemovePlayersRequest
payload (for game-specific data) and the ExtRemovePlayer
payload in the list of players to remove (for player-specific data).
Server->MatchApi()->RemovePlayers(
GameInstanceId,
PlayersToRemove,
ExtRemovePlayersRequest,
RemovePlayersDelegate
)
Server.MatchApi.RemovePlayers(
GameInstanceId,
PlayersToRemove,
ExtRemovePlayersRequest,
RemovePlayersCallback
)
{
"requestId": 19,
"type": "gameInstanceRpc.RemovePlayersV1Request",
"payload": {
"game_instance_id": "1",
"players": {},
"ext":{}
}
}
After a player has been removed from the party, the Game Instance Plugin onRemovePlayers
is called. This method is used to prepare any custom data (ExtRemovedFromGame
) to send to the removed players.
suspend fun onRemovePlayers(
gameInstance: GameInstance.GameInstance,
playersToRemove: List<PlayerToRemove>,
requestExt: ExtRemovePlayersRequest
): Map<PlayerId, ExtRemovedFromGame>
Removed players will receive the onRemovedFromGame
event with the ExtRemovedFromGame
payload.
Upon removal, the removed players will appear in the removedPlayers
list on the GameInstance.GameInstance
. If the same players are added back into the game instance via matchmaking, they will be removed from the removedPlayers
list and appear within the players
list as a part of the new party that they joined the game with.
RemovePlayers
also invokes the Party Plugin’s returnFromGameInstance
method and provides a list of the specific players being removed from the game. See Party Service Tasks: Return from a game instance for more information.
End a game instance #
End a game instance for all players
EndGame
must be invoked to end the game instance, even if all players have left the game instance.
The game server calls MatchApiEndGame
to end the game instance and perform end game processes.
Server->MatchApi()->EndGame(
GameInstanceId,
PlayerGameResults,
ExtEndGameRequest,
EndGameDelegate
)
Server.MatchApi.EndGame(
GameInstanceId,
PlayerGameResults,
ExtEndGameRequest,
EndGameCallback
)
{
"requestId": 20,
"type": "gameInstanceRpc.EndGameV1Request",
"payload": {
"game_instance_id": "1",
"player_game_results": {},
"ext":{}
}
}
After the game instance has ended, the Game Instance Plugin onEndGame
method is invoked to create a new ExtGameEnded
payload per player. This payload can store game results, metrics, grants, and other end game data.
suspend fun onEndGame(
gameInstance: GameInstance.GameInstance,
playerGameResults: List<PlayerGameResult>,
requestExt: ExtEndGameRequest
): Map<PlayerId, ExtGameEnded>
Players removed from the game instance before the game ends can be included in end game processes and receive end game data. This is useful if you have a game that issues additional rewards to players at the end of the game, whether or not they are still active.
Players will receive the onGameEnded
event with the ExtGameEnded
payload that relates to them. This notification indicates that the end of game information has been successfully processed, and the game instance has ended.
EndGame
also invokes the Party Plugin’s returnFromGameInstance
method and provides a list of players currently in the game instance. This list does not include players previously removed from the game instance. See Party Service Tasks: Return from a game instance for more information.
Handle game end failures #
Pragma Engine provides two features to account for situations where the end game request never arrives: Keep Alive Heartbeats and Absolute Timeouts. A game end payload can fail to arrive due to game server crashes, game code bugs, network issues, or malicious actors. These features help release players from a game instance and allow them to reenter the game loop to start a new game instance.
In these failure situations, the player receives an OnGameInstanceTerminated
event, including a reason for shutdown.
When the game is forced to shut down, no end game data is processed.
Keep alive heartbeats #
The Keep Alive Heartbeats feature requires game servers to send occasional heartbeats after starting a game instance. This allows Pragma Engine to confirm that the game instance and game server are still operational.
When enabled, Pragma Engine expects a MatchKeepAliveV1
request based on the configured amount of time (keepAliveIntervalMillis
). If the engine doesn’t receive the request after a consecutive set of the configured amount of missed values (keepAliveMissesLimit
), it ends the game instance and returns players to their party, calling the Party Plugin returnFromGameInstance
method.
Game servers using the Pragma Engine-provided Unreal and Unity SDKs automatically send heartbeats to Pragma Engine on a successful response of the ConnectPlayers
method when this feature is enabled. It does this by starting a background process that makes the necessary MatchKeepAliveV1
requests every keepAliveIntervalMillis
while the match is progress.
The configuration for this feature can be found in GameInstanceServiceConfig
. This feature is enabled by default, with a 30000
milliseconds (30 seconds) value for keepAliveIntervalMillis
in production environments, and a keepAliveMissesLimit
value of 3
.
A separate keepAliveIntervalMillis
configuration for development in dev-defaults.yml
is set to 5000
milliseconds (5 seconds). To modify these values, edit the local-dev.yml
file.
To disable this feature, set the GameInstanceServiceConfig.enableKeepAlive
configuration property to false
.
As a best practice, we recommend against turning off the Keep Alive Heartbeats feature, as it’s critical for game flow health.
Absolute timeouts #
The Absolute Timeouts feature makes Pragma Engine end a game instance after a specified period of time elapses.
To enable this feature, set the GameInstanceServiceConfig.enableAbsoluteTimeout
configuration property to true
and provide a value for GameInstanceServiceConfig.absoluteTimeoutMillis
.
Once enabled, Pragma Engine starts a background task that runs after a configured amount of time (absoluteTimeoutMillis
) passes. If a game instance is still in progress when the background task runs, the engine ends the game instance and returns players to their party, calling the Party Plugin returnFromGameInstance
method.
This process releases the game instance from the Game Instance Service. The game server itself may still need to end or cleanup the game, and/or shutdown.