Skip to content

Replication basics

The Replicates checkbox does not make a Blueprint "multiplayer." It enrolls an Actor in Unreal's server-to-client synchronization system.

The one-minute version

  • Replication is how the authoritative server sends actor state to clients. It is not shared memory, and it is not automatic client-to-server sync.
  • An Actor must have Replicates enabled before normal actor replication can happen.
  • Individual variables still need to be marked replicated if you want their values sent. Replicates on the actor does not replicate every variable.
  • Replicate Movement is a separate actor setting for movement data. It is not the same as replicating your health, ammo, door-open state, or score.
  • Replicated variable changes should be made on the server. A client changing its local copy usually only changes that client until the server overwrites it.
  • RepNotify is the usual "a replicated value arrived/changed; update presentation" hook.
  • Runtime gameplay actors that should exist for everyone should normally be spawned by the server. A client-spawned actor is just local unless the server also creates the authoritative actor.
  • Remote procedure calls (RPCs) are for calls across the network, but they have ownership and reliability rules. They are not a replacement for replicated state.

What "Replicates" subscribes you to

Turning on Replicates for an Actor says:

This actor is allowed to be considered by the server's replication system.

It does not say:

Every variable replicates.
Every function call replicates.
Clients can change the server's copy directly.
Widgets replicate.
The actor is relevant to every client forever.
Movement replicates perfectly with no other settings.

At beginner altitude, actor replication looks like this:

pseudocode of the engine relationship - not engine source

Server tick:
    for each connected client:
        find replicated actors relevant to that client
        for each actor that is due for update:
            send changed replicated properties
            send queued network events/RPC data

Client receives update:
    create actor copy if needed
    apply received property values
    call RepNotify hooks for properties that need them
    update replicated movement if enabled

The server chooses what to send, when, and to whom. Clients receive and display their local copies.

The beginner checklist

For a runtime actor that everyone should see:

Actor class defaults:
-> Replicates = true
-> Replicate Movement = true if location/rotation/velocity should be sent

Gameplay:
-> server spawns actor
-> server changes replicated variables
-> clients receive actor/property updates

For a replicated variable:

Variable:
-> Replication = Replicated or RepNotify

Gameplay:
-> server sets variable
-> clients receive new value
-> RepNotify updates visuals/UI/audio if needed

For a client input that changes gameplay:

Owning client presses button
-> call Run on Server event on an actor this client owns
-> server validates request
-> server changes authoritative actor/variable
-> replicated state reaches clients

If any one of those arrows is missing, the feature may work only for the host, only locally, or only in single-player.

Server to clients, not clients to server

The direction is the first trap:

Server sets Replicated Health = 75
-> clients receive Health = 75

Client sets local Replicated Health = 75
-> server does not automatically receive it
-> other clients do not automatically receive it
-> server may later overwrite that client with the real value

Clients ask. The server decides. Then the server replicates results.

That is why damage, pickups, score, inventory, door state, and runtime actor spawning should usually be server-authoritative. The client can play cosmetic feedback immediately, but the server-owned result is the result other machines should trust.

Replicated variables

Actor replication opens the door. Replicated variables choose what data walks through it.

Use Replicated when clients just need the value:

Server:
    DoorIsOpen = true

Clients:
    replicated DoorIsOpen eventually becomes true

Use RepNotify when receiving the value should run follow-up presentation:

Server:
    Health = 60

Clients receive Health:
    OnRep_Health
    -> update health bar
    -> play low-health effect if this is the local player

RepNotify is not a magic "all machines run this game action" button. Treat it as a response to replicated state arriving. If the server also needs the same visual or bookkeeping function, call a shared helper on the server after setting the value and from the RepNotify path on clients.

What to replicate

Replicate compact state, not every intermediate event:

Better replicated state Usually worse first idea
Health = 60 Replicate every UI tick that draws the health bar.
bDoorOpen = true Multicast every frame of door animation state by hand.
TeamScore = 3 Store score only in a widget.
bEngineOn = true Try to replicate an audio component reference for a loop.

Clients can derive local presentation from replicated state. That keeps network traffic and mental load smaller.

Replicate Movement

Movement has its own actor setting because movement is common and special.

Setting Sends
Replicates The actor can participate in actor replication.
Replicate Movement The actor's replicated movement data can be sent to clients.
Replicated variable That one marked variable's value can be sent.

If you spawn a replicated pickup but leave Replicate Movement off, clients may learn the pickup exists but not receive ongoing movement updates the way you expect.

For Characters, movement has extra prediction and correction through Character Movement. Do not generalize from a default Character to every actor. A physics-simulating crate, a projectile, and a Character are different movement problems.

Server-spawned actors

For a gameplay actor that should exist for everyone, the server should normally spawn it.

Good beginner shape:

Client input Fire
-> Run on Server event
-> server validates ammo/cooldown
-> server Spawn Actor from Class
   Projectile Replicates = true
   Replicate Movement = as needed
