$npx -y skills add quodsoler/unreal-engine-skills --skill ue-networking-replicationUse 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/replic
| 1 | # UE Networking & Replication |
| 2 | |
| 3 | You are an expert in Unreal Engine's networking and replication systems. |
| 4 | |
| 5 | ## Context Check |
| 6 | |
| 7 | Read `.agents/ue-project-context.md` for this project's multiplayer configuration. |
| 8 | Look for: server topology (dedicated, listen, P2P), player count, replicated classes, |
| 9 | and any custom net drivers. |
| 10 | |
| 11 | If the context file is absent, ask: |
| 12 | 1. Server topology? (dedicated, listen, P2P) |
| 13 | 2. Maximum player count per session? |
| 14 | 3. Which actors or components need to replicate data? |
| 15 | 4. Are you using Gameplay Ability System (GAS)? |
| 16 | |
| 17 | --- |
| 18 | |
| 19 | ## Net Roles and Authority |
| 20 | |
| 21 | UE uses a server-authoritative model: the server is the source of truth for game state. |
| 22 | Clients predict locally and reconcile with server corrections. |
| 23 | |
| 24 | Every actor on every machine has a local role and a remote role (`ENetRole`). |
| 25 | |
| 26 | ``` |
| 27 | ROLE_Authority — owns and can modify this actor (server for replicated actors) |
| 28 | ROLE_AutonomousProxy — client copy of the locally controlled pawn |
| 29 | ROLE_SimulatedProxy — client copy of another player's actor; engine interpolates state |
| 30 | ROLE_None — not replicated |
| 31 | ``` |
| 32 | |
| 33 | From `Actor.h`: |
| 34 | ```cpp |
| 35 | ENetRole GetLocalRole() const { return Role; } // role on current machine |
| 36 | ENetRole GetRemoteRole() const; // role the other end sees |
| 37 | bool HasAuthority() const { return (GetLocalRole() == ROLE_Authority); } |
| 38 | ``` |
| 39 | |
| 40 | Net modes: `NM_Standalone`, `NM_DedicatedServer`, `NM_ListenServer`, `NM_Client`. |
| 41 | |
| 42 | **Role matrix for a replicated Pawn:** |
| 43 | |
| 44 | | Machine | GetLocalRole() | GetRemoteRole() | |
| 45 | |----------------|----------------------|-----------------------------------------| |
| 46 | | Server | ROLE_Authority | ROLE_AutonomousProxy or SimulatedProxy | |
| 47 | | Owning Client | ROLE_AutonomousProxy | ROLE_Authority | |
| 48 | | Other Clients | ROLE_SimulatedProxy | ROLE_Authority | |
| 49 | |
| 50 | **Listen-server caveat:** the host is both `ROLE_Authority` and locally controlled. |
| 51 | Use `IsLocallyControlled()` to distinguish logic that should skip the host player. |
| 52 | |
| 53 | --- |
| 54 | |
| 55 | ## UNetDriver |
| 56 | |
| 57 | `UNetDriver` is the core transport class responsible for managing all network connections and |
| 58 | packet delivery for a world. It owns the list of `UNetConnection` objects and drives the |
| 59 | replication tick. Access it via `UWorld::GetNetDriver()`. |
| 60 | |
| 61 | ```cpp |
| 62 | UNetDriver* Driver = GetWorld()->GetNetDriver(); |
| 63 | // Driver->ClientConnections — all connected clients (server-side) |
| 64 | // Driver->ServerConnection — connection to server (client-side) |
| 65 | ``` |
| 66 | |
| 67 | For most gameplay code you never interact with `UNetDriver` directly; it is relevant when |
| 68 | writing custom net drivers, profiling connection state, or debugging packet loss. |
| 69 | |
| 70 | --- |
| 71 | |
| 72 | ## Property Replication |
| 73 | |
| 74 | ### Actor Setup |
| 75 | |
| 76 | ```cpp |
| 77 | AMyActor::AMyActor() |
| 78 | { |
| 79 | bReplicates = true; // AActor::SetReplicates() also available at runtime |
| 80 | SetReplicateMovement(true); // replicates FRepMovement (location/rotation/velocity) |
| 81 | SetNetUpdateFrequency(10.f); // checks per second |
| 82 | SetMinNetUpdateFrequency(2.f); // floor when nothing changes |
| 83 | NetPriority = 1.0f; // higher = preferred when bandwidth is saturated |
| 84 | } |
| 85 | ``` |
| 86 | |
| 87 | From `Actor.h`: `SetReplicates`, `SetReplicateMovement`, `SetNetUpdateFrequency`, |
| 88 | `SetMinNetUpdateFrequency`, and `SetNetCullDistanceSquared` are all `ENGINE_API`. |
| 89 | |
| 90 | **FRepMovement:** when `bReplicateMovement = true`, the engine serializes position, |
| 91 | velocity, and rotation into an `FRepMovement` struct (declared in `Actor.h`) and |
| 92 | sends it to simulated proxies. `UCharacterMovementComponent` bypasses this with its |
| 93 | own prediction-based replication; it writes compressed moves via `FSavedMove_Character` |
| 94 | and reconciles them server-side, so `SetReplicateMovement(false)` is the correct |
| 95 | default for characters using CMC. |
| 96 | |
| 97 | ### Declaring Properties |
| 98 | |
| 99 | ```cpp |
| 100 | UPROPERTY(Replicated) |
| 101 | int32 Health; |
| 102 | |
| 103 | UPROPERTY(ReplicatedUsing = OnRep_State) |
| 104 | EMyState State; |
| 105 | |
| 106 | UFUNCTION() |
| 107 | void OnRep_State(EMyState PreviousState); // old value passed as optional parameter |
| 108 | ``` |
| 109 | |
| 110 | ### GetLifetimeReplicatedProps |
| 111 | |
| 112 | ```cpp |
| 113 | // MyActor.cpp |
| 114 | #include "Net/UnrealNetwork.h" |
| 115 | |
| 116 | void AMyActor::GetLifetimeReplicatedProps( |
| 117 | TArray<FLifetimeProperty>& OutLifetimeProps) const |
| 118 | { |
| 119 | Super::GetLifetimeReplicatedProps(OutLifetimeProps); // NEVER omit this |
| 120 | DOREPLIFETIME(AMyActor, Health); |
| 121 | DOREPLIFETIME_CONDITION(AMyActor, State, COND_OwnerOnly); |
| 122 | DOREPLIFETIME_CONDITION(AMyActor, SimData, COND_SimulatedOnly); |
| 123 | DOREPLIFETIME_CONDITION(AMyActor, Ini |