Skip to content

Multiplayer roles

In multiplayer, "where should this variable live?" also means "which machine has this object?"

The one-minute version

  • Unreal multiplayer is server-authoritative. The server owns the true gameplay state; clients send requests and render their local view of that state.
  • GameMode exists on the server only. Remote clients do not have the real GameMode instance.
  • GameState exists on the server and clients. Put game-wide state there when clients need to know it.
  • PlayerState exists for every player on every machine. It is the normal place for replicated per-player score, name, team, ready state, and similar public player data.
  • PlayerController exists on the server and on its owning client. Other clients do not get your PlayerController. Use it for local input, local UI, and owner-only client communication.
  • Pawn / Character exists on the server and on clients where it is relevant. The owning client controls its pawn; other clients see simulated copies.
  • GameInstance, widgets, and most UI are local only. They are not shared by replication just because they exist in a multiplayer session.

The mental model

In single-player, all the framework objects are in one process, so it is easy to misread "global" as "everyone can see it." In multiplayer, every machine has its own world copy.

flowchart LR
    Server[Server world<br/>authoritative gameplay] --> C1[Client 1 world<br/>local view + input]
    Server --> C2[Client 2 world<br/>local view + input]

The server decides authoritative gameplay results:

  • who spawned;
  • whether damage counted;
  • where replicated actors are;
  • which replicated variables changed;
  • which clients should receive updates.

Clients own presentation and input:

  • reading local input;
  • showing widgets;
  • camera/audio/cosmetic feedback;
  • asking the server to perform gameplay actions.

A listen server is both: it is the server and also has a local player. That is useful for testing, but it hides many "works for host, fails for remote client" bugs. Test with a remote client mindset early.

Which machines have which object?

Object Server has it? Owning client has it? Other clients have it? Beginner job
GameMode Yes No real instance No real instance Rules, login/start/restart flow, authoritative match decisions.
GameState Yes Yes Yes Replicated game-wide state clients should know.
PlayerController Yes, for each player Yes, for that player No Input ownership, local UI/camera, owner-only client messages.
PlayerState Yes, for each player Yes, all players Yes, all players Replicated per-player public state.
Pawn / Character Yes Yes, if relevant and possessed Yes, if relevant Body in the world: movement, collision, damage target, abilities.
HUD / widgets Usually no on dedicated server Yes, local only Each client has its own UI Screen presentation and local menu state.
GameInstance One per process One per process One per process Local runtime data and managers; not network-shared.
AIController Usually yes Usually no Usually no Server-side non-player character control.

This table is the answer to many confusing bugs:

"I set a variable in GameMode and the client sees None."
-> Remote clients do not have the server's GameMode instance.

"I stored score on the Character and it resets on death."
-> The pawn body can be destroyed and replaced. PlayerState is usually the
   multiplayer home for public per-player score.

"I tried to get another player's PlayerController."
-> Other clients usually do not have it. Use PlayerState for public player
   data, or replicated pawn/state for world behavior.

GameMode vs GameState

Use the single-player GameMode & friends page for the basic framework split. Multiplayer adds the server/client audience rule:

Need Put it in
Decide whether a player may join GameMode
Choose spawn/restart rules GameMode
Track match timer that clients display GameState
Track team score visible to everyone GameState
Store "mission complete" for all clients in this match GameState

GameMode is the authority that decides rules. GameState is the replicated public state clients can observe.

The common trap is putting a timer or score in GameMode because it "belongs to the game." That works on the server and listen-server host, then remote clients cannot read it. If clients need to display it, replicate it through GameState or another replicated actor.

PlayerController vs PlayerState

PlayerController represents one human player's control path. It is private to the server and that one owning client.

Good PlayerController jobs:

  • local input routing;
  • pause/menu ownership;
  • local HUD/widget creation;
  • camera/view target changes for that player;
  • server remote procedure calls (RPCs) from the owning player;
  • owner-only client messages.

