Course contentsShow
← Unreal Engine Game Development
Lesson 121 of 8802. The Gameplay FrameworkFree lesson

Managing Player Session Persistence

You will handle player reconnection scenarios by correctly re-associating existing PlayerState data with new PlayerController instances upon login.

In this lesson, you will learn how to bridge the gap between a player’s unique identity and the temporary PlayerController instance created when they reconnect to a game session.

Understanding the Transient Nature of Controllers

In Unreal Engine, the PlayerController is an ephemeral object. If a player experiences a momentary network hiccup or leaves and returns to a session, the server destroys their original PlayerController and spawns a brand-new one upon login.

While the PlayerController disappears, the PlayerState is designed to survive these transitions. The PlayerState acts as the "persistent memory" for an individual user during a match. When a new PlayerController is created, our goal is to ensure the game recognizes that this is the same human player and re-links them to their existing PlayerState data, such as their score or inventory.

The Reconnection Workflow

When a player reconnects, Unreal Engine calls PostLogin within your GameMode. This is the perfect place to verify if the player has existing data.

Instead of treating every login as a fresh slate, we check if a PlayerState already exists for this player’s unique User ID (often tracked via UniqueNetId).

void AMyGameMode::PostLogin(APlayerController* NewPlayer)
{
    Super::PostLogin(NewPlayer);

    // Check if the player has an existing PlayerState or saved stats
    if (NewPlayer && NewPlayer->PlayerState)
    {
        // Re-associate the new Controller with the persistent PlayerState
        // The PlayerState replicates the player's history (score, health, etc.)
        APlayerState* ExistingState = NewPlayer->PlayerState;
        
        // Log that we have successfully re-linked the session
        UE_LOG(LogTemp, Log, TEXT("Reconnected player %s to existing state."), *ExistingState->GetPlayerName());
    }
}

By leveraging PlayerState, the server ensures that even though the "brain" (the PlayerController) was replaced, the "memory" (the PlayerState) remains intact. This prevents players from losing their progression simply because their network connection flickered. As long as you keep your critical gameplay data inside the PlayerState rather than the PlayerController, the transition will be seamless to the player.

Key Takeaway: Always store persistent player data in the PlayerState, as the PlayerController is destroyed and recreated during reconnection events, but the PlayerState serves as the durable link to the player's history.