unreal-replication

Unreal 5.8 Replication

Design and debug authoritative network state

---
name: unreal-replication
description: Design, implement, optimize, test, and debug server-authoritative multiplayer replication in Unreal Engine 5.8. Use for authority, roles, ownership, owning connections, replicated actors/components/properties, RepNotify, RPCs, relevancy, priority, dormancy, conditions, Fast Arrays, replicated UObjects/subobjects, Generic Replication, Replication Graph, Iris, bandwidth, ordering, prediction boundaries, Network Insights, packet emulation, or multiplayer UI state.
---

# Unreal 5.8 Replication

## Ownership boundary

This skill owns general Actor/property/RPC authority, ownership, relevancy, dormancy, and state
transport. Prediction remains subsystem-owned: route Character saved moves/root motion to
[`unreal-character-movement`](../unreal-character-movement/SKILL.md), network physics/ragdolls to
[`unreal-chaos-physics`](../unreal-chaos-physics/SKILL.md), and ability prediction to
[`unreal-gas-abilities`](../unreal-gas-abilities/SKILL.md).

## Select the replication system

- Start with **Generic Replication**, UE 5.8's default, unless measured scale requires another
  system.
- Evaluate **Replication Graph** for many replicated actors and connections. It is Beta and does
  not currently support split screen on console builds.
- Evaluate **Iris** for its filtering/prioritization/scalability architecture only with an
  explicit migration and compatibility plan. UE 5.8 still marks Iris Experimental and Generic
  Replication remains the default.
- Do not combine selection with gameplay prediction. Replication moves authoritative state;
  prediction is subsystem-specific behavior.

Read [`references/system-selector.md`](references/system-selector.md) before choosing.

## Design the network contract first

For every multiplayer action, state:

1. Which server object owns the canonical state?
2. Which client owns the connection allowed to request it?
3. What untrusted intent does the client submit?
4. What does the server validate and execute?
5. Which state persists for late join/relevancy and therefore uses properties?
6. Which transient occurrence uses an RPC or local reaction?
7. Which connections need the result, at what frequency and precision?
8. What may be predicted locally, and how is it reconciled?

Read [`references/authority-ownership.md`](references/authority-ownership.md).

## Choose state versus event

- Use replicated properties/RepNotify for durable state and late-joining/re-entering clients.
- Use Server RPCs for client intent on an actor/component owned by that client's connection.
- Use Client RPCs for targeted transient messages to the owning client.
- Use NetMulticast sparingly for transient effects visible to currently relevant clients.
- If every occurrence matters, do not encode it as repeated writes to one replicated scalar.
- Keep related values that require coherent handling in one replicated struct; OnRep order across
  separate properties is not deterministic.

Use [`references/properties-repnotify.md`](references/properties-repnotify.md) and
[`references/rpcs-ordering.md`](references/rpcs-ordering.md).

## Implement in dependency order

1. Set actor/component replication and server-only spawn/destruction.
2. Establish owner and owning connection; do not confuse ownership with authority.
3. Define replicated state, conditions, RepNotify handlers, and state invariants.
4. Define minimal client-intent Server RPCs with server validation/rate limits.
5. Add relevancy, priority, update frequency, and dormancy only from real requirements.
6. Use registered replicated subobjects and Fast Arrays for the relevant data shape.
7. Reuse CMC, GAS, or another subsystem's prediction rather than inventing generic prediction.
8. Test dedicated server and remote clients under lag, loss, jitter, reordering, reconnect, and
   relevancy transitions.
9. Capture Network Insights before optimizing bandwidth or selecting a scalable driver.

## Required answer format

Return:

1. **Authority/ownership table** per actor and action.
2. **Network contract**: client intent, server validation, canonical mutation, client result.
3. **Property/RPC/condition choice** with exact C++/Blueprint actions.
4. **Relevancy, dormancy, frequency, and scale strategy**.
5. **Prediction/reconciliation owner**, if any.
6. **Network test matrix and trace-based performance check**.

Do not invent ownership, delivery/order guarantees, maturity status, or bandwidth savings.

## Hard rules

- The server owns gameplay truth; client parameters are requests, never proof.
- `HasAuthority`/network role is not the owning connection.
- A client can call a Server RPC only through an actor/component it owns through its connection.
- Spawn and destroy replicated gameplay actors on the server.
- Never use reliable RPCs for high-frequency input/tick traffic.
- A client-called NetMulticast executes only on that invoking client.
- Do not rely on ordering across actors or between separate RepNotifies.
- Wake/flush a dormant actor **before** mutating replicated state.
- Replicate gameplay state, not widgets; local UI observes replicated models.
- Do not manually replicate Character transforms instead of CMC network movement.
- Profile before adopting Replication Graph, Iris, custom relevancy, or custom priority.

Read [`references/relevancy-dormancy.md`](references/relevancy-dormancy.md),
[`references/components-subobjects-fastarrays.md`](references/components-subobjects-fastarrays.md),
[`references/patterns.md`](references/patterns.md), and
[`references/debugging-testing.md`](references/debugging-testing.md). See
[`references/sources.md`](references/sources.md) for the UE 5.8 source trail.

## Ownership boundary

This skill owns general Actor/property/RPC authority, ownership, relevancy, dormancy, and state
transport. Prediction remains subsystem-owned: route Character saved moves/root motion to
[`unreal-character-movement`](/unreal/unreal-character-movement/), network physics/ragdolls to
[`unreal-chaos-physics`](/unreal/unreal-chaos-physics/), and ability prediction to
[`unreal-gas-abilities`](/unreal/unreal-gas-abilities/).

## Select the replication system

- Start with **Generic Replication**, UE 5.8's default, unless measured scale requires another
  system.
- Evaluate **Replication Graph** for many replicated actors and connections. It is Beta and does
  not currently support split screen on console builds.
- Evaluate **Iris** for its filtering/prioritization/scalability architecture only with an
  explicit migration and compatibility plan. UE 5.8 still marks Iris Experimental and Generic
  Replication remains the default.
