Replicating Actor Components¶
A replicated HealthComponent or InventoryComponent is still a subobject of a replicated actor. The actor is the network carrier, the component is the reusable state owner, and the server still changes the real gameplay values.
At a glance
Use this for: replicated health, inventory, team, status, interaction, or weapon components - Main requirement: owning actor replicates and the component is set to replicate - Authority rule: server changes the component's gameplay state - Official docs: Replicating Actor Components, Components, and Remote Procedure Calls
The one-minute version¶
- Actor Components do not become networked just because they are reusable.
- The owning actor must replicate before component replication can reach clients.
- The component itself must also be configured to replicate if it has replicated variables, RepNotify state, component RPCs, or replicated subobjects.
- Replicated component variables still follow the normal direction: server to clients. Client-side changes are local guesses unless the server accepts and sets the real value.
- Component RPCs use the component's owning actor and owning connection. A client cannot bypass ownership just because the RPC lives on a component.
- Dynamic replicated components should be created by the server and marked for replication. Client-created dynamic components are local unless the server creates the networked version.
- Relevancy, owner-only behavior, dormancy, and update frequency still come from the actor replication path around the component.
The replication stack¶
For a component value to replicate, the stack has to be valid all the way up:
Replicated actor
-> replicated actor component
-> replicated component variable or component RPC
-> server changes/calls it through an allowed path
-> relevant clients receive it
If any layer is missing, the component can still work locally while multiplayer silently disagrees.
For a Blueprint component placed in an actor's Components panel:
Owning actor class defaults:
Replicates = true
Component details:
Component Replication / Replicates = true
Component variable:
Replication = Replicated or RepNotify
Gameplay:
server changes the variable
That is separate from component ownership in the editor. The component may be owned by the actor for lifetime, but it still needs networking setup for its state to travel.
Static components¶
A static component is part of the actor from the start: added in the Blueprint Components panel or as a default subobject in C++.
Beginner examples:
HealthComponenton a player, enemy, or destructible barrel;InventoryComponenton a player character or PlayerState;TeamComponenton pawns and objectives;InteractableComponenton doors, pickups, and consoles.
Static component replication is the cleanest first path because every copy of the actor already knows the component should exist.
BP_Enemy class:
Replicates = true
HealthComponent:
Replicates = true
CurrentHealth = RepNotify
bDead = RepNotify
Server damage path:
HealthComponent.ApplyDamageToHealth()
-> CurrentHealth changes
-> clients receive CurrentHealth
-> OnRep_CurrentHealth updates local bars/materials
Do not mark every component replicated by reflex. Replicate the component when it owns networked state or networked messages. A purely local audio, camera, or debug helper component usually does not need this.
Dynamic components¶
A dynamic component is added at runtime. For replication, the server should be the machine that creates the authoritative component.
Server:
Add Component by Class: BP_StatusEffectComponent
Set Is Replicated = true if needed
initialize replicated effect state
Clients:
receive the replicated component/subobject path
receive replicated variables when the actor is relevant
Client-created dynamic components are useful for cosmetics:
Owning client:
add local-only reticle helper component
play local prediction effect
They are not the networked gameplay component. If the server never creates the component, other machines have no authoritative component to receive.
Component variables and RepNotify¶
Replicated component variables work like actor variables:
Server HealthComponent:
CurrentHealth = 60
Relevant client copies:
CurrentHealth becomes 60
OnRep_CurrentHealth runs on that component copy
Good component RepNotify jobs:
- update a local health bar, nameplate, material parameter, or audio cue;
- broadcast a local dispatcher such as
OnHealthChanged; - rebuild local UI after late relevance or respawn rebinding;
- apply an idempotent presentation helper.
Poor component RepNotify jobs:
- deciding whether damage was valid;
- granting inventory items;
- spawning authoritative actors;
- calling a Server RPC because a value arrived;
- assuming a different component's OnRep already ran.
If several fields must be interpreted together, replicate one struct or state enum from the component rather than racing several separate OnRep functions.
Component RPCs¶
Actor Components can define RPCs, but the ownership rule does not disappear. The component's owner chain must resolve to a replicated actor and the correct owning connection.
Client presses Use Item
-> owned PlayerController or pawn calls ServerUseItem
-> server asks InventoryComponent to use the item
-> InventoryComponent changes replicated entries
-> clients/owning client update UI from replicated state
This is usually clearer than calling a Server RPC directly on some component attached to a world object the client does not own.
For shared world objects:
Bad shape:
Client calls Door.InteractableComponent.ServerOpen
Door is not owned by that client
Better shape:
Client calls ServerTryInteract on owned pawn/controller
server validates target
server calls Door.InteractableComponent.Open on the server
Door replicated state changes
Reliable vs unreliable also matters for component RPCs. A component RPC is not cheaper just because the graph is tidier. Frequent messages may be better as compressed replicated state, local prediction, or rate-limited unreliable events.
Relevancy still belongs to the actor¶
The component is replicated as part of its owning actor's network path. That means:
- if the actor is not relevant to a connection, the component's public state does not update there;
- if the actor is owner-only, the component state follows that owner-only audience;
- if the actor is dormant, changed component state may need the actor to wake before clients hear about it;
- if the actor is destroyed or replaced, component references on UI/listeners become stale.
This matters for components that beginners expect to be global:
InventoryComponent on PlayerState:
good for public or owner-linked player state, depending on what you expose
InventoryComponent on current pawn:
good for body/equipment state, but respawn can replace it
InventoryComponent on GameInstance:
local only; does not replicate
Choose the actor owner before blaming the component.
Health and inventory examples¶
HealthComponent¶
Owning actor:
Replicates = true
HealthComponent:
Replicates = true
CurrentHealth = RepNotify
bDead = RepNotify
OnHealthChanged dispatcher is local
Server:
Event AnyDamage
-> HealthComponent.ApplyDamageToHealth
-> CurrentHealth changes
Clients:
OnRep_CurrentHealth
-> broadcast local OnHealthChanged
-> widgets/nameplates update
The dispatcher is local. The replicated health value is the network truth.
InventoryComponent¶
Owned player path:
Client clicks Use
-> ServerUseItem(ItemSlot) on owned pawn/controller
Server:
InventoryComponent validates slot/count/cooldown
updates replicated inventory summary or owner-only inventory state
Owning client:
OnRep_InventoryState
-> local inventory UI refreshes
Do not replicate widget slots, drag/drop payload widgets, or pickup actor references as the inventory truth. Replicate item IDs, counts, equipment slot, and any per-instance state the client is allowed to know.
When it fails, and what failure looks like¶
| Symptom | Likely cause |
|---|---|
| Component value changes only for the host | Client changed the component locally, or the server never changed the replicated value. |
| Actor appears but component value stays default | Actor replicates, but the component or its variable is not configured for replication. |
| Server RPC on component never runs | The client called through a component whose owning actor is not owned by that client. |
| Dynamic component exists on server but not clients | It was not created/registered/marked for replication on the server path. |
| Component OnRep fires but UI is still wrong | UI is bound to an old component after respawn or actor replacement. |
| Other players see private inventory data | The state was replicated publicly on a relevant actor instead of owner-only/local data. |
| Component update seems delayed forever | Owning actor is not relevant, has low update frequency, or is dormant. |
| Multicast from component misses some clients | The owning actor is not relevant to those clients when the multicast is sent. |
Print the component name, owner actor, owner connection if you can expose it,
net mode, authority, component Replicates setting, and the variable before
and after the server changes it.
What replicated components do not do¶
- They do not make a non-replicated actor replicate.
- They do not let clients change server state directly.
- They do not make local dispatchers cross the network.
- They do not replicate widgets, sounds, Niagara components, or dynamic material instances as the main truth.
- They do not bypass actor relevancy, dormancy, ownership, or RPC eligibility.
- They do not make a runtime component global if only a client created it.
- They do not make a component reference valid after the owning actor is destroyed or respawned.
Lookalikes - which one do I want?¶
| Tool | Use when | Not for |
|---|---|---|
| Replicated actor variable | The state belongs naturally on one actor and reuse is not needed. | Sharing the same health/inventory logic across many actor types. |
| Replicated Actor Component | Reusable actor-owned state or behavior needs replication. | Independent world objects with their own transform/lifetime. |
| Component dispatcher | Local listeners need a local event after state changes. | Sending events to other machines by itself. |
| Component RPC | A replicated component owns a message, and the owning actor connection allows it. | Bypassing ownership on shared world actors. |
| Child Actor Component | You need an actor instance as a component-like child. | Plain reusable state with no separate actor identity. |
| PlayerState / GameState variable | Public player/match state needs a framework owner. | Body-specific component state that dies with a pawn. |
The quick path is to put health or inventory back on every actor because the component did not replicate at first. The concrete cost is duplicated logic and five different multiplayer bugs. Keep the component, but make the actor, component, variable, and server-write path explicit.
Going deeper¶
- Actor Components as reusable gameplay
- the reusable component pattern before networking.
- HealthComponent and damage response pattern
- server-owned health changes and local UI broadcasts.
- Small Inventory Architecture - item IDs, entries, UI, equipped actors, SaveGame, and multiplayer ownership.
- Replication basics - actor replication, variables, RPCs, relevancy, and widgets.
- Blueprint Custom Events as RPCs - component RPCs still follow ownership.
- RepNotify variables and local presentation - state arrival driving local presentation.
- Actor relevancy, owner-only, and dormancy basics - why a replicated component follows its actor audience.
- Official docs: Replicating Actor Components, Components, UActorComponent, Replicate Actor Properties, Remote Procedure Calls, and Actor Owner and Owning Connection.
- Engine source (requires engine access - we do not reproduce it here):
UActorComponent::SetIsReplicated,UActorComponent::SetIsReplicatedByDefault,UActorComponent::GetOwner, component RPC routing, and component replication helpers live inEngine/Source/Runtime/Engine/Private/Components/ActorComponent.cppand declarations inEngine/Source/Runtime/Engine/Classes/Components/ActorComponent.h; actor ownership and subobject replication hooks are underEngine/Source/Runtime/Engine/Private/Actor.cppandEngine/Source/Runtime/Engine/Classes/GameFramework/Actor.h.