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

Designing Modular Gameplay Framework Interactions

You will architect a clean communication flow between GameMode, PlayerState, and Controllers to maintain a scalable and bug-free project structure.

In this lesson, you will learn how to architect a clean communication flow between the GameMode, PlayerState, and PlayerController to ensure your project remains scalable and bug-free.

The Communication "Golden Rule"

When building gameplay systems, the most common pitfall for beginners is creating "spaghetti code"—where every class is tightly coupled to every other class, making it impossible to change one without breaking three others. To avoid this, follow the principle of Functional Segregation:

  • GameMode (The Referee): Only knows the rules. It should trigger events (e.g., "Round Started") but should never directly modify a specific player’s UI or inventory.
  • PlayerState (The Ledger): Holds the long-term data (Score, Player Name, Team ID). Think of this as the "Source of Truth" for an individual player.
  • PlayerController (The Messenger): Acts as the bridge between the human input and the game world. It listens to the GameMode and updates the PlayerState or instructs the Pawn.

Maintaining Flow

Imagine a "Score Update" event. Instead of the GameMode reaching into the UI to update a text block, it should simply notify the PlayerState that a point was scored. The PlayerState updates its variable, and the PlayerController (or UI) observes that change.

// Inside GameMode: Keep it high-level
void AMyGameMode::AddScore(APlayerController* VictimController) {
    if (auto* PS = Cast<AMyPlayerState>(VictimController->PlayerState)) {
        PS->IncrementScore(10); // GameMode triggers the logic
    }
}

By funneling interactions this way, you ensure that your GameMode doesn't need to know if a player is using a HUD, a VR headset, or a spectator camera. It only needs to know that the PlayerState exists.

Why this scales

When you need to add a new game mode—like "Capture the Flag"—you don't have to rewrite your player logic. Because your PlayerState and PlayerController aren't dependent on the specific rules of the GameMode, they remain "plug-and-play." You simply swap the GameMode class, and the rest of your framework continues to function independently.

Key Takeaway: The GameMode dictates the rules, the PlayerState holds the data, and the PlayerController acts as the intermediary; never let these classes talk directly to components that don't belong to them.