- Do not combine selection with gameplay prediction. Replication moves authoritative state;
  prediction is subsystem-specific behavior.

Read [`references/system-selector.md`](/unreal/unreal-replication/system-selector/) before choosing.

## Design the network contract first

For every multiplayer action, state:

1. Which server object owns the canonical state?
2. Which client owns the connection allowed to request it?
3. What untrusted intent does the client submit?
4. What does the server validate and execute?
5. Which state persists for late join/relevancy and therefore uses properties?
6. Which transient occurrence uses an RPC or local reaction?
7. Which connections need the result, at what frequency and precision?
8. What may be predicted locally, and how is it reconciled?

Read [`references/authority-ownership.md`](/unreal/unreal-replication/authority-ownership/).

## Choose state versus event

- Use replicated properties/RepNotify for durable state and late-joining/re-entering clients.
- Use Server RPCs for client intent on an actor/component owned by that client's connection.
- Use Client RPCs for targeted transient messages to the owning client.
- Use NetMulticast sparingly for transient effects visible to currently relevant clients.
- If every occurrence matters, do not encode it as repeated writes to one replicated scalar.
- Keep related values that require coherent handling in one replicated struct; OnRep order across
  separate properties is not deterministic.

Use [`references/properties-repnotify.md`](/unreal/unreal-replication/properties-repnotify/) and
[`references/rpcs-ordering.md`](/unreal/unreal-replication/rpcs-ordering/).

## Implement in dependency order

1. Set actor/component replication and server-only spawn/destruction.
2. Establish owner and owning connection; do not confuse ownership with authority.
3. Define replicated state, conditions, RepNotify handlers, and state invariants.
4. Define minimal client-intent Server RPCs with server validation/rate limits.
5. Add relevancy, priority, update frequency, and dormancy only from real requirements.
6. Use registered replicated subobjects and Fast Arrays for the relevant data shape.
7. Reuse CMC, GAS, or another subsystem's prediction rather than inventing generic prediction.
8. Test dedicated server and remote clients under lag, loss, jitter, reordering, reconnect, and
   relevancy transitions.
9. Capture Network Insights before optimizing bandwidth or selecting a scalable driver.

## Required answer format

Return:

1. **Authority/ownership table** per actor and action.
2. **Network contract**: client intent, server validation, canonical mutation, client result.
3. **Property/RPC/condition choice** with exact C++/Blueprint actions.
4. **Relevancy, dormancy, frequency, and scale strategy**.
5. **Prediction/reconciliation owner**, if any.
6. **Network test matrix and trace-based performance check**.

Do not invent ownership, delivery/order guarantees, maturity status, or bandwidth savings.

## Hard rules

- The server owns gameplay truth; client parameters are requests, never proof.
- `HasAuthority`/network role is not the owning connection.
- A client can call a Server RPC only through an actor/component it owns through its connection.
- Spawn and destroy replicated gameplay actors on the server.
- Never use reliable RPCs for high-frequency input/tick traffic.
- A client-called NetMulticast executes only on that invoking client.
- Do not rely on ordering across actors or between separate RepNotifies.
- Wake/flush a dormant actor **before** mutating replicated state.
- Replicate gameplay state, not widgets; local UI observes replicated models.
- Do not manually replicate Character transforms instead of CMC network movement.
- Profile before adopting Replication Graph, Iris, custom relevancy, or custom priority.

Read [`references/relevancy-dormancy.md`](/unreal/unreal-replication/relevancy-dormancy/),
[`references/components-subobjects-fastarrays.md`](/unreal/unreal-replication/components-subobjects-fastarrays/),
[`references/patterns.md`](/unreal/unreal-replication/patterns/), and
[`references/debugging-testing.md`](/unreal/unreal-replication/debugging-testing/). See
[`references/sources.md`](/unreal/unreal-replication/sources/) for the UE 5.8 source trail.

