How do you debug replication issues in an Unreal Engine project?
Enemy positions "teleport" and the health bar lags behind, but only in a real networked game — in PIE on the dev machine everything is smooth. You add latency in PIE with Net PktLag/PktLoss and read the network debug tools:
PIE clean local net: smooth, no desync
Net PktLag=120 PktLoss=5: enemy snaps/teleports, health bar lags
showdebug net: enemy actor present, NetUpdateFrequency low
Net.DumpRelevantActors 1: enemy IS in the relevant list for the client
Authority log: "Enemy SetHealth on SERVER" (state written on server)
Diagnose the cause.
Reproduce in PIE multi-client, then use Net PktLag/PktLoss to simulate bad networks, the showdebug net overlay, Net.DumpRelevantActors, and authority logging to confirm which machine writes state and whether the property is registered.
- ✗Testing only on a perfect local network with zero latency or loss
- ✗Debugging on one machine and assuming the server side behaves identically
- ✗Never checking whether the property is actually registered for replication
- →What does
Net PktLagreveal that a clean local test cannot? - →How do you confirm a property is registered without reading the source?
Scenario
Players complain that enemy positions "teleport" and the health bar sometimes lags behind. On the developer's machine in PIE everything is smooth — the bug shows up only in a real networked game.
Symptom vs cause
Smooth locally, bad over the network is the classic sign that the bug is hidden by PIE's zero latency. A perfect local network masks packet loss, jitter, and ordering problems.
Debugging tools
1. Reproduce a real network
Net PktLag=120 // artificial latency, ms
Net PktLagVariance=40
Net PktLoss=5 // packet loss, %
These console commands in PIE recreate the conditions that surface the bug.
2. Network overlay
showdebug net
Shows replicated actors, their update frequency, and per-connection load right on screen.
3. Relevancy dump
Net.DumpRelevantActors 1
Confirms whether the problem actor replicates to a given client at all — if it is missing from the list, relevancy or dormancy is the cause.
4. Authority logging
UE_LOG(LogTemp, Warning, TEXT("%s SetHealth on %s"),
*GetName(),
HasAuthority() ? TEXT("SERVER") : TEXT("CLIENT"));
Confirms state is written on the server, not the client.
5. Registration check
- Is the property marked
Replicated/ReplicatedUsing? - Is there a
DOREPLIFETIMEinGetLifetimeReplicatedProps? - Was
Super::GetLifetimeReplicatedPropscalled?
Typical outcome
The enemy "teleport" is a correction: the client predicted movement while the server's authoritative update arrived late and snapped the position. The fix is smoothing the interpolation and checking NetUpdateFrequency.