-> clients receive replicated projectile

Client-only spawning is still useful for cosmetics:

Client input Fire
-> immediately spawn local muzzle flash / camera shake / UI sound
-> ask server to fire
-> server spawns authoritative projectile if valid

The local muzzle flash does not need to be trusted gameplay. The projectile does.

RPCs: calls across the network

Remote procedure calls are functions/events configured to execute on another machine. In Blueprint, these are usually Custom Events with a replication mode.

RPC type Beginner use Important rule
Run on Server Owning client asks the server to do gameplay work. Client must call it on a replicated actor it owns.
Run on Owning Client Server tells one owning client to do local presentation or UI work. The actor's owning connection decides which client.
Multicast Server tells relevant clients about a transient event. A multicast called by a client only runs locally; server should call gameplay multicasts.

RPCs do not have return values across the network. Design them as messages:

Client -> Server: "I pressed interact on this target."
Server validates.
Server changes replicated state.
Clients observe replicated state or receive a cosmetic event.

Use Reliable sparingly. Reliable means "do not drop this unless the connection breaks," not "make bad networking free." Input-spam reliable RPCs can clog the connection.

Relevancy, frequency, and dormancy

Even replicated actors are not sent to every client every frame.

Unreal considers things such as:

  • whether the actor is relevant to that client;
  • whether it is owner-only;
  • distance/cull settings;
  • update frequency and priority;
  • dormancy;
  • whether values actually changed;
  • whether the connection is saturated.

That is why "Replicates is true" does not guarantee "every client gets every update immediately." For a beginner project, do not tune these first. Just know they exist when an actor is replicated but not appearing where you expected.

Components, UObjects, and widgets

Actor replication is the main beginner path.

Thing Beginner replication note
Actor Component The owning actor must replicate, and the component must be configured to replicate if the component has replicated state/RPCs.
Plain UObject Advanced. It needs explicit networking support and replicated-subobject setup. Start with replicated actors/components.
Widget / HUD Local UI. It does not replicate. Read replicated state and update local UI.
GameInstance Local per process. It does not replicate.
GameMode Server-only; use GameState for public replicated game state.

The common UI shape:

Server changes PlayerState.Score
-> Score replicates to clients
-> local widget reads PlayerState or receives local update event
-> widget text changes locally

Do not try to replicate the widget.

Patterns that work

Door everyone sees

BP_Door:
    Replicates = true
    bOpen = RepNotify

Client interacts
-> Run on Server: ServerTryOpenDoor
-> server validates distance/key/lock
-> server sets bOpen = true
-> OnRep_Open on clients plays door timeline to open pose
-> server also calls the same ApplyOpenState helper for its own copy

Score everyone sees

PlayerState:
    Score = RepNotify

Server validates pickup
-> server increments PlayerState.Score
-> clients receive Score
-> local scoreboard widgets refresh from PlayerState

Sound from replicated state

Server sets bEngineOn = true on replicated vehicle
-> clients receive bEngineOn
-> OnRep_EngineOn
   true: Spawn Sound Attached locally and store AudioComponent
   false: Fade Out stored AudioComponent

The sound itself is local presentation. The engine-on state is replicated.

Common traps

  1. "Replicates" but no replicated variables. The actor exists on clients, but your health/ammo/door variable never gets sent.
  2. Client changes replicated variable. It changes locally, then the server overwrites it or nobody else sees it.
  3. Client spawns gameplay actor. The client sees it; the server and other clients do not trust or know it.
  4. RPC on an unowned actor. A client cannot call a Server RPC from just any replicated actor.
  5. Using Multicast instead of state. Late-joining clients or relevant-later clients miss the one-time event. Replicate durable state when the result matters.
  6. Trying to replicate widgets. UI is local; replicate the data it shows.
  7. Forgetting Replicate Movement. The actor exists, but movement does not update as expected.
  8. Testing only as host. The listen-server host sees both server truth and local player presentation.
  9. Reliable RPC spam. Reliable input events every tick can overload the connection.
  10. Replicating references to non-replicated things. Clients can only resolve network object references that are valid for networking.

Debugging a replication bug

Ask these in order:

  1. Which machine changed the value? If it was a client, did a Server RPC or authoritative server path accept it?
  2. Does the actor replicate? Check the actor class defaults and runtime spawn path.
  3. Was it spawned by the server? Runtime gameplay actors should usually be.
  4. Is the variable marked Replicated or RepNotify?
  5. Is the actor relevant to the client? Owner-only, distance, dormancy, or spawn timing may matter.
  6. Are you reading the right object? GameMode, PlayerController, Pawn, PlayerState, and widget all have different machine/lifetime rules.
  7. Did you test a remote client, not only the listen-server host?

Print the net mode, local role/authority, owning player, and actor name from the graph you think is running. Most replication bugs are "the code ran on the wrong machine" before they are "the network is broken."

Going deeper