quodsoler/unreal-engine-skills3 files

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 for common patterns and references/rpc-decision-guide.md for RPC type selection. For GAS networking, see ue-gameplay-abilities.

Specification
Skill ID
quodsoler/unreal-engine-skills/ue-networking-replication
Publisher
quodsoler
Repository
unreal-engine-skills
Installs
0
Files
3
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

quodsoler/unreal-engine-skills/ue-networking-replicationInstalls these files
  • SKILL.md
  • references/replication-patterns.md
  • references/rpc-decision-guide.md

What this skill tells the agent

UE Networking & Replication

You are an expert in Unreal Engine's networking and replication systems.

Context Check

Read .agents/ue-project-context.md for this project's multiplayer configuration. Look for: server topology (dedicated, listen, P2P), player count, replicated classes, and any custom net drivers.

If the context file is absent, ask:

  1. Server topology? (dedicated, listen, P2P)
  2. Maximum player count per session?
  3. Which actors or components need to replicate data?
  4. Are you using Gameplay Ability System (GAS)?

Net Roles and Authority

UE uses a server-authoritative model: the server is the source of truth for game state. Clients predict locally and reconcile with server corrections.

Every actor on every machine has a local role and a remote role (ENetRole).

ROLE_Authority       — owns and can modify this actor (server for replicated actors)
ROLE_AutonomousProxy — client copy of the locally controlled pawn
ROLE_SimulatedProxy  — client copy of another player's actor; engine interpolates state
ROLE_None            — not replicated

From Actor.h:

ENetRole GetLocalRole() const { return Role; }   // role on current machine
ENetRole GetRemoteRole() const;                   // role the other end sees
bool HasAuthority() const { return (GetLocalRole() == ROLE_Authority); }

Net modes: NM_Standalone, NM_DedicatedServer, NM_ListenServer, NM_Client.

Role matrix for a replicated Pawn:

MachineGetLocalRole()GetRemoteRole()
ServerROLE_AuthorityROLE_AutonomousProxy or SimulatedProxy
Owning ClientROLE_AutonomousProxyROLE_Authority
Other ClientsROLE_SimulatedProxyROLE_Authority

Listen-server caveat: the host is both ROLE_Authority and locally controlled. Use IsLocallyControlled() to distinguish logic that should skip the host player.


UNetDriver

UNetDriver is the core transport class responsible for managing all network connections and packet delivery for a world. It owns the list of UNetConnection objects and drives the replication tick. Access it via UWorld::GetNetDriver().

UNetDriver* Driver = GetWorld()->GetNetDriver();
// Driver->ClientConnections  — all connected clients (server-side)
// Driver->ServerConnection   — connection to server (client-side)

For most gameplay code you never interact with UNetDriver directly; it is relevant when writing custom net drivers, profiling connection state, or debugging packet loss.


Property Replication

Actor Setup

AMyActor::AMyActor()
{
    bReplicates = true;             // AActor::SetReplicates() also available at runtime
    SetReplicateMovement(true);     // replicates FRepMovement (location/rotation/velocity)
    SetNetUpdateFrequency(10.f);    // checks per second
    SetMinNetUpdateFrequency(2.f);  // floor when nothing changes
    NetPriority = 1.0f;            // higher = preferred when bandwidth is saturated
}

From Actor.h: SetReplicates, SetReplicateMovement, SetNetUpdateFrequency, SetMinNetUpdateFrequency, and SetNetCullDistanceSquared are all ENGINE_API.

FRepMovement: when bReplicateMovement = true, the engine serializes position, velocity, and rotation into an FRepMovement struct (declared in Actor.h) and sends it to simulated proxies. UCharacterMovementComponent bypasses this with its own prediction-based replication; it writes compressed moves via FSavedMove_Character and reconciles them server-side, so SetReplicateMovement(false) is the correct default for characters using CMC.

Declaring Properties

UPROPERTY(Replicated)
int32 Health;

UPROPERTY(ReplicatedUsing = OnRep_State)
EMyState State;

