ue-networking-replication
Use this skill when working on multiplayer networking, replication, RPC calls, net role logic, server/client authority, prediction, or synchronizing game state. Also use when the user mentions 'DOREPLIFETIME', 'dedicated server', 'replicated', or 'net role'. See references/replication-patterns.md fo
By quodsoler · 822 installs
npx skills add quodsoler/unreal-engine-skills --skill ue-networking-replication
Source repository · Upstream listing
UE Networking & Replication
Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".
Server authoritative replication for actors, components and subobjects. Core APIs live in the Engine module ( GameFramework/Actor.h , Engine/NetDriver.h , Net/UnrealNetwork.h ) and the NetCore module ( Net/Core/PushModel/PushModel.h , Net/Serialization/FastArraySerializer.h ). ELifetimeCondition and REPNOTIFY come from CoreUObject ( UObject/CoreNetTypes.h ). Optional systems: the Iris replication system ( IrisCore module, SetupIrisSupport(Target) in Build.cs) and the ReplicationGraph plugin (Beta in 5.8, Build.cs module ReplicationGraph ).
Context
Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing.
Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.
Request is about… Go to
Authority checks, roles, dedicated vs listen server [Net Roles, Net Modes and Authority]( net roles net modes and authority)
Replicating a variable, OnRep , GetLifetimeReplicatedProps [Property Replication]( property replication)
Who receives a property ( COND ) [Lifetime Conditions]( lifetime conditions)
Cutting per frame comparison cost [Push Model]( push model)
Replicated arrays / inventories [Fast Array Serialization]( fast array serialization)
Server/Client/Multicast calls, validation [Remote Procedure Calls]( remote procedure calls)
SetOwner , relevancy, culling, dormancy [Ownership, Relevancy and Dormancy]( ownership relevancy and dormancy)
Replicating UObject s owned by an actor or component [Subobject Replication]( subobject replication)
Simulated bodies, physics prediction [Physics Replication]( physics replication)
Iris, net.Iris.UseIrisReplication [Iris Replication System]( iris replication system)
50+ connections, spatial relevancy [Replication Graph]( replication graph)
UNetDriver , UNetConnection , disconnect detection [Net Driver and Connections]( net driver and connections)
Worked end to end examples: [replication patterns](references/replication patterns.md). RPC selection tables and verbatim engine RPC declarations: [RPC decision guide](references/rpc decision guide.md).
Net Roles, Net Modes and Authority
ENetRole is declared in Engine/Classes/Engine/EngineTypes.h ; the accessors are on AActor .
From GameFramework/Actor.h :
ENetMode ( Engine/Classes/Engine/EngineBaseTypes.h ): NM Standalone , NM DedicatedServer , NM ListenServer , NM Client . Every mode below NM Client is a server.
Machine GetLocalRole() GetRemoteRole()
Server ROLE Authority ROLE AutonomousProxy or ROLE SimulatedProxy
Owning client ROLE AutonomousProxy ROLE Authority
Other clients ROLE SimulatedProxy ROLE Authority
On a listen server the host is ROLE Authority and locally controlled: use APawn::IsLocallyControlled() to skip host only or client only paths.
Property Replication
Rules:
OnRep must be a UFUNCTION() . Its optional single parameter is the previous value and must match the property type.
Only the authority may write a replicated property. OnRep does not fire on the machine that made the change.
UPROPERTY(NotReplicated) inside a replicated struct excludes a member.
FVector NetQuantize / NetQuantize10 / NetQuantize100 / NetQuantizeNormal ( Engine/NetSerialization.h ) cut world position bandwidth: 0, 1 and 2 decimal places, and 16 bits per component for normals.
FRepMovement ( Engine/Classes/Engine/ReplicatedState.h ) carries location/rotation/velocity when SetReplicateMovement(true) ; override virtual void OnRep ReplicatedMovement() to post process it. UCharacterMovementComponent replicates moves itself — see ue character movement .
On the first bunch for a connection, every eligible property is sent at once. Keep initial state small and push spawn only data behind COND InitialOnly .
Macros ( Net/UnrealNetwork.h ): DOREPLIFETIME , DOREPLIFETIME CONDITION , DOREPLIFETIME CONDITION NOTIFY , DOREPLIFETIME WITH PARAMS , DOREPLIFETIME WITH PARAMS FAST , DOREPLIFETIME WITH PARAMS FAST STATIC ARRAY , DOREPLIFETIME ACTIVE OVERRIDE , DOREPLIFETIME ACTIVE OVERRIDE FAST , DISABLE REPLICATED PROPERTY .
FDoRepLifetimeParams ( Net/UnrealNetwork.h ) is the struct behind the WITH PARAMS forms:
Lifetime Conditions
Full ELifetimeCondition enum, CoreUObject/Public/UObject/CoreNetTypes.h :
Value Sends to
COND None every connection
COND InitialOnly initial bunch only
COND OwnerOnly the actor's owning connection
COND SkipOwner everyone except the owner
COND SimulatedOnly connections where the actor is a simulated proxy
COND AutonomousOnly connections where the actor is an autonomous proxy
COND SimulatedOrPhysics simulated proxies or bRepPhysics actors
COND InitialOrOwner initial bunch, or the owner
COND Custom always eligible; toggled at runtime via the active override macros
COND ReplayOrOwner replay connection or the owner
COND ReplayOnly replay connection only
COND SimulatedOnlyNoReplay simulated proxies, never replay
COND SimulatedOrPhysicsNoReplay simulated or bRepPhysics , never replay
COND SkipReplay everything except the replay connection
COND Dynamic condition is overridden at runtime; replicates until you set one
COND Never never replicated
COND NetGroup subobjects only — connections in the same net condition group
COND NetGroup pairs with UE::Net::FNetConditionGroupManager ( Net/Core/Misc/NetConditionGroupManager.h , module NetCore ), reached through UNetworkSubsystem::GetNetConditionGroupManager() ( Net/Subsystems/NetworkSubsystem.h ):
UE::Net::NetGroupOwner and UE::Net::NetGroupReplay are engine managed groups; do not add a player controller to them. APlayerController also exposes RemoveFromNetConditionGroup , IsMemberOfNetConditionGroup and GetNetConditionGroups .
Push Model
Push model removes the per frame memcmp of replicated properties: the property is only compared when you mark it dirty. It works with the classic net driver and with Iris — it is not an Iris feature.
MARK PROPERTY DIRTY FROM NAME(ClassName, PropertyName, Object) is the preferred marker. Static arrays use MARK PROPERTY DIRTY FROM NAME STATIC ARRAY INDEX(ClassName, PropertyName, ArrayIndex, Object) or MARK PROPERTY DIRTY FROM NAME STATIC ARRAY(ClassName, PropertyName, Object) .
Opt in twice: bWithPushModel = true; in the game/server .Target.cs (defaults to true only for Editor targets, TargetRules.cs:1524 ) and Net.IsPushModelEnabled=1 (defaults to false, PushModel.cpp:434 ). Until both are on, properties are compared as usual.
The macros compile to nothing when WITH PUSH MODEL is off, so the code is always safe to ship (exception: the no push MARK PROPERTY DIRTY FROM NAME STATIC ARRAY stub takes 4 arguments, PushModel.h:489 , so the 3 argument form fails to compile there).
A struct property mutated by reference needs an accessor that marks it dirty before handing out the reference.
With push model enabled, forgetting one marker means the property silently stops replicating — this is the main cost of opting in.
Fast Array Serialization
FFastArraySerializer sends only changed items instead of the whole array.
Item struct derives from FFastArraySerializerItem and may implement any of:
The array struct derives from FFastArraySerializer , implements NetDeltaSerialize via FastArrayDeltaSerialize<ItemType, ArrayType (Items, DeltaParms, this) , and needs TStructOpsTypeTraits<... { WithNetDeltaSerializer = true } . It may also implement the array level receive hook:
FPostReplicatedReceiveParameters::OldArraySize is the size before the update, which makes this the right place for "the whole list changed, rebuild the UI" work.
Dirty rules — both are mandatory, and both are common sources of "my array does not replicate":
MarkItemDirty(Item) after adding or mutating an item.
MarkArrayDirty() after removing an item (it also invalidates the ID map).
Full inventory implementation: [replication patterns, Pattern 3](references/replication patterns.md).
Remote Procedure Calls
UFUNCTION network specifiers ( UObject/ObjectMacros.h ): Server , Client , NetMulticast , Reliable , Unreliable , WithValidation , BlueprintAuthorityOnly , BlueprintCosmetic . Reliable / Unreliable are only valid together with Server , Client or NetMulticast .
You write Implementation bodies; with WithValidation you also write Validate , and returning false disconnects the caller.
Rule Detail
Ownership A Server RPC only routes if the calling client owns the actor through its SetOwner chain up to its APlayerController . Unowned actors drop the call; the only trace is a LogNet Warning "No owning connection for actor…" ( NetDriver.cpp:8274 ).
Client RPC target Needs an actor whose owning connection exists; APlayerController is the reliable choice.
Reliability Reliable for state changes, Unreliable for high frequency cosmetics. Do not send Reliable RPCs every tick: once a channel has more than RELIABLE BUFFER (512, NetConnection.h:82 ) unacked reliable bunches the connection is closed with ReliableBufferOverflow ( DataChannel.cpp:1445 ).
Late joiners Multicasts are not replayed. Persistent state belongs in a replicated property.
Parameters Net addressable types only. A UObject that is neither replicated nor stably named (asset, class, map placed actor) arrives as nullptr ; pass an id and resolve remotely.
Direction Client / NetMulticast called on a client are never sent; they just run locally on that client ( Actor.cpp:5569 5573 , 5587 5592 ). Guard call sites with HasAuthority() .
Decision tables, reliability matrices and verbatim PlayerController.h declarations: [RPC decision guide](references/rpc decision guide.md).
Ownership, Relevancy and Dormancy
Relevancy fields and hooks on AActor :
SetNetCullDistanceSquared() sets the squared radius; NetPriority breaks ties when bandwidth saturates; GetReplayPriority() does the same for replay recording.
Dormancy ( ENetDormancy in EngineTypes.h : DORM Never , DORM Awake , DORM DormantAll , DORM DormantPartial , DORM Initial ):
A waking dormant actor is diffed against the replicator the connection kept when it went dormant ( DataChannel.cpp:2510 2519 ), so normally only changes are sent; an actor whose channel closed on relevancy gets a full initial bunch when it re enters range, which fires its OnRep s again. Write OnRep handlers that tolerate repeats.
Subobject Replication
bReplicateUsingRegisteredSubObjectList defaults to false in 5.8 ( GDefaultUseSubObjectReplicationList = false in Engine/Private/Components/ActorComponent.cpp , project wide CVar net.SubObjects.DefaultUseSubObjectReplicationList ). Opt in per class, or nothing you register replicates:
AActor registration API ( GameFramework/Actor.h ); UActorComponent ( Components/ActorComponent.h ) mirrors all but the ActorComponent variants:
RemoveReplicatedSubObject only stops future updates — the client keeps its copy. Use DestroyReplicatedSubObjectOnRemotePeers to delete it remotely, or TearOffReplicatedSubObjectOnRemotePeers to leave an orphaned local copy. The subobject must override virtual bool IsSupportedForNetworking() const to return true and declare its own GetLifetimeReplicatedProps .
When the flag is false, the engine instead calls the still live virtual:
Inside it, forward to