Bad PlayerController jobs:

  • scoreboard data everyone needs to see;
  • another player's public team/color/name;
  • world pickups other players should observe;
  • match state that exists even after a player respawns.

PlayerState is the public per-player record. If every client needs to know a player's score, team, display name, ready state, or current loadout summary, start by considering PlayerState.

Pawn / Character

Pawn or Character is the body in the world. It is the thing that moves, collides, takes damage, plays animations, fires weapons, and can be possessed or replaced.

In multiplayer, a pawn has different meanings on different machines:

View What it means
Server authoritative pawn The server's true gameplay version.
Owning client's pawn The local player controls this copy and may have prediction.
Other clients' copies Simulated views of someone else's pawn.

That is why a client-only health change, launch, spawn, or damage result often snaps back or only appears locally. The server did not accept it as the real state.

Use Pawn/Character for body-specific state:

  • health on this current body;
  • movement state;
  • equipped weapon actor reference;
  • animation-driving values;
  • short-lived ability state tied to the body.

Use PlayerState instead when the data should survive pawn death/respawn and be visible as player identity/state.

Where should this variable go?

Data or behavior First place to consider Why
Match rules, max players, can-start check GameMode Server-only authority decides rules.
Public match timer GameState All clients need to see it.
Team score GameState Game-wide replicated state.
Player score/name/team PlayerState Per-player state visible to all clients.
Local pause menu widget PlayerController / widget Only the local player needs it.
Input action handling PlayerController or pawn, by design The owning client drives input.
Character health Character or health component Health belongs to the body taking damage.
Score that survives death PlayerState Pawn can be destroyed and respawned.
Selected graphics/audio settings GameInstance / save system Local player preference, not replicated gameplay.
Door open state everyone sees Replicated door actor or game state owner It is world state clients need to observe.

The rule is not "always put score in PlayerState" or "always put UI in PlayerController." The rule is: match the data's lifetime, audience, and authority.

Authority, ownership, and local control

Three questions show up constantly:

Question Meaning
Has Authority? Is this copy authoritative for this actor? For normal replicated gameplay actors, that usually means the server.
Is Locally Controlled? Is this pawn controlled by a controller local to this machine? Useful for local camera, UI, and input presentation.
Who owns this actor? Which player connection is associated with it for owner-only replication and RPC rules.

Do not use these as magic incantations. Use them to answer a concrete question:

Should only the owning player show this crosshair?
-> Is Locally Controlled on the pawn, or local PlayerController UI path.

Should only the server apply damage?
-> Has Authority or server-owned damage path.

Can this client call a Server RPC on this actor?
-> The actor must be replicated and owned by that client's connection.

For Unreal's many meanings of "owner," keep Ownership and lifetime nearby. Networking owner is not the same as component ownership, attachment, possession, or garbage-collection lifetime.

Common traps

  1. Reading GameMode on a remote client. It is server-only.
  2. Testing only as listen-server host. The host can see server-only state and local UI, so remote-client bugs stay hidden.
  3. Putting public player data in PlayerController. Other clients do not have your controller.
  4. Putting persistent player data on the pawn. Death/respawn can replace the body.
  5. Expecting GameInstance to replicate. Each process has its own local GameInstance.
  6. Changing gameplay state only on a client. The server can overwrite or ignore that local change.
  7. Using Multicast for everything. Multicast is not a substitute for choosing the right replicated owner/state.
  8. Confusing local UI with replicated gameplay. Widgets are local presentation; they should read replicated state, not be the source of authority.

A first multiplayer feature shape

For a simple replicated pickup score:

Player overlaps coin on client
-> client may show local prediction/cosmetic if desired
-> server authoritative overlap or Server RPC validates pickup
-> server destroys/marks coin collected
-> server increments player's PlayerState score
-> score replication reaches clients
-> each client's UI reads PlayerState and updates locally

The UI update is local. The score truth is replicated. The pickup decision is server-authoritative.

Going deeper