unreal 5.8 replication design, implement, optimize, test, and debug server-authoritative multiplayer replication in unreal engine 5.8. use for authority, roles, ownership, owning connections, replicated actors/components/properties, repnotify, rpcs, relevancy, priority, dormancy, conditions, fast arrays, replicated uobjects/subobjects, generic replication, replication graph, iris, bandwidth, ordering, prediction boundaries, network insights, packet emulation, or multiplayer ui state. authority, role, and owning connection authority, role, and owning connection keep the concepts separate | concept | answers | |---|---| | authority / local role | which machine owns this actor's canonical replicated copy? | | owner | which actor is this actor's ue owner? | | owning connection | which client connection is reached through the owner chain to a playercontroller? | | local control | is this pawn/controller controlled by a local player on this machine? | | relevancy | should this connection currently receive this actor? | network role is not ownership. a server has authority over replicated gameplay actors, while a client may own a connection to its playercontroller/pawn and therefore be permitted to call server rpcs through that chain. client request path text local input/ui -> locally owned playercontroller, pawn, or owned replicated component -> server rpc carrying minimal intent -> server validates current canonical state, range, permissions, rate, and target -> server mutates canonical state -> properties/rpcs replicate the result do not put server rpcs on arbitrary world actors and expect clients to call them. route the request through an owned actor, then have server code interact with the target. validation checklist validate on the server: - requesting connection may perform the action; - actor and target still exist and are relevant to the rule; - distance, line of sight, cooldown, resources, and state preconditions; - numeric values are bounded and derived server-side where possible; - request rate/sequence is acceptable; - the request cannot select objects hidden from that player; - repeated or reordered requests are safe/idempotent where needed. withvalidation is an available c++ rpc mechanism, but server gameplay logic must still enforce rules regardless of where validation is written. spawn and destruction - spawn replicated gameplay actors on the server. - destroy them on the server. - a client-spawned actor is local to that client unless it participates through another authoritative mechanism; setting replicates on the client copy does not create the server copy. - cosmetic local actors are allowed when they have no gameplay authority. ui boundary widgets are not replicated actors and should not own rpcs. a widget emits intent to its owning local controller/pawn/component. it observes replicated state through a presenter/viewmodel. components, subobjects, and fast arrays components, subobjects, and fast arrays replicated actorcomponents both must be true: - owning actor replicates; - actorcomponent replicates (setisreplicatedbydefault(true) in the component constructor for a default behavior, or the appropriate instance setup). components can replicate properties, rpcs, and their own subobjects. component rpcs add more overhead than actor rpcs; route high-volume calls through the actor when appropriate. replicated uobjects/subobjects use a uobject subobject when state belongs to an actor/component but needs its own identity and replicated properties without becoming a world actor. preferred forward-compatible procedure: 1. make the outer/owner a replicated actor or replicated actorcomponent. 2. enable breplicateusingregisteredsubobjectlist on that owner. 3. create the subobject on the server with a stable ownership relationship. 4. register it with addreplicatedsubobject and an optional condition. 5. remove/unregister it before deletion when required by the lifetime path. 6. wake/flush the owning actor before changing a dormant subobject. the registered subobject list works with generic replication and repgraph and is the only supported subobject method for iris. do not enable iris while relying only on legacy replicatesubobjects overrides. fast arrays use ffastarrayserializer for replicated collections with item-level additions, removals, and changes where a normal whole-array representation is too costly or lacks item callbacks. implementation contract: - item struct derives from ffastarrayserializeritem; - container struct derives from ffastarrayserializer and owns the item array; - provide the required delta serialization trait/function for the chosen pattern; - call markitemdirty after an item changes; - call markarraydirty for structural changes when required by the operation; - handle add/change/remove callbacks as received-state reactions; - use stable item identity and do not retain pointers to entries that may move. verify exact signatures against fastarrayserializer.h for the engine build; do not invent them from memory. iris has a native fast array path, but iris itself remains experimental. selection | data | representation | |---|---| | a few scalar states | actor/component replicated properties | | cohesive values needing ordered handling | one replicated struct | | large changing item collection | fast array | | modular owned state object | registered replicated uobject subobject | | independent world relevance/transform | replicated actor | debugging, testing, and profiling debugging, testing, and profiling minimum topology matrix test each feature in: - dedicated server + two remote clients; - listen server + remote client; - late join after state changed; - leave and re-enter relevancy; - disconnect/reconnect or respawn where supported; - two local players if split screen is supported. do not accept a listen-server-only pass; the host combines authority and local control and can hide ownership defects. adverse network matrix use ue network emulation, then turn it off after each test: - latency (netemulation.pktlag or a named emulation profile); - packet loss (netemulation.pktloss); - jitter/lag variance; - packet duplication; - packet reordering, when compatible with the chosen lag settings. verify input responsiveness, correction, reliable-queue health, stale-state rejection, and eventual authoritative convergence. network insights launch instances with networking trace enabled, for example: text -trace=net -nettrace=1 for editor capture, add -tracehost=localhost when needed. inspect: - packet overview for timing and size; - packet content for actors, properties, and rpcs; - net stats for inclusive/exclusive byte cost; - connection direction and selected connection; - spikes during spawn, relevance changes, or ui-driven action spam. useful commands - net.actorreport: active replicated actor information. - net.dumprelevantactors: actors relevant on the next update. - net.listactorchannels: open actor channels. - net.forceonepacketperbunch: stress ordering assumptions. - net.dormancyenable 0/1: isolate dormancy-related failures. - showdebug enhancedinput: inspect input before blaming rpcs. confirm command availability/side effects in the 5.8 console-command reference before adding to automation or shipping tooling. failure tree | symptom | first checks | |---|---| | server rpc never runs | caller owns actor, actor/component replicates, call made on client copy | | property only updates for owner | replication condition and actor relevancy/ownership | | works until actor sleeps | wake/flush before mutation, including component/subobject | | remote client misses effect | actor relevance at multicast time; should it be durable state? | | duplicate/late effect | repnotify treated as a new event instead of current state | | character rubber-bands | server/client movement divergence; use cmc trace/saved moves | | bandwidth spike | high-frequency rpc/property, always-relevant actors, large collections | | only host works | local-control/authority branch conflated or wrong owner | shipping gate - server remains correct with malicious/out-of-range/repeated client requests. - all durable state reconstructs for late and re-relevant clients. - reliable rpc rate is bounded under worst input spam. - ordering assumptions survive forced packet/bunch stress. - network insights meets server cpu and per-connection bandwidth budgets at target scale. - experimental/beta system risks and rollback are documented. replication patterns replication patterns networked door 1. server owns bisopen (repnotify) and interaction rules. 2. client sends servertryinteract(door) through its owned pawn/controller. 3. server validates range, line of sight, permissions, and current state. 4. wake the dormant door before mutation. 5. repnotify sets door presentation from current state. 6. return the door to dormancy after it settles. do not multicast the only open event; a late-relevant client needs durable state. health and ui 1. server applies damage and owns health. 2. health replicates/uses gas attribute replication. 3. repnotify/attribute delegate updates a local presentation model. 4. local hud pushes the display change. 5. death state is authoritative; cosmetic hit/death cues may be transient. route gas details to $unreal-gas-attributes-effects and ui details to $unreal-umg-commonui. inventory - server owns the collection and validates add/remove/equip/drop. - client submits item identity and requested verb, never a new inventory total. - use a fast array when item-level delta replication and callbacks justify it. - use owner-only conditions for private inventory; replicate public equipped presentation separately when other clients need it. - ui selection is local and keyed by stable item identity. projectile selector - important persistent/colliding projectile: server-spawned replicated actor with an appropriate movement/prediction model. - high-volume cosmetic tracer: local cosmetic driven from an authoritative hit/result event. - never accept a client claim that a hit occurred without server validation or the game's deliberate lag-compensation model. character movement use acharacter + ucharactermovementcomponent network prediction/correction for standard characters. do not send per-tick transform rpcs or use client setactorlocation as prediction. route custom movement serialization to $unreal-character-movement. match state placement - gamemode: server-only rules and authority. - gamestate: replicated match-wide state clients need. - playerstate: replicated player state that should outlive pawn possession and be visible as designed. - playercontroller: owner-only control/request channel; each client gets its own controller. - pawn/character: current possessed avatar and movement/gameplay state. choose placement from lifetime, visibility, and ownership—not convenience. replicated properties and repnotify replicated properties and repnotify use properties for state choose a replicated property when a client becoming relevant later must learn the current truth: - health, score, inventory contents, team, door open/closed state; - match phase and timestamps; - equipped item or persistent ability state. on the server, mutate the canonical property. clients apply received values; client edits to a replica are not authoritative and may be overwritten. c++ setup 1. set the actor to replicate. 2. mark the property uproperty(replicated) or uproperty(replicatedusing=onrepname). 3. override getlifetimereplicatedprops and call super. 4. register with doreplifetime, a condition macro, or lifetime params. 5. put client-side reaction in the repnotify; it may accept the previous value. use blueprint replicated/repnotify settings for blueprint actors, but keep the same ownership and state rules. repnotify design - treat repnotify as "received/applied current replicated state," not proof that the event just happened in the viewer's timeline. - make presentation reactions idempotent. - if server and clients require the same reaction, put it in a shared non-rpc function and call it from the authoritative mutation path and repnotify as appropriate. do not assume all c++ and blueprint repnotify server behaviors are identical. - use the previous-value parameter when transition logic needs old versus new. - put values requiring coherent ordering in one replicated struct. epic states there is no deterministic order between onreps for separate variables. conditions use the narrowest correct built-in condition: - condowneronly: private owner state; - condskipowner: remote-only correction/presentation when owner predicts; - condinitialonly: immutable setup state after initial replication; - condsimulatedonly / condautonomousonly: role-specific state; - conddynamic or custom active override only when simpler static conditions cannot express it. conditions are per registered property layout; avoid per-instance assumptions in lifetime setup. state versus occurrence repeated writes can collapse to the latest received state. if every occurrence matters, use an appropriate event/rpc, counter/sequence, or replicated collection—not a bool toggled too quickly. for a chest, replicate bisopen for durable state; emit/derive the opening effect only when its timing is still meaningful. ui hookup repnotify or a gameplay delegate updates a local presenter/viewmodel, which pushes into widgets. never bind ui to poll replicated properties every frame. relevancy, priority, frequency, and dormancy relevancy, priority, frequency, and dormancy relevancy relevancy is per connection: should this actor affect this viewer now? use built-in settings before overriding isnetrelevantfor: - balwaysrelevant for genuinely global actors only; - bonlyrelevanttoowner for private actors such as a playercontroller; - bnetuseownerrelevancy for actors that should follow their owner; - netculldistancesquared for distance-based relevance where enabled. dynamically spawned replicated actors can be destroyed on a client when they become irrelevant and recreated when relevant again. durable state must survive that transition through replication, not a one-shot multicast. update frequency and priority - netupdatefrequency determines how often an actor is considered for updates in generic replication. - priority decides which actors replicate first when a connection saturates; elapsed time since last update contributes, preventing simple starvation. - do not set every actor always relevant or high frequency. - change frequency/priority only from measured responsiveness and bandwidth evidence. dormancy use dormancy for actors that replicate state but remain unchanged for long periods. epic calls it one of the most impactful server replication optimizations. procedure: 1. map-placed initially static actor: start with dorminitial when appropriate. 2. runtime/static actor: use dormdormantall when all connections can sleep it. 3. before changing replicated actor/component/subobject state, call flushnetdormancy, forcenetupdate, or set dormawake as the update pattern requires. 4. for continuous changes, wake with setnetdormancy(dormawake) and return to dormdormantall after state settles. 5. do not return a once-awakened map actor to dorminitial. blueprint actor replicated-property writes may flush automatically, but replicated actorcomponent blueprint properties do not have the same guarantee. keep the explicit wake-before-mutate rule. diagnostic sequence if a property updates only sometimes: 1. confirm mutation occurs on the server. 2. confirm the actor/component/property replicates. 3. confirm the connection owns/is relevant as required. 4. check dormancy and wake order. 5. check condition and update frequency. 6. inspect the packet/property in network insights. use lognetdormancy, net.dumprelevantactors, and net.actorreport for targeted evidence. rpcs, reliability, and ordering rpcs, reliability, and ordering rpc selector | need | mechanism | |---|---| | client requests authoritative action | server rpc on client-owned actor/component | | server targets one owning client | client rpc | | server sends transient effect to currently relevant clients | netmulticast, sparingly | | durable state for late relevance/join | replicated property, not rpc | | local-only presentation | local function/event | rpcs are unidirectional and do not return values. return outcomes through replicated state or a separate targeted response. execution truths - a client server rpc runs remotely only when invoked through that client's owning connection; otherwise it is dropped. - a server client rpc targets the actor's owning client. - a server netmulticast runs on the server and clients for which the actor is currently relevant. - a client-called netmulticast runs only on the invoking client. - rpcs require a replicated actor/component and valid ownership conditions. reliable versus unreliable use reliable only when loss would break a low-frequency essential transition and the call rate is strictly bounded. reliable rpcs consume an ordered reliable queue; input spam can overflow it. use unreliable for frequent, replaceable, or cosmetic occurrences. design behavior that remains correct when unreliable calls are dropped. never send reliable rpcs from tick or directly from unbounded button repeat. prefer replicated state when the current result matters more than each call. ordering rules - do not rely on rpc call order across different actors. - reliable rpc ordering guarantees are scoped; do not infer a global event timeline. - multicast versus unicast ordering is not universally preserved. - separate repnotify callback order is nondeterministic. - if values must be interpreted atomically/coherently, group them in one struct or add an explicit sequence/state-machine contract. design receivers to be idempotent, tolerate missing obsolete events, and reject stale sequence numbers when correctness requires it. request payload rule send minimum intent, for example tryinteract(target) or tryequip(itemid). do not send trusted results such as new balance, damage dealt, final position, or permission flags. the server derives and validates results from canonical state. ue 5.8 primary sources ue 5.8 primary sources all links were checked against epic's ue 5.8 documentation on 2026-07-19. fundamentals - networking overview - actor owner and owning connection - actor role and remote role - replicate actor properties - remote procedure calls - replicated object execution order filtering and performance - actor relevancy - actor priority - actor network dormancy - detailed actor replication flow - replication graph components, subobjects, and scale systems - replicating actor components - replicating uobjects - ffastarrayserializer - introduction to iris - migrate to iris testing and subsystem boundaries - testing, debugging, and optimization - networking insights - console commands for network debugging - networked character movement ue 5.8 maturity notes - generic replication is the default. - replication graph is marked beta. - iris is compiled in but remains experimental and is not the default. - the registered subobject list is the only subobject method compatible with iris. replication-system selector replication-system selector generic replication use by default. it supports replicated actors, properties, rpcs, relevancy, priority, update frequency, dormancy, components, and subobjects. most ue networking documentation assumes it. remain on generic replication when actor/connection counts fit the server budget and its model meets the game's filtering needs. tune content and dormancy before replacing the driver. replication graph evaluate when the server must repeatedly build per-connection replication lists for large actor and connection counts. repgraph keeps persistent graph nodes/lists that share work across frames and connections. adoption gate: - a network insights/server trace shows replication-list gathering or per-connection actor evaluation is a material bottleneck; - actor categories have clear spatial, always-relevant, owner-only, team, or dormancy rules; - the team can implement and test custom graph nodes; - the project accepts beta maturity; - console split screen is not required, because epic documents that limitation. iris iris is compiled into ue but is not the default replication system. ue 5.8 marks it experimental. it changes relevancy into filtering and priority into iris prioritization, shares quantized replicated state work, and aims for stronger scalability/concurrency. adoption gate: - a specific iris capability or measured scale need justifies experimental risk; - all plugins/subsystems and custom serializers are compatibility-tested; - replicated subobjects use the registered subobject list; - migration differences are documented and both network correctness and performance are tested; - rollback to generic replication is planned until the shipping gate is passed. do not select iris because it is newer. do not assume generic settings map unchanged: consult the 5.8 migration guide. selection output return: | candidate | measured need | maturity/constraint | decision | |---|---|---|---| | generic | baseline | default/stable path | use/reject | | repgraph | large actor x connection filtering cost | beta; console split-screen limitation | use/reject | | iris | specific filtering/prioritization/scalability need | experimental; migration work | use/reject | no selection is complete without a representative server trace and target-player-count test.

