Guide

Game remote entity interpolation and snapshot smoothing systems explained

Harbor Vanguard launched team deathmatch with a 20 Hz authoritative server and correct client-side prediction for the local player. Remote enemies still looked broken: they teleported between tick positions, feet slid on strafes, and peeking players appeared a full server tick ahead of where bullets registered. Telemetry tagged 58% of matches with at least one “skating” complaint event — players describing opponents as ice-skating or jittering across cover.

The bug was not prediction; it was how remote entities were displayed. Applying each server snapshot directly to the render transform updates the mesh only when packets arrive — irregularly — so motion stutters even when simulation is correct. Entity interpolation (snapshot interpolation, remote smoothing) buffers past authoritative states and renders every remote entity slightly in the past, lerping between two confirmed snapshots at a stable display rate. This guide covers snapshot buffers, render delay, position and rotation blending, extrapolation limits, jitter adaptation, animation sync, the Harbor Vanguard refactor, a technique decision table versus instant snap and full rollback, pitfalls, and a production checklist.

Local prediction versus remote interpolation

Multiplayer netcode splits into two problems that beginners often merge:

  • Local player — hide input latency with prediction and reconcile when the server disagrees. Covered in depth in the prediction guide.
  • Remote entities — you do not have their inputs. You only receive sparse state snapshots. Smooth display requires interpolation (and sometimes limited extrapolation), not prediction of foreign input streams.

Harbor Vanguard fixed local movement first; remote skating persisted because engineers reused the same “apply snapshot immediately” path for all entities. Separating the pipelines — predict self, interpolate others — is the first architectural rule.

Snapshot model and the interpolation buffer

The server simulates at fixed ticks (e.g. 20 Hz = 50 ms per tick, 64 Hz = 15.6 ms). Each tick it sends per-entity state: position, rotation, velocity, animation phase, health flags, weapon state. Clients store snapshots in a ring buffer keyed by server tick or timestamp.

To render at time t, the client does not use the latest snapshot. It uses:

Render time = current server time − interpolation delay

Typical delay is one to three server ticks (50–150 ms at 20 Hz). That delay buys two confirmed snapshots bracketing the render moment so the engine can blend smoothly. Without it, you only ever have discrete jumps.

Find snapshots S0 and S1 where t0 ≤ render time < t1. Interpolation factor:

α = (render time − t0) / (t1 − t0)

Position: P = lerp(P0, P1, α). Rotation: quaternion slerp between R0 and R1 — never euler lerp on characters (gimbal wobble and wrong shortest path).

Render delay, jitter and adaptive buffers

Fixed delay works on LAN. On consumer internet, packet arrival jitters: one snapshot arrives 30 ms late, the next on time. If the buffer is too shallow, the client runs out of future snapshots and stalls or snaps.

Adaptive interpolation delay tracks recent packet spacing (variance of Δt between snapshots) and adds margin:

  • Measure rolling 95th-percentile inter-arrival time per connection.
  • Set delay = max(base delay, p95 spacing + safety margin).
  • Cap delay (e.g. 200 ms) so high-ping players do not render enemies in another era.

Harbor Vanguard started with a fixed 50 ms delay on a 20 Hz server — one tick. Under jitter, 41% of remote entities hit buffer underrun at least once per round. Raising base delay to 100 ms and adding adaptive +25 ms margin on high-variance connections cut underruns to 6% without changing server tick rate.

Extrapolation and dead reckoning limits

When the buffer empties — snapshot still in flight — pure interpolation has nothing to blend toward. Options:

  • Freeze at last known pose (safe, looks stuck).
  • Extrapolate using last velocity and angular velocity (dead reckoning) for a short window.
  • Snap when the late snapshot arrives (visible pop).

Production shooters almost always extrapolate for 100–250 ms max, then freeze or fade. Uncapped extrapolation makes enemies dive through walls when packets burst after loss. Harbor capped extrapolation at 150 ms and clamped velocity to the entity’s max sprint speed so cheats could not amplify bogus velocity fields.

Extrapolation is display-only. Hit detection and lag compensation still use authoritative server history — never trust extrapolated poses for damage.

Animation, velocity and visual coherence

