Loading...
Loading...
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.
npx skill4agent add quodsoler/unreal-engine-skills ue-networking-replication.agents/ue-project-context.mdENetRoleROLE_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 replicatedActor.hENetRole GetLocalRole() const { return Role; } // role on current machine
ENetRole GetRemoteRole() const; // role the other end sees
bool HasAuthority() const { return (GetLocalRole() == ROLE_Authority); }NM_StandaloneNM_DedicatedServerNM_ListenServerNM_Client| Machine | GetLocalRole() | GetRemoteRole() |
|---|---|---|
| Server | ROLE_Authority | ROLE_AutonomousProxy or SimulatedProxy |
| Owning Client | ROLE_AutonomousProxy | ROLE_Authority |
| Other Clients | ROLE_SimulatedProxy | ROLE_Authority |
ROLE_AuthorityIsLocallyControlled()UNetDriverUNetConnectionUWorld::GetNetDriver()UNetDriver* Driver = GetWorld()->GetNetDriver();
// Driver->ClientConnections — all connected clients (server-side)
// Driver->ServerConnection — connection to server (client-side)UNetDriverAMyActor::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
}Actor.hSetReplicatesSetReplicateMovementSetNetUpdateFrequencySetMinNetUpdateFrequencySetNetCullDistanceSquaredENGINE_APIbReplicateMovement = trueFRepMovementActor.hUCharacterMovementComponentFSavedMove_CharacterSetReplicateMovement(false)UPROPERTY(Replicated)
int32 Health;
UPROPERTY(ReplicatedUsing = OnRep_State)
EMyState State;
UFUNCTION()
void OnRep_State(EMyState PreviousState); // old value passed as optional parameter// 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);
}COND_NoneCOND_OwnerOnlyCOND_SkipOwnerCOND_SimulatedOnlyCOND_AutonomousOnlyCOND_InitialOnlyCOND_CustomCOND_OwnerOnlyCOND_InitialOnlyCOND_InitialOnlyCOND_InitialOnlyFRepLayoutDOREPLIFETIME_CONDITIONFRepLayoutDOREPLIFETIME_WITH_PARAMS_FASTbIsPushBasedTArrayFFastArraySerializerreferences/replication-patterns.mdNetSerializeUSTRUCTTStructOpsTypeTraitsWithNetSerializer = trueFVector_NetQuantize10FVectorreferences/rpc-decision-guide.md// 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);_Implementation_ValidatefalsePlayerController.hUFUNCTION(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);APlayerControllerNetConnectionint32floatFStringFVectorUObject*nullptrUSTRUCT(BlueprintType)UObject*nullptrTArrayTMap// Server sets owner to control connection routing for RPCs and COND_OwnerOnly
Weapon->SetOwner(PlayerController);
// Relevancy flags (from Actor.h)
bAlwaysRelevant = true; // replicate to every connection
bOnlyRelevantToOwner = true; // replicate only to the owning connection
// Override for custom logic (e.g., team-based relevancy)
virtual bool IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget,
const FVector& SrcLocation) const override;NetCullDistanceSquaredNetPrioritySetNetDormancy(DORM_DormantAll); // stop replication
FlushNetDormancy(); // send one update then return to dormantNetCullDistanceSquaredOnRep_OnRep_DORM_DormantAllActor.hENGINE_API void AddReplicatedSubObject(UObject* SubObject,
ELifetimeCondition NetCondition = COND_None);
ENGINE_API void RemoveReplicatedSubObject(UObject* SubObject);
ENGINE_API void AddActorComponentReplicatedSubObject(UActorComponent* OwnerComponent,
UObject* SubObject,
ELifetimeCondition NetCondition = COND_None);bReplicateUsingRegisteredSubObjectList = trueAddReplicatedSubObjectBeginPlayRemoveReplicatedSubObjectEndPlayReplicateSubobjectsbReplicateUsingRegisteredSubObjectList = falsebool AMyActor::ReplicateSubobjects(UActorChannel* Channel,
FOutBunch* Bunch, FReplicationFlags* RepFlags)
{
bool bWrote = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
bWrote |= Channel->ReplicateSubobject(MySubObject, *Bunch, *RepFlags);
return bWrote;
}// 1. Client predicts immediately
void AMyCharacter::LocalPredictAbility(int32 AbilityId)
{
if (IsLocallyControlled())
{
ApplyAbilityEffectLocal(AbilityId); // immediate visual/audio
ServerActivateAbility(AbilityId); // request server confirmation
}
}
// 2. Server validates, broadcasts, or corrects
void AMyCharacter::ServerActivateAbility_Implementation(int32 AbilityId)
{
if (CanActivateAbility(AbilityId))
{
ApplyAbilityEffectAuthority(AbilityId);
MulticastAbilityActivated(AbilityId);
}
else
{
ClientCorrectionAbilityFailed(AbilityId); // roll back client prediction
}
}UCharacterMovementComponentNetworkSmoothingModeLinearExponentialDisabledFSavedMove_CharacterPhysCustomUCharacterMovementComponentUAbilitySystemComponentFPredictionKeyUPROPERTY(Replicated)OnRep_FPredictionKeyFPredictionKey::CreateNewPredictionKeyGameplayEffectGameplayEffectFPredictionKeyUAbilitySystemComponent::TryActivateAbilityUGameplayAbilityFScopedPredictionWindowue-gameplay-abilities[ ] bReplicates = true in constructor
[ ] SetNetUpdateFrequency / SetMinNetUpdateFrequency set appropriately
[ ] All UPROPERTY(Replicated) / UPROPERTY(ReplicatedUsing=...) declared
[ ] GetLifetimeReplicatedProps overridden; Super called first
[ ] DOREPLIFETIME / DOREPLIFETIME_CONDITION for each property
[ ] OnRep_ functions declared UFUNCTION() and implemented
[ ] Server RPCs have WithValidation; _Validate implemented
[ ] NetMulticast / Client RPCs guarded with HasAuthority() on call site
[ ] Subobjects registered via AddReplicatedSubObject or ReplicateSubobjects
[ ] SetOwner() called on server after spawning owned actors
[ ] DORM_DormantAll set on actors that rarely updateUReplicationGraph// Build.cs: "ReplicationGraph"
// Project: set ReplicationDriverClassName in DefaultEngine.ini
// [/Script/OnlineSubsystemUtils.IpNetDriver]
// ReplicationDriverClassName=/Script/MyGame.MyReplicationGraph
UCLASS()
class UMyReplicationGraph : public UReplicationGraph
{
GENERATED_BODY()
public:
virtual void InitGlobalActorClassSettings() override;
virtual void InitGlobalGraphNodes() override;
virtual void InitConnectionGraphNodes(UNetReplicationGraphConnection* RepGraphConnection) override;
};UReplicationGraphNode_GridSpatialization2DUReplicationGraphNode_AlwaysRelevantUReplicationGraphNode_AlwaysRelevant_ForConnectionUReplicationGraphNode_ActorList| Mistake | Fix |
|---|---|
Modifying state without | Add |
Server RPC without | Add |
Calling | Only call from server; guard with |
Plain | Use |
Omitting | Always call |
Passing non-replicated | Pass an ID; look up object on remote side |
Using | Use |
| Replicating cosmetic-only properties — increases bandwidth for data clients can compute locally | Only replicate gameplay-critical state; derive visuals client-side |
APlayerControllerAPawnAPlayerStatePlayerController.h// nullptr on local players (server-side); points to the network connection otherwise
UPROPERTY(DuplicateTransient)
TObjectPtr<UNetConnection> NetConnection;UNetConnectionUNetDriverAPlayerController::GetNetConnection()COND_OwnerOnlyAGameModeBase::OnLogoutNetConnection->GetConnectionState() == USOCK_ClosedIsClosingOrClosed()NetConnectionAPlayerControllerAPawnAPlayerStateue-gameplay-frameworkue-gameplay-abilitiesue-cpp-foundationsreferences/replication-patterns.mdreferences/rpc-decision-guide.md