Chapter 04

The Gameplay Framework

The core classes and their authority split, GameState in depth, actors versus components, and why composition beats deep inheritance.

In this chapter

  1. The Core Classes
  2. Actors and Components
  3. Actor Composition
  4. GameState in Depth
1

The Core Classes

The framework classes and their authority split — who owns what across the network:

ClassRoleNetwork presence
GameModeRules of the match; spawns players; win and lose conditionsServer only, never replicated
GameStateMatch-wide state — scores, timers, the player listReplicated to all clients
PlayerStatePer-player state — name, score; survives pawn deathReplicated to all clients
PlayerControllerBridges a human to their pawn; owns input, camera and UIServer + owning client
PawnThe controllable entity — character, vehicle, floating cameraReplicated
CharacterPawn + capsule + skeletal mesh + movement componentReplicated
Mental model. GameMode is the rules, GameState is the shared scoreboard, PlayerController is the brain, and Pawn or Character is the body.

Controller ↔ Pawn is the classic decoupling of input and decision from entity. A Controller possesses a Pawn; the Pawn doesn't know or care who controls it. That's what lets the same pawn be driven by a player or an AI without changing the pawn.

ACharacter earns its own class because the CharacterMovementComponent gives you networked bipedal locomotion out of the box — which is a significant amount of netcode you'd otherwise write yourself.


2

Actors and Components

The two component bases

ClassHas a transform?Use it for
UActorComponentNo spatial data at allPure behavior — health, inventory, cooldown tracking
USceneComponentYes, adds a transformAnything that needs a position in space

An Actor's own transform is delegated to its RootComponent. The actor doesn't store a position itself — it asks its root.

Build something as a component when it's a reusable capability many different actors might need: health, inventory, targeting, interaction. Rather than a Health base class that forces everything into one hierarchy, you add a HealthComponent to any actor that can take damage.


3

Actor Composition

Actor composition means building an actor's behavior by assembling components rather than inheriting from a deep chain of classes.

Deep inheritance
  • Gets rigid fast
  • Shared behavior that doesn't fit the tree gets duplicated
  • Base classes swell into god classes
  • One change ripples everywhere
Composition
  • Mix and match capabilities
  • Reuse across unrelated actors
  • Designers add or remove behavior by adding or removing a component

It's the classic "favor composition over inheritance" principle. Some inheritance is still fine — a Character is a Pawn — but distinct capabilities like health, inventory and abilities belong in components.

Component injection is also the mechanism Game Features use to add behavior to actors they don't own, without either side holding a reference. See Chapter 10.

4

GameState in Depth

The table frames it, but GameState deserves the fuller picture, since a lot of architecture hangs off it. It's the replicated shared-truth holder — the one place every client is guaranteed to agree on the state of the match. Since GameMode is server-only, GameState is its client-visible counterpart: anything all clients need to read goes here.

The two base classes

ClassPairs withAdds
AGameStateBaseAGameModeBaseMinimal base — PlayerArray, GameModeClass / SpawnedGameMode refs, replicated world time
AGameStateAGameModeMatch-state machine — MatchState, GetMatchState(), the WaitingToStart → InProgress → WaitingPostMatch flow

Match the pair: GameModeBase with GameStateBase, or GameMode with GameState. On AGameModeBase you don't get the match-state machine, and the base is enough.

Creating a child

The GameState class is set by the GameMode, not on itself. Make the subclass, then point the GameMode at it:

AMyGameMode::AMyGameMode()
{
    GameStateClass = AMyGameState::StaticClass();
}

In Blueprints: set the Game State Class dropdown in the GameMode's Class Defaults, or project-wide in Project Settings → Maps & Modes, or per-level in World Settings.

Accessing it

Use GetWorld()->GetGameState<AMyGameState>().

On clients the GameState can be null for the first frame or two after connecting, until replication delivers it. Guard for null, and drive UI off OnRep_* or HandleMatchHasStarted rather than assuming it exists at BeginPlay.

Only one is ever alive

One GameState per world, spawned by the GameMode, with one replicated copy per client. Each UWorld gets its own — so multi-client PIE gives each window its own — and seamless travel briefly has a transition map's GameState before the destination's takes over.

Within one active world at one time it's a singleton by design, which is exactly why it's a safe home for shared state. Chapter 5 covers what should and shouldn't live there.

Interview drill

Answer each out loud before re-reading the chapter.

  1. Walk me through GameMode, GameState, PlayerController, Pawn, and Character.
  2. What is the difference between an Actor and a Component? When do you build something as a component?
  3. What is Actor Composition and why is it preferred over deep inheritance?
← Chapter 3 ↑ Index Chapter 5 →