Authority, role, and owning connection

# Authority, role, and owning connection

## Keep the concepts separate

| Concept | Answers |
|---|---|
| Authority / local role | Which machine owns this actor's canonical replicated copy? |
| Owner | Which Actor is this actor's UE owner? |
| Owning connection | Which client connection is reached through the owner chain to a PlayerController? |
| Local control | Is this Pawn/Controller controlled by a local player on this machine? |
| Relevancy | Should this connection currently receive this actor? |

Network role is not ownership. A server has authority over replicated gameplay actors, while a
client may own a connection to its PlayerController/Pawn and therefore be permitted to call
Server RPCs through that chain.

## Client request path

```text
local input/UI
  -> locally owned PlayerController, Pawn, or owned replicated component
  -> Server RPC carrying minimal intent
  -> server validates current canonical state, range, permissions, rate, and target
  -> server mutates canonical state
  -> properties/RPCs replicate the result
```

Do not put Server RPCs on arbitrary world actors and expect clients to call them. Route the
request through an owned actor, then have server code interact with the target.

## Validation checklist

Validate on the server:

- requesting connection may perform the action;
- actor and target still exist and are relevant to the rule;
- distance, line of sight, cooldown, resources, and state preconditions;
- numeric values are bounded and derived server-side where possible;
- request rate/sequence is acceptable;
- the request cannot select objects hidden from that player;
- repeated or reordered requests are safe/idempotent where needed.

