End Game Instances #
This topic provides instructions on ending or terminating game instances using the player client or backend methods and custom services. You can end a game instance in the following ways:
- by calling the Match API’s
EndGame()method from the game server - by calling
GameInstance.end()directly from any Game Instance plugin implementation
Certain errors trigger the GameInstance.terminate() method, which destroys the game instance.
End a game instance through the MatchApi #
To facilitate ending a game instance from the game server side, the game server can call MatchApi.EndGame():
Server->MatchApi()->EndGame(
const FString& GameInstanceId,
const TArray<FPragma_GameInstance_PlayerGameResult>& PlayerGameResults,
const FPragma_GameInstance_ExtEndGameRequest& Ext,
const FOnCompleteDelegate& OnComplete
)
Server.MatchApi.EndGame(
PragmaId gameInstanceId,
IEnumerable<PlayerGameResult> playerGameResults,
ExtEndGameRequest ext,
CompleteDelegate onComplete
)
The MatchApi.EndGame() method invokes GameInstancePlugin.handleBackendEndRequest(), where you can call GameInstance.end() to officially end the game instance.
End a game instance via SQS #
Instead of sending EndGame requests directly to the Pragma backend via RPC, game servers can route these requests through Amazon SQS. This allows game servers to continue posting end-game data even when the platform is temporarily unavailable for maintenance.
Key characteristics of the SQS end game flow:
- Idempotent:
EndGameis idempotent based onGameInstanceId. Duplicate messages from SQS are handled as no-ops. - Graceful fallback: If SQS connection info is not available, the SDK falls back to the standard direct RPC flow.
- Restart resilient: With
processEndGameForUnknownInstanceenabled, the platform can processEndGamerequests for game instances that are no longer in memory after a restart.
For setup instructions, see Set up persistent end game via SQS. For architecture details including error handling, retries, and the Dead Letter Queue, see Persistent end game via SQS.
Handle game server end requests #
When the game server calls MatchApi.EndGame(), the GameInstancePlugin.handleBackendEndRequest() method is invoked. You can use this method to call GameInstance.end() or to
update party and player data see Update from a backend service.
For example:
suspend fun handleBackendEndRequest(
gameInstanceSnapshot: GameInstance.GameInstance,
playerGameResults: List<PlayerGameResult>,
requestExt: ExtEndGameRequest,
) {
gameInstanceSnapshot.end(playerGameResults.associate { it.playerId to ExtGameEnded.getDefaultInstance() })
}
End a game instance from a plugin #
To handle the successful completion of a game instance, call GameInstance.end() with the player IDs and ExtGameEnded data from a backend method.
GameInstance{
fun end(extMap: Map<PlayerId, ExtGameEnded>)
}
For example, to end a game instance as soon as all players have been removed, call end() from the Game Instance Plugin’s handleBackendRemovePlayersRequest() method:
suspend fun handleBackendRemovePlayersRequest(
gameInstanceSnapshot: GameInstance.GameInstance,
requestExt: ExtBackendRemovePlayersRequest,
playersToRemove: Map<PlayerId, ExtBackendRemovePlayer>,
) {
playersToRemove.forEach { (playerId, _) ->
gameInstanceSnapshot.removePlayer(
playerId, ExtRemovedFromGame.getDefaultInstance())
}
if (gameInstanceSnapshot.players.isEmpty()) {
gameInstanceSnapshot.end(mapOf())
}
}
When end of game information has been successfully processed, and the game instance has ended, players will receive the onGameEnded event with the ExtGameEnded payload that relates to them.
Set game instance expiration #
You can configure game instances to automatically expire after a certain duration (measured from the last time the game instance is accessed). Game instances will be removed after they have not been accessed for the full duration of the expiration. This includes actions such as reading or modifying game instance state or game player state, and player/partner client synchronization operations.
By default, the expiration feature is enabled with an expiration time of one day. If you change the configuration value, any existing game instances that have not been accessed during the expiration duration will be removed. You can disable expiration functionality or change the time limit in the GameInstanceServiceConfig block of your yaml file:
game:
serviceConfigs:
GameInstanceServiceConfig:
enableStaleGameInstanceExpiration: true
staleGameInstanceExpirationMinutes: 1440
When a game instance expires, the Game Instance plugin onGameInstanceExpired() method is called.
Handle game instance expirations #
Using the Game Instance plugin onGameInstanceExpired() method, you can define other actions that should occur when a game instance expires. By default, the method terminates the game instance with the EXPIRED reason.
suspend fun onGameInstanceExpired(
gameInstanceSnapshot: GameInstance.GameInstance,
) {
gameInstanceSnapshot.terminate(
GameInstanceTerminationReason.EXPIRED)
}
When a game is terminated, players will receive the OnGameInstanceTerminated event with the termination reason.
Related events and errors #
Related events:
Related errors:
- GameInstanceService_UnknownGameInstanceId