Position lerp alone leaves feet sliding if the animation state machine still plays idle while the mesh moves. Derive display velocity from snapshot deltas and drive locomotion blend trees:

  • Speed = |P1 − P0| / Δt
  • Heading from horizontal velocity vector
  • Trigger jump/crouch from snapshot flags, not from inferred physics

For root-motion animations, either disable root motion on remote entities and drive transforms from snapshots, or reconcile root delta each frame against interpolated position (remote root motion is a common skating source).

Weapon and upper-body layers can interpolate on a shorter delay than lower body when snapshots include aim yaw/pitch separately — but keep delay consistent enough that crosshair alignment with hit feedback does not feel dishonest.

Bandwidth, priority and relevance

Interpolation quality depends on snapshot density. Not every entity needs 64 Hz updates:

  • Relevance tiers — full rate for visible combatants, reduced rate beyond fog distance or behind occlusion.
  • Delta compression — send fields that changed since last acked snapshot; quantize position to millimeter integers.
  • Interest management — stop streaming entities outside AOI; freeze last pose or despawn mesh.

When rate drops, increase interpolation delay proportionally or accept more extrapolation — document the tradeoff per tier so designers do not tune spawn counts that collapse remote update rate.

Harbor Vanguard refactor

Changes shipped in three passes:

  1. Split render paths: local predicted, remote interpolated-only.
  2. Ring buffer with 100 ms base delay + adaptive jitter margin; quaternion slerp for rotation.
  3. 150 ms extrapolation cap; velocity-clamped dead reckoning; animation driven from snapshot velocity.

Results on 10k beta matches (NA/EU, 30–120 ms ping):

  • Skating complaint events: 58% → 11% of matches
  • Buffer underrun per entity per round: 41% → 6%
  • Median perceived remote smoothness rating (post-match survey): 2.8 → 4.1 / 5
  • Added display latency on remotes: ~100 ms (acceptable vs instant-jitter)

Hit registration fairness unchanged — server rewind untouched. Players stopped blaming netcode for misses that were actually interpolation confusion on their own aim.

Technique decision table

ApproachBest forWeak when
Instant snapshot snapTurn-based, low entity countAny real-time action with >10 Hz sim
Fixed-delay interpolationLan, stable datacenter pathsConsumer Wi-Fi jitter
Adaptive delay + slerpFPS/MOBA remote playersUltra-low-latency esports LAN (may reduce delay)
Extrapolation + interpolationPacket loss without stutterLong loss bursts (must cap and freeze)
Rollback (full sim rewind)Fighting games, peer meshHigh entity count shooters
Prediction on remotesNever (without their inputs)Always wrong for competitive fairness

Common pitfalls

  • Interpolating the local player — doubles latency feel; predict self, interpolate others.
  • Euler rotation lerp — gimbal flip and wrong arc on 180-degree turns.
  • Zero render delay — mathematically cannot smooth between two points.
  • Uncapped extrapolation — enemies phase through geometry during burst loss.
  • Using display pose for traces — breaks trust; server history only for hits.
  • Root motion on remotes — feet slide despite good position lerp.
  • Same delay for all entity types — projectiles may need shorter delay; idle props need none.
  • Ignoring clock sync — render time must use estimated server clock, not local frame time alone.

Production checklist

  • Separate code paths: local prediction vs remote interpolation.
  • Ring buffer snapshots by server tick with monotonic validation.
  • Set base interpolation delay ≥ 2 server ticks; tune per tick rate.
  • Adapt delay from packet jitter; cap maximum display lag.
  • Lerp position; slerp rotation; quantize sensibly on wire.
  • Cap extrapolation time and velocity; freeze on sustained loss.
  • Drive remote animation from snapshot velocity and flags.
  • Disable or reconcile root motion on non-local entities.
  • Tier update rate by relevance; document delay per tier.
  • Sync client server clock estimate (NTP-style smoothing).
  • Telemetry: buffer underruns, extrapolation time, snap magnitude.
  • Playtest at 80, 120, 200 ms ping; verify hits still feel fair.

Key takeaways

  • Remote entities need interpolation, not input prediction.
  • Render in the past with delay so two snapshots always bracket display time.
  • Adaptive jitter buffers beat fixed delay on real networks.
  • Extrapolate briefly, then freeze — never unlimited dead reckoning.
  • Harbor Vanguard cut skating complaints 58% to 11% by splitting pipelines and adding slerp + adaptive delay.

Related reading