`WithValidation` is an available C++ RPC mechanism, but server gameplay logic must still enforce
rules regardless of where validation is written.

## Spawn and destruction

- Spawn replicated gameplay actors on the server.
- Destroy them on the server.
- A client-spawned actor is local to that client unless it participates through another
  authoritative mechanism; setting Replicates on the client copy does not create the server copy.
- Cosmetic local actors are allowed when they have no gameplay authority.

## UI boundary

Widgets are not replicated actors and should not own RPCs. A widget emits intent to its owning
local controller/pawn/component. It observes replicated state through a presenter/Viewmodel.

Components, subobjects, and Fast Arrays

# Components, subobjects, and Fast Arrays

## Replicated ActorComponents

Both must be true:

- owning Actor replicates;
- ActorComponent replicates (`SetIsReplicatedByDefault(true)` in the component constructor for a
  default behavior, or the appropriate instance setup).

Components can replicate properties, RPCs, and their own subobjects. Component RPCs add more
overhead than Actor RPCs; route high-volume calls through the Actor when appropriate.

## Replicated UObjects/subobjects

Use a UObject subobject when state belongs to an Actor/component but needs its own identity and
replicated properties without becoming a world Actor.

Preferred forward-compatible procedure:

1. Make the outer/owner a replicated Actor or replicated ActorComponent.
2. Enable `bReplicateUsingRegisteredSubObjectList` on that owner.
3. Create the subobject on the server with a stable ownership relationship.
4. Register it with `AddReplicatedSubObject` and an optional condition.
5. Remove/unregister it before deletion when required by the lifetime path.
6. Wake/flush the owning Actor before changing a dormant subobject.

The registered subobject list works with Generic Replication and RepGraph and is the only
supported subobject method for Iris. Do not enable Iris while relying only on legacy
`ReplicateSubobjects` overrides.

## Fast Arrays

