メインコンテンツまでスキップ

Matchmaking Error Handling – Best Practices

Last updated on February 27, 2025

Handling matchmaking connection errors is crucial to ensuring a smooth player experience. When a connection issue occurs, the game should provide clear feedback to the player and attempt to recover gracefully. Implementing proper error handling can prevent frustration and help players reconnect quickly without disrupting their gameplay. How to handle matchmaking connection issues:

  • Display a clear and informative message based on the error of each of step delegates (i.e start matchmaking, joining session, travelling to the DS, etc), so players understand why the matchmaking flow failed. You can use Byte Wars tutorial module for the he Playing in DS flow reference (Unreal Engine or Unity).
  • Disable matchmaking feature if the lobby connection is lost.
  • Show a manual retry option in a popup or message in each of steps of the matchmaking.

Matchmaking Error Handling

The Unreal Engine OSS has a built-in polling system to check the match ticket status. Once a match ticket is successfully created in the matchmaking service, the system will poll for updates every 15 seconds. The polling will automatically stop when the match ticket is either found or not found (response with error code 520303) in the matchmaking service. However, if a connection disruption occurs, but the player stays logged in, the polling will continue running in the background until it completes.

...
auto ABSubsystem = IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM);
auto SessionInterface = ABSubsystem->GetSessionInterface();
SessionInterface->OnMatchmakingCompleteDelegates.AddWeakLambda(this, [this](FName SessionName, bool bWasSuccessful)
{
if (bWasSuccessful)
{
// Do something when the matchmaking request is successful.
}
else
{
// Implement a solution to handle failed request.
}
});
...

Currently, if a matchmaking fails, the AGS OSS does not provide details about whether the failure was caused by a websocket timeout or another issue.

Joining Session Error Handling

...
auto ABSubsystem = IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM);
auto SessionInterface = ABSubsystem->GetSessionInterface();
SessionInterface->OnJoinSessionCompleteDelegates.AddWeakLambda(this, [this](Name SessionName, EOnJoinSessionCompleteResult::Type Result)
{
if(Result == EOnJoinSessionCompleteResult::Success)
{
// Do something when the joining game session is successful.
}
else
{
// Implement a solution to handle failed joining game session request.
}
});
...

Currently, if a matchmaking fails, the AGS OSS does not provide details about whether the failure was caused by a websocket timeout or another issue.

Sessions Timeouts Handling

When the player is disconnected from the session service for any reason, the session service will identify the player as inactive member of the session. The inactive member has a Inactive Timeout limit which could be configured here. You can set the value of Inactive Timeout greater than the websocket connection timeout to ensure when the websocket is succesfully reconnected, the player is still in the game session.

Recovery Game Session

If a player gets disconnected from the WebSocket connection but hasn’t been removed from the game session by session service, the game client can restore their session. This means that once the WebSocket connection is successfully re-established, the player can seamlessly return to their session.

  1. Restore the game session.
...
auto ABSubsystem = IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM);
auto SessionInterface = ABSubsystem->GetSessionInterface();
SessionInterface->RestoreActiveSessions("<UserId>",
FOnRestoreActiveSessionsComplete::CreateWeakLambda(this, [this](const FUniqueNetId& LocalUserId, const FOnlineError& ResultState)
{
if (ResultState.bSucceeded)
{
// Do something when the restoring game session is successful.
}
else
{
// Implement a solution to handle failed request.
}
})
);
...
  1. Rejoin the DS after succesfully restoring the game session.
...
auto ABSubsystem = IOnlineSubsystem::Get(ACCELBYTE_SUBSYSTEM);
auto SessionInterface = ABSubsystem->GetSessionInterface();
auto ABSessionInterface = StaticCastSharedPtr<FOnlineSessionV2AccelByte>(SessionInterface);
FString ServerAddress = "";
ABSessionInterface->GetResolvedConnectString(Name_GameSession, ServerAddress);
APlayerController::ClientTravel(ServerAddress, TRAVEL_Absolute);
...