# Unreal Engine 5.7 — Networking Module Reference **Last verified:** 2026-02-13 **Knowledge Gap:** UE 5.7 networking improvements --- ## Overview UE 5.7 networking: - **Client-Server Architecture**: Server-authoritative (RECOMMENDED) - **Replication**: Automatic state synchronization - **RPCs (Remote Procedure Calls)**: Call functions across network - **Relevancy**: Optimize bandwidth by only replicating relevant actors --- ## Basic Multiplayer Setup ### Enable Replication on Actor ```cpp UCLASS() class AMyActor : public AActor { GENERATED_BODY() public: AMyActor() { // ✅ Enable replication bReplicates = true; bAlwaysRelevant = true; // Always replicate to all clients } }; ``` ### Network Role Checks ```cpp // Check role if (HasAuthority()) { // Running on server } if (GetLocalRole() == ROLE_AutonomousProxy) { // This is the owning client (local player) } if (GetRemoteRole() == ROLE_SimulatedProxy) { // This is a remote client (other players) } ``` --- ## Replicated Variables ### Basic Replication ```cpp UPROPERTY(Replicated) int32 Health; UPROPERTY(Replicated) FVector Position; // ✅ Implement GetLifetimeReplicatedProps void AMyActor::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AMyActor, Health); DOREPLIFETIME(AMyActor, Position); } ``` ### Conditional Replication ```cpp // Only replicate to owner DOREPLIFETIME_CONDITION(AMyCharacter, Ammo, COND_OwnerOnly); // Skip owner (replicate to everyone else) DOREPLIFETIME_CONDITION(AMyCharacter, TeamID, COND_SkipOwner); // Only when changed DOREPLIFETIME_CONDITION(AMyCharacter, Score, COND_InitialOnly); ``` ### RepNotify (Callback on Replication) ```cpp UPROPERTY(ReplicatedUsing=OnRep_Health) int32 Health; UFUNCTION() void OnRep_Health() { // Called on clients when Health changes UpdateHealthUI(); } // Implement GetLifetimeReplicatedProps (same as above) ``` --- ## RPCs (Remote Procedure Calls) ### Server RPC (Client → Server) ```cpp // Client calls, server executes UFUNCTION(Server, Reliable) void Server_TakeDamage(int32 Damage); void AMyCharacter::Server_TakeDamage_Implementation(int32 Damage) { // Runs on server only Health -= Damage; if (Health <= 0) { Server_Die(); } } bool AMyCharacter::Server_TakeDamage_Validate(int32 Damage) { // Validate input (anti-cheat) return Damage >= 0 && Damage <= 100; } ``` ### Client RPC (Server → Client) ```cpp // Server calls, client executes UFUNCTION(Client, Reliable) void Client_ShowDeathScreen(); void AMyCharacter::Client_ShowDeathScreen_Implementation() { // Runs on client only ShowDeathUI(); } ``` ### Multicast RPC (Server → All Clients) ```cpp // Server calls, all clients execute UFUNCTION(NetMulticast, Reliable) void Multicast_PlayExplosion(FVector Location); void AMyActor::Multicast_PlayExplosion_Implementation(FVector Location) { // Runs on server and all clients UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ExplosionEffect, Location); } ``` ### RPC Reliability ```cpp // Reliable: Guaranteed delivery (important events) UFUNCTION(Server, Reliable) void Server_FireWeapon(); // Unreliable: Best-effort delivery (frequent updates, position sync) UFUNCTION(Server, Unreliable) void Server_UpdateAim(FRotator AimRotation); ``` --- ## Server-Authoritative Pattern (RECOMMENDED) ### Movement Example ```cpp class AMyCharacter : public ACharacter { UPROPERTY(Replicated) FVector ServerPosition; void Tick(float DeltaTime) override { Super::Tick(DeltaTime); if (GetLocalRole() == ROLE_AutonomousProxy) { // Client: Send input to server FVector Input = GetMovementInput(); Server_Move(Input); // Client-side prediction (move locally) AddMovementInput(Input); } if (HasAuthority()) { // Server: Authoritative position ServerPosition = GetActorLocation(); } else { // Client: Interpolate toward server position FVector NewPos = FMath::VInterpTo(GetActorLocation(), ServerPosition, DeltaTime, 5.0f); SetActorLocation(NewPos); } } UFUNCTION(Server, Unreliable) void Server_Move(FVector Input); void Server_Move_Implementation(FVector Input) { // Server validates and applies movement AddMovementInput(Input); } }; ``` --- ## Network Relevancy (Bandwidth Optimization) ### Custom Relevancy ```cpp bool AMyActor::IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation) const { // Only replicate if within range float Distance = FVector::Dist(SrcLocation, GetActorLocation()); return Distance < 5000.0f; } ``` ### Always Relevant Actors ```cpp AMyActor() { bAlwaysRelevant = true; // Replicate to all clients (e.g., GameState, PlayerController) bOnlyRelevantToOwner = true; // Only replicate to owner (e.g., PlayerController) } ``` --- ## Ownership ### Set Owner ```cpp // Assign owner (important for RPCs and relevancy) MyActor->SetOwner(OwningPlayerController); ``` ### Check Owner ```cpp if (GetOwner() == PlayerController) { // This actor is owned by this player } ``` --- ## Game Mode & Game State ### Game Mode (Server Only) ```cpp UCLASS() class AMyGameMode : public AGameMode { GENERATED_BODY() public: // Game mode only exists on server // Use for server-side logic (spawning, scoring, rules) }; ``` ### Game State (Replicated to All Clients) ```cpp UCLASS() class AMyGameState : public AGameState { GENERATED_BODY() public: // ✅ Replicate game state to all clients UPROPERTY(Replicated) int32 RedTeamScore; UPROPERTY(Replicated) int32 BlueTeamScore; virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AMyGameState, RedTeamScore); DOREPLIFETIME(AMyGameState, BlueTeamScore); } }; ``` --- ## Player Controller & Player State ### Player Controller (One per Player) ```cpp UCLASS() class AMyPlayerController : public APlayerController { GENERATED_BODY() public: // Exists on server and owning client // Use for player-specific logic, input handling }; ``` ### Player State (Replicated Player Info) ```cpp UCLASS() class AMyPlayerState : public APlayerState { GENERATED_BODY() public: UPROPERTY(Replicated) int32 Kills; UPROPERTY(Replicated) int32 Deaths; virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(AMyPlayerState, Kills); DOREPLIFETIME(AMyPlayerState, Deaths); } }; ``` --- ## Sessions & Matchmaking ### Create Session ```cpp #include "OnlineSubsystem.h" #include "OnlineSessionSettings.h" void CreateSession() { IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(); IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface(); TSharedPtr SessionSettings = MakeShareable(new FOnlineSessionSettings()); SessionSettings->bIsLANMatch = false; SessionSettings->NumPublicConnections = 4; SessionSettings->bShouldAdvertise = true; Sessions->CreateSession(0, FName("MySession"), *SessionSettings); } ``` ### Find Sessions ```cpp void FindSessions() { IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get(); IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface(); TSharedRef SearchSettings = MakeShareable(new FOnlineSessionSearch()); SearchSettings->bIsLanQuery = false; SearchSettings->MaxSearchResults = 20; Sessions->FindSessions(0, SearchSettings); } ``` --- ## Performance Tips ### Reduce Bandwidth ```cpp // Use unreliable RPCs for frequent updates UFUNCTION(Server, Unreliable) void Server_UpdatePosition(FVector Pos); // Conditional replication (only replicate to relevant clients) DOREPLIFETIME_CONDITION(AMyActor, Health, COND_OwnerOnly); // Limit replication frequency SetReplicationFrequency(10.0f); // Update 10 times per second (default 100) ``` --- ## Debugging ### Network Debugging ```cpp // Console commands: // stat net - Show network stats // stat netplayerupdate - Show player update stats // NetEmulation PktLoss=10 - Simulate 10% packet loss // NetEmulation PktLag=100 - Simulate 100ms latency // Draw debug for replication: UE_LOG(LogNet, Warning, TEXT("Replicating Health: %d"), Health); ``` --- ## Sources - https://docs.unrealengine.com/5.7/en-US/networking-and-multiplayer-in-unreal-engine/ - https://docs.unrealengine.com/5.7/en-US/actor-replication-in-unreal-engine/ - https://docs.unrealengine.com/5.7/en-US/rpcs-in-unreal-engine/