Use `FFastArraySerializer` for replicated collections with item-level additions, removals, and
changes where a normal whole-array representation is too costly or lacks item callbacks.

Implementation contract:

- item struct derives from `FFastArraySerializerItem`;
- container struct derives from `FFastArraySerializer` and owns the item array;
- provide the required delta serialization trait/function for the chosen pattern;
- call `MarkItemDirty` after an item changes;
- call `MarkArrayDirty` for structural changes when required by the operation;
- handle add/change/remove callbacks as received-state reactions;
- use stable item identity and do not retain pointers to entries that may move.

Verify exact signatures against `FastArraySerializer.h` for the engine build; do not invent them
from memory. Iris has a native Fast Array path, but Iris itself remains Experimental.

## Selection

| Data | Representation |
|---|---|
| A few scalar states | actor/component replicated properties |
| Cohesive values needing ordered handling | one replicated struct |
| Large changing item collection | Fast Array |
| Modular owned state object | registered replicated UObject subobject |
| Independent world relevance/transform | replicated Actor |

Debugging, testing, and profiling

# Debugging, testing, and profiling

## Minimum topology matrix

Test each feature in:

- dedicated server + two remote clients;
- listen server + remote client;
- late join after state changed;
- leave and re-enter relevancy;
- disconnect/reconnect or respawn where supported;
- two local players if split screen is supported.

Do not accept a listen-server-only pass; the host combines authority and local control and can
hide ownership defects.

## Adverse network matrix

Use UE network emulation, then turn it off after each test:

- latency (`NetEmulation.PktLag` or a named emulation profile);
- packet loss (`NetEmulation.PktLoss`);
- jitter/lag variance;
- packet duplication;
- packet reordering, when compatible with the chosen lag settings.

Verify input responsiveness, correction, reliable-queue health, stale-state rejection, and
eventual authoritative convergence.

## Network Insights

Launch instances with networking trace enabled, for example:

```text
-trace=net -NetTrace=1
```

For editor capture, add `-tracehost=localhost` when needed. Inspect:

- Packet Overview for timing and size;
- Packet Content for actors, properties, and RPCs;
- Net Stats for inclusive/exclusive byte cost;
- connection direction and selected connection;
- spikes during spawn, relevance changes, or UI-driven action spam.

## Useful commands

- `net.ActorReport`: active replicated actor information.
- `net.DumpRelevantActors`: actors relevant on the next update.
- `net.ListActorChannels`: open actor channels.
- `net.ForceOnePacketPerBunch`: stress ordering assumptions.
- `net.DormancyEnable 0/1`: isolate dormancy-related failures.
- `showdebug enhancedinput`: inspect input before blaming RPCs.

Confirm command availability/side effects in the 5.8 console-command reference before adding to
automation or shipping tooling.

## Failure tree

| Symptom | First checks |
|---|---|
| Server RPC never runs | caller owns actor, actor/component replicates, call made on client copy |
| Property only updates for owner | replication condition and actor relevancy/ownership |
| Works until actor sleeps | wake/flush before mutation, including component/subobject |
| Remote client misses effect | actor relevance at multicast time; should it be durable state? |
| Duplicate/late effect | RepNotify treated as a new event instead of current state |
| Character rubber-bands | server/client movement divergence; use CMC trace/saved moves |
| Bandwidth spike | high-frequency RPC/property, always-relevant actors, large collections |
| Only host works | local-control/authority branch conflated or wrong owner |

## Shipping gate

- Server remains correct with malicious/out-of-range/repeated client requests.
- All durable state reconstructs for late and re-relevant clients.
- Reliable RPC rate is bounded under worst input spam.
- Ordering assumptions survive forced packet/bunch stress.
- Network Insights meets server CPU and per-connection bandwidth budgets at target scale.
- Experimental/Beta system risks and rollback are documented.

Replication patterns

# Replication patterns

## Networked door

1. Server owns `bIsOpen` (RepNotify) and interaction rules.
2. Client sends `ServerTryInteract(Door)` through its owned Pawn/Controller.
3. Server validates range, line of sight, permissions, and current state.
4. Wake the dormant door before mutation.
5. RepNotify sets door presentation from current state.
6. Return the door to dormancy after it settles.

Do not multicast the only open event; a late-relevant client needs durable state.

## Health and UI

1. Server applies damage and owns health.
2. Health replicates/uses GAS attribute replication.
3. RepNotify/attribute delegate updates a local presentation model.
4. Local HUD pushes the display change.
5. Death state is authoritative; cosmetic hit/death cues may be transient.

Route GAS details to `$unreal-gas-attributes-effects` and UI details to
`$unreal-umg-commonui`.

## Inventory

- Server owns the collection and validates add/remove/equip/drop.
- Client submits item identity and requested verb, never a new inventory total.
- Use a Fast Array when item-level delta replication and callbacks justify it.
- Use owner-only conditions for private inventory; replicate public equipped presentation
  separately when other clients need it.
- UI selection is local and keyed by stable item identity.

## Projectile selector

- Important persistent/colliding projectile: server-spawned replicated Actor with an appropriate
  movement/prediction model.
- High-volume cosmetic tracer: local cosmetic driven from an authoritative hit/result event.
- Never accept a client claim that a hit occurred without server validation or the game's
  deliberate lag-compensation model.

## Character movement

Use `ACharacter` + `UCharacterMovementComponent` network prediction/correction for standard
characters. Do not send per-tick transform RPCs or use client `SetActorLocation` as prediction.
Route custom movement serialization to `$unreal-character-movement`.

## Match state placement

- `GameMode`: server-only rules and authority.
- `GameState`: replicated match-wide state clients need.
- `PlayerState`: replicated player state that should outlive Pawn possession and be visible as
  designed.
- `PlayerController`: owner-only control/request channel; each client gets its own controller.
- `Pawn/Character`: current possessed avatar and movement/gameplay state.

Choose placement from lifetime, visibility, and ownership—not convenience.

Replicated properties and RepNotify

# Replicated properties and RepNotify

