Immutable. This exact content is served forever at /api/v1/blob/f6667e5b169b7348.
---
name: unreal-multiplayer
group: Unreal
description: >-
Build Actor replication, GameMode/GameState architecture and server-authoritative gameplay. Use
when building Unreal networking, actor replication, or RPCs.
---
# unreal-multiplayer
## Core Philosophy
Unreal Engine was built from its inception in 1998 as a multiplayer tournament engine. Networking in Unreal is deeply opinionated: it centers around a strict **Server-Authoritative Client-Server architecture** orchestrated by the GameMode, GameState, PlayerState, and PlayerController classes. The server runs the definitive physical simulation; clients are visual and audio playback terminals that send player intent. Master Unreal multiplayer by understanding the Actor Replication lifecycle, property replication with `DOREPLIFETIME`, and the strict division between Multicast, Client, and Server RPCs.
---
## 4-Step Unreal Multiplayer Architecture
### Step 1: The Core Gameplay Framework Classes
1. **GameMode (Server Only)**:
- Exists exclusively on the authoritative server. Defines match rules, win conditions, player spawning (`SpawnDefaultPawnAtTransform`), and score tracking. Never replicated to clients.
2. **GameState (Server $\to$ All Clients)**:
- Replicated to all machines. Tracks match state (Round time, Team scores, Match phase: *WaitingToStart, InProgress, PostMatch*).
3. **PlayerState (Server $\to$ All Clients)**:
- Replicated to all machines. Tracks individual player attributes (Player Name, Ping, Kills, Current Score).
4. **PlayerController (Server $\leftrightarrow$ Owning Client)**:
- Exists on the server and the *specific owning client*. Handles input translation, UI HUD management, and secure Server RPC communication.
### Step 2: Actor & Property Replication (`DOREPLIFETIME`)
1. **Actor Replication Setup**:
- `bReplicates = true` in constructor.
- `SetReplicateMovement(true)` for physical actors.
2. **Replicated Properties (`ReplicatedUsing`)**:
- Replicate variables using `UPROPERTY(ReplicatedUsing = OnRep_Health)`.
- Implement `GetLifetimeReplicatedProps`:
```cpp
void ACharacterBase::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(ACharacterBase, Health);
DOREPLIFETIME_CONDITION(ACharacterBase, SecretInventory, COND_OwnerOnly);
}
```
3. **RepNotify Functions**:
- `OnRep_Health()` executes automatically on clients whenever the server updates `Health`.
### Step 3: Remote Procedure Call (RPC) Classification
1. **Server RPC (`Server, Reliable, WithValidation`)**:
- Called by Owning Client $\to$ Executed on Server.
- Must implement `_Validate` (Security gate) and `_Implementation`:
```cpp
bool AWeapon::ServerFire_Validate(FVector AimDir) { return AimDir.IsNormalized(); }
void AWeapon::ServerFire_Implementation(FVector AimDir) { /* Authoritative Fire */ }
```
2. **Client RPC (`Client, Reliable`)**:
- Called by Server $\to$ Executed on Owning Client only (e.g. *ClientShowHitMarker*).
3. **NetMulticast RPC (`NetMulticast, Unreliable`)**:
- Called by Server $\to$ Executed on Server and *all* simulated clients (e.g. *MulticastPlayExplosionFX*).
### Step 4: Network Relevancy & Dormancy Optimization
1. **Network Relevancy (`IsNetRelevantFor`)**:
- Actors beyond view distance or hidden behind terrain are not replicated to distant clients, conserving network bandwidth.
2. **Net Dormancy (`DORM_DormantAll`)**:
- Static or rarely changing world actors (chests, switches) are set dormant until an event wakes them up, saving server tick budget.
---
## Deliverable Format: Authoritative Server-Validated Weapon Firing (C++)
```cpp
// Weapon.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Weapon.generated.h"
UCLASS()
class AWeapon : public AActor {
GENERATED_BODY()
public:
AWeapon();
UPROPERTY(ReplicatedUsing = OnRep_AmmoCount, BlueprintReadOnly)
int32 AmmoCount;
UFUNCTION()
void OnRep_AmmoCount();
UFUNCTION(Server, Reliable, WithValidation)
void ServerFire(FVector_NetQuantize TraceStart, FVector_NetQuantizeNormal AimDir);
UFUNCTION(NetMulticast, Unreliable)
void MulticastSpawnMuzzleFX();
protected:
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
};
```
---
## Worked Example: Mitigating Dedicated Server Bandwidth Saturation
- **Context**: A 32-player Unreal shooter was experiencing severe packet drops and server tick degradation down to 14 Hz during firefights.
- **Diagnosis**: Using `NetProfile` and `Network Insights`, engineers discovered weapon firing was using `Reliable` NetMulticast RPCs and replicating unquantized 64-bit vector coordinates 30 times per second.
- **Optimization**:
1. Converted `FVector` to `FVector_NetQuantize` (16-bit integer compression).
2. Changed cosmetic FX RPCs from `Reliable` to `Unreliable`.
3. Activated Net Dormancy on 800 static interactive loot containers in the map.
- **Outcome**: Server bandwidth per client decreased by 68%; server tick rate stabilized at 60 Hz.
---
## Verification Checklist
- [ ] GameMode contains zero client-side logic and is never accessed from client HUDs.
- [ ] All Server RPCs implement `_Validate()` security checks to prevent packet injection.
- [ ] `DOREPLIFETIME_CONDITION` used to prevent sending private data (e.g. inventory) to non-owners.
- [ ] Cosmetic effects transmitted via `Unreliable` Multicast RPCs.
- [ ] Net Relevancy distance and Net Dormancy configured for large maps.
---
## Anti-Patterns
- **Calling Server RPCs on Un-Owned Actors**: Invoking a Server RPC from a client on an Actor that is not possessed or owned by that client's PlayerController (fails silently).
- **Using Reliable RPCs for Frequent Ticks**: Marking high-frequency weapon fire or footstep RPCs as `Reliable`, causing TCP-style packet queues when latency spikes.
- **Accessing `AGameMode` on Clients**: Writing `GetWorld()->GetAuthGameMode()` inside client UI widgets, which returns `nullptr` on non-server machines.