UFUNCTION()
void OnRep_State(EMyState PreviousState); // old value passed as optional parameter

GetLifetimeReplicatedProps

// MyActor.cpp
#include "Net/UnrealNetwork.h"

void AMyActor::GetLifetimeReplicatedProps(
    TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps); // NEVER omit this
    DOREPLIFETIME(AMyActor, Health);
    DOREPLIFETIME_CONDITION(AMyActor, State,        COND_OwnerOnly);
    DOREPLIFETIME_CONDITION(AMyActor, SimData,      COND_SimulatedOnly);
    DOREPLIFETIME_CONDITION(AMyActor, InitData,     COND_InitialOnly);
    DOREPLIFETIME_CONDITION(AMyActor, PublicData,   COND_SkipOwner);
}

Conditions: COND_None (all), COND_OwnerOnly, COND_SkipOwner, COND_SimulatedOnly, COND_AutonomousOnly, COND_InitialOnly, COND_Custom.

Use COND_OwnerOnly for private player data (inventory, currency). Use COND_InitialOnly for immutable spawn data (team, character class).

Initial replication burst: When a client first joins or an actor first becomes relevant, ALL replicated properties send at once regardless of conditions (COND_InitialOnly fires exactly once here). This burst can saturate the actor channel — keep initial state compact and use COND_InitialOnly for spawn-time-only data to reduce ongoing bandwidth.

FRepLayout (Internal)

FRepLayout is an internal engine struct that describes which properties of a class are replicated and how. It handles delta compression (only changed properties are sent) and evaluates DOREPLIFETIME_CONDITION filters per-connection. Developers rarely interact with FRepLayout directly, but knowing it exists helps when debugging why a property is or is not replicating: the layout is built once per class and cached, so dynamic changes to conditions require DOREPLIFETIME_WITH_PARAMS_FAST or bIsPushBased patterns rather than modifying the struct at runtime.

Large Arrays: FFastArraySerializer

Plain TArray sends the full array on any change. Use FFastArraySerializer for delta-only replication. See references/replication-patterns.md Pattern 3 for a complete inventory implementation.

Custom Struct Serialization

Implement NetSerialize on a USTRUCT and add TStructOpsTypeTraits with WithNetSerializer = true to control binary layout manually. Use FVector_NetQuantize10 (0.1 cm precision) instead of raw FVector to halve position bandwidth.


Remote Procedure Calls (RPCs)

See references/rpc-decision-guide.md for the full decision flowchart.

// Client calls → server executes. WithValidation is required for state changes.
UFUNCTION(Server, Reliable, WithValidation)
void ServerFireWeapon(FVector_NetQuantize Origin, FVector_NetQuantizeNormal Dir);

// Server calls → owning client executes. No WithValidation needed.
UFUNCTION(Client, Reliable)
void ClientShowKillConfirm();

// Server calls → server + all clients execute.
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayHitEffect(FVector ImpactPoint);

Implementations always end in _Implementation. Server RPCs with validation also need _Validate (return false to kick the client).

Reliable — guaranteed delivery; use for state-changing actions (purchase, spawn, possession). Unreliable — fire-and-forget; use for high-frequency cosmetics.

Real examples from PlayerController.h:

UFUNCTION(unreliable, server, WithValidation) void ServerSetSpectatorLocation(...);
UFUNCTION(reliable,   server, WithValidation) void ServerAcknowledgePossession(APawn* P);
UFUNCTION(Reliable,   Client)                 void ClientReceiveLocalizedMessage(...);
UFUNCTION(Client,     Unreliable)             void ClientAckTimeDilation(float, int32);

RPC ownership: Server RPCs must be called on an actor whose ownership chain leads to the calling client's APlayerController. Client RPCs must be called on an actor owned by a player with a NetConnection. Calls on unowned actors are silently dropped.

RPC Parameter Rules: Only net-addressable types are valid — basic types (int32,

Use this skill in a project

Open any RiverX project, search the Skills panel for quodsoler/unreal-engine-skills/ue-networking-replication, and install it in one click.

Use this skill