## Use properties for state

Choose a replicated property when a client becoming relevant later must learn the current truth:

- health, score, inventory contents, team, door open/closed state;
- match phase and timestamps;
- equipped item or persistent ability state.

On the server, mutate the canonical property. Clients apply received values; client edits to a
replica are not authoritative and may be overwritten.

## C++ setup

1. Set the actor to replicate.
2. Mark the property `UPROPERTY(Replicated)` or `UPROPERTY(ReplicatedUsing=OnRep_Name)`.
3. Override `GetLifetimeReplicatedProps` and call `Super`.
4. Register with `DOREPLIFETIME`, a condition macro, or lifetime params.
5. Put client-side reaction in the RepNotify; it may accept the previous value.

Use Blueprint Replicated/RepNotify settings for Blueprint actors, but keep the same ownership and
state rules.

## RepNotify design

- Treat RepNotify as "received/applied current replicated state," not proof that the event just
  happened in the viewer's timeline.
- Make presentation reactions idempotent.
- If server and clients require the same reaction, put it in a shared non-RPC function and call it
  from the authoritative mutation path and RepNotify as appropriate. Do not assume all C++ and
  Blueprint RepNotify server behaviors are identical.
- Use the previous-value parameter when transition logic needs old versus new.
- Put values requiring coherent ordering in one replicated struct. Epic states there is no
  deterministic order between OnReps for separate variables.

## Conditions

Use the narrowest correct built-in condition:

- `COND_OwnerOnly`: private owner state;
- `COND_SkipOwner`: remote-only correction/presentation when owner predicts;
- `COND_InitialOnly`: immutable setup state after initial replication;
- `COND_SimulatedOnly` / `COND_AutonomousOnly`: role-specific state;
- `COND_Dynamic` or custom active override only when simpler static conditions cannot express it.

Conditions are per registered property layout; avoid per-instance assumptions in lifetime setup.

## State versus occurrence

Repeated writes can collapse to the latest received state. If every occurrence matters, use an
appropriate event/RPC, counter/sequence, or replicated collection—not a bool toggled too quickly.
For a chest, replicate `bIsOpen` for durable state; emit/derive the opening effect only when its
timing is still meaningful.

## UI hookup

RepNotify or a gameplay delegate updates a local presenter/Viewmodel, which pushes into widgets.
Never bind UI to poll replicated properties every frame.

# Relevancy, priority, frequency, and dormancy

## Relevancy

Relevancy is per connection: should this actor affect this viewer now? Use built-in settings before
overriding `IsNetRelevantFor`:

- `bAlwaysRelevant` for genuinely global actors only;
- `bOnlyRelevantToOwner` for private actors such as a PlayerController;
- `bNetUseOwnerRelevancy` for actors that should follow their owner;
- `NetCullDistanceSquared` for distance-based relevance where enabled.

Dynamically spawned replicated actors can be destroyed on a client when they become irrelevant
and recreated when relevant again. Durable state must survive that transition through replication,
not a one-shot multicast.

## Update frequency and priority

- `NetUpdateFrequency` determines how often an actor is considered for updates in Generic
  Replication.
- Priority decides which actors replicate first when a connection saturates; elapsed time since
  last update contributes, preventing simple starvation.
- Do not set every actor always relevant or high frequency.
- Change frequency/priority only from measured responsiveness and bandwidth evidence.

## Dormancy

Use dormancy for actors that replicate state but remain unchanged for long periods. Epic calls it
one of the most impactful server replication optimizations.

Procedure:

1. Map-placed initially static actor: start with `DORM_Initial` when appropriate.
2. Runtime/static actor: use `DORM_DormantAll` when all connections can sleep it.
3. **Before** changing replicated actor/component/subobject state, call `FlushNetDormancy`,
   `ForceNetUpdate`, or set `DORM_Awake` as the update pattern requires.
4. For continuous changes, wake with `SetNetDormancy(DORM_Awake)` and return to
   `DORM_DormantAll` after state settles.
5. Do not return a once-awakened map actor to `DORM_Initial`.

Blueprint actor replicated-property writes may flush automatically, but replicated ActorComponent
Blueprint properties do not have the same guarantee. Keep the explicit wake-before-mutate rule.

## Diagnostic sequence

If a property updates only sometimes:

1. Confirm mutation occurs on the server.
2. Confirm the actor/component/property replicates.
3. Confirm the connection owns/is relevant as required.
4. Check dormancy and wake order.
5. Check condition and update frequency.
6. Inspect the packet/property in Network Insights.

Use `LogNetDormancy`, `net.DumpRelevantActors`, and `net.ActorReport` for targeted evidence.

RPCs, reliability, and ordering

# RPCs, reliability, and ordering

## RPC selector

| Need | Mechanism |
|---|---|
| Client requests authoritative action | Server RPC on client-owned actor/component |
| Server targets one owning client | Client RPC |
| Server sends transient effect to currently relevant clients | NetMulticast, sparingly |
| Durable state for late relevance/join | Replicated property, not RPC |
| Local-only presentation | Local function/event |

RPCs are unidirectional and do not return values. Return outcomes through replicated state or a
separate targeted response.

## Execution truths

- A client Server RPC runs remotely only when invoked through that client's owning connection;
  otherwise it is dropped.
- A server Client RPC targets the actor's owning client.
- A server NetMulticast runs on the server and clients for which the actor is currently relevant.
- A client-called NetMulticast runs only on the invoking client.
- RPCs require a replicated actor/component and valid ownership conditions.

## Reliable versus unreliable

Use reliable only when loss would break a low-frequency essential transition and the call rate is
strictly bounded. Reliable RPCs consume an ordered reliable queue; input spam can overflow it.

Use unreliable for frequent, replaceable, or cosmetic occurrences. Design behavior that remains
correct when unreliable calls are dropped.

Never send reliable RPCs from Tick or directly from unbounded button repeat. Prefer replicated
state when the current result matters more than each call.

## Ordering rules

