End a Game #
Goal: Allow a player client to tell the game server to shut down, and handle server shutdown processes.
In this section we will work with the following methods:
In the player controller:
- TellGameServerToEndGame(): Allows player client to tell the game server to end the game.
In the game mode base:
- EndGame(): Handles game end data and calls
ShutdownServer()
. - ShutdownServer(): Shuts down the game server.
Allow player to request game end #
We want to allow player clients to end the game from the game interface. To do so, we’ll create a BlueprintCallable function that tells the server to end the game. You can connect this function to a button in the GameServerLevel to allow players to end the game instance when they click it.
In
MyPlayerController.h
, declare theTellGameServerToEndGame()
UFunction, which will execute on the server:public: UFUNCTION(BlueprintCallable, Server, Reliable, Category="Pragma") void TellGameServerToEndGame();
In
MyPlayerController.cpp
, defineTellGameServerToEndGame()
. When used the method will call ourMyGameModeBase
EndGame()
function, which we will define in the next step.void AMyPlayerController::TellGameServerToEndGame_Implementation() { UE_LOG(LogTemp, Display, TEXT("MyGameClient -- Telling game server to end the game...")); Cast<AMyGameModeBase>(GetWorld()->GetAuthGameMode())->EndGame(); }
Define EndGame #
In
MyGameModeBase.h
, declare theEndGame()
method:public: void EndGame();
In
MyGameModeBase.cpp
, defineEndGame()
such that it handles player game results, callsMatchApi.EndGame()
to end the game, and calls ourShutdownServer()
method as a result. We’ll defineShutdownServer()
in the next step.void AMyGameModeBase::EndGame() { if (!StoredGameStartData.IsSet()) { UE_LOG(LogTemp, Error, TEXT("MyGameServer -- No match data when trying to end game.")) ShutdownServer(); return; } TArray<FPragma_GameInstance_PlayerGameResult> PlayerGameResults; for (const auto& Player : StoredGameStartData->Players) { auto i = PlayerGameResults.Emplace(); PlayerGameResults[i].PlayerId = Player.PlayerId; // PlayerGameResults[i].Ext = TEXT("your player-specific data here"); } UE_LOG(LogTemp, Display, TEXT("MyGameServer -- Attempting to end game...")); Server->MatchApi().EndGame( StoredGameStartData->GameInstanceId, PlayerGameResults, FPragma_GameInstance_ExtEndGameRequest{}, UPragmaMatchApi::FOnCompleteDelegate::CreateLambda( [this](const TPragmaResult<>& Result) { if (Result.IsSuccessful()) { UE_LOG(LogTemp, Display, TEXT("MyGameServer -- End game succeeded.")); } else { UE_LOG(LogTemp, Error, TEXT("MyGameServer -- End game failed.")); } ShutdownServer(); }) ); }
Shut down the server #
In
MyGameModeBase.h
, declare aShutdownServer()
method:private: static void ShutdownServer();
In
MyGameModeBase.cpp
, define theShutdownServer()
method such that it uses the UnrealFGenericPlatformMisc
interface to exit the game server:void AMyGameModeBase::ShutdownServer() { FGenericPlatformMisc::RequestExit(false); }