- Do not rely on RPC call order across different actors.
- Reliable RPC ordering guarantees are scoped; do not infer a global event timeline.
- Multicast versus unicast ordering is not universally preserved.
- Separate RepNotify callback order is nondeterministic.
- If values must be interpreted atomically/coherently, group them in one struct or add an explicit
  sequence/state-machine contract.

Design receivers to be idempotent, tolerate missing obsolete events, and reject stale sequence
numbers when correctness requires it.

## Request payload rule

Send minimum intent, for example `TryInteract(Target)` or `TryEquip(ItemId)`. Do not send trusted
results such as new balance, damage dealt, final position, or permission flags. The server derives
and validates results from canonical state.

UE 5.8 primary sources

# UE 5.8 primary sources

All links were checked against Epic's UE 5.8 documentation on 2026-07-19.

## Fundamentals

- [Networking Overview](https://dev.epicgames.com/documentation/en-us/unreal-engine/networking-overview-for-unreal-engine)
- [Actor owner and owning connection](https://dev.epicgames.com/documentation/en-us/unreal-engine/actor-owner-and-owning-connection-in-unreal-engine)
- [Actor role and remote role](https://dev.epicgames.com/documentation/en-us/unreal-engine/actor-role-and-remote-role-in-unreal-engine)
- [Replicate Actor Properties](https://dev.epicgames.com/documentation/en-us/unreal-engine/replicate-actor-properties-in-unreal-engine)
- [Remote Procedure Calls](https://dev.epicgames.com/documentation/en-us/unreal-engine/remote-procedure-calls-in-unreal-engine)
- [Replicated Object Execution Order](https://dev.epicgames.com/documentation/en-us/unreal-engine/replicated-object-execution-order-in-unreal-engine)

## Filtering and performance

- [Actor Relevancy](https://dev.epicgames.com/documentation/en-us/unreal-engine/actor-relevancy-in-unreal-engine)
- [Actor Priority](https://dev.epicgames.com/documentation/en-us/unreal-engine/actor-priority-in-unreal-engine)
- [Actor Network Dormancy](https://dev.epicgames.com/documentation/en-us/unreal-engine/actor-network-dormancy-in-unreal-engine)
- [Detailed Actor Replication Flow](https://dev.epicgames.com/documentation/en-us/unreal-engine/detailed-actor-replication-flow-in-unreal-engine)
- [Replication Graph](https://dev.epicgames.com/documentation/en-us/unreal-engine/replication-graph-in-unreal-engine)

## Components, subobjects, and scale systems

- [Replicating Actor Components](https://dev.epicgames.com/documentation/en-us/unreal-engine/replicating-actor-components-in-unreal-engine)
- [Replicating UObjects](https://dev.epicgames.com/documentation/en-us/unreal-engine/replicating-uobjects-in-unreal-engine)
- [`FFastArraySerializer`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/NetCore/FFastArraySerializer)
- [Introduction to Iris](https://dev.epicgames.com/documentation/en-us/unreal-engine/introduction-to-iris-in-unreal-engine)
- [Migrate to Iris](https://dev.epicgames.com/documentation/en-us/unreal-engine/migrate-to-iris-in-unreal-engine)

## Testing and subsystem boundaries

- [Testing, Debugging, and Optimization](https://dev.epicgames.com/documentation/en-us/unreal-engine/network-debugging-for-unreal-engine)
- [Networking Insights](https://dev.epicgames.com/documentation/en-us/unreal-engine/networking-insights-in-unreal-engine)
- [Console Commands for Network Debugging](https://dev.epicgames.com/documentation/en-us/unreal-engine/console-commands-for-network-debugging-in-unreal-engine)
- [Networked Character Movement](https://dev.epicgames.com/documentation/en-us/unreal-engine/understanding-networked-movement-in-the-character-movement-component-for-unreal-engine)

## UE 5.8 maturity notes

- Generic Replication is the default.
- Replication Graph is marked **Beta**.
- Iris is compiled in but remains **Experimental** and is not the default.
- The registered subobject list is the only subobject method compatible with Iris.

Replication-system selector

# Replication-system selector

## Generic Replication

Use by default. It supports replicated actors, properties, RPCs, relevancy, priority, update
frequency, dormancy, components, and subobjects. Most UE networking documentation assumes it.

Remain on Generic Replication when actor/connection counts fit the server budget and its model
meets the game's filtering needs. Tune content and dormancy before replacing the driver.

## Replication Graph

Evaluate when the server must repeatedly build per-connection replication lists for large actor
and connection counts. RepGraph keeps persistent graph nodes/lists that share work across frames
and connections.

Adoption gate:

- a Network Insights/server trace shows replication-list gathering or per-connection actor
  evaluation is a material bottleneck;
- actor categories have clear spatial, always-relevant, owner-only, team, or dormancy rules;
- the team can implement and test custom graph nodes;
- the project accepts Beta maturity;
- console split screen is not required, because Epic documents that limitation.

## Iris

Iris is compiled into UE but is not the default replication system. UE 5.8 marks it
**Experimental**. It changes relevancy into filtering and priority into Iris prioritization,
shares quantized replicated state work, and aims for stronger scalability/concurrency.

Adoption gate:

- a specific Iris capability or measured scale need justifies Experimental risk;
- all plugins/subsystems and custom serializers are compatibility-tested;
- replicated subobjects use the registered subobject list;
- migration differences are documented and both network correctness and performance are tested;
- rollback to Generic Replication is planned until the shipping gate is passed.

Do not select Iris because it is newer. Do not assume Generic settings map unchanged: consult the
5.8 migration guide.

## Selection output

Return:

| Candidate | Measured need | Maturity/constraint | Decision |
|---|---|---|---|
| Generic | baseline | default/stable path | use/reject |
| RepGraph | large actor x connection filtering cost | Beta; console split-screen limitation | use/reject |
| Iris | specific filtering/prioritization/scalability need | Experimental; migration work | use/reject |

No selection is complete without a representative server trace and target-player-count test.