Snapshot Interpolation
The snapshot interpolation system provides smooth rendering of remote entities by buffering transform snapshots and playing them back with an adaptive-rate algorithm. It eliminates jitter, prevents extrapolation artifacts, and handles teleportation gracefully.
Overview
In a networked game, state updates arrive at irregular intervals due to network jitter. Simply applying each update as it arrives produces visible stuttering. The snapshot interpolation system solves this by:
Buffering snapshots in a ring buffer.
Maintaining a playback timeline that runs slightly behind the newest data.
Adapting the playback speed to absorb jitter: speeding up when the buffer grows, slowing down when it thins.
Interpolating linearly between the two snapshots bracketing the current timeline position.
The result is smooth, consistent-speed movement with no overshoot or oscillation.
Key Classes
plSnapshotBuffer
A templated ring buffer that stores plNetworkTransformSnapshot entries and manages the adaptive playback timeline.
plNetworkInterpolator
A convenience wrapper around plSnapshotBuffer with a simpler API:
plSnapshotInterpolationConfig
Configuration for the interpolation behavior:
Property | Type | Default | Description |
|---|---|---|---|
|
| 100 ms | Target delay behind the newest snapshot. Should be at least 2x the send interval. |
|
| 0.05 | Maximum speed deviation from 1.0x (5%). A character at 3 m/s varies between 2.85 and 3.15 m/s. |
|
| 2.0 | How aggressively the playback rate adapts per second. |
|
| 5.0 | Distance above which the entity snaps instead of interpolating. |
How Adaptive-Rate Playback Works
Traditional interpolation picks a fixed render time (e.g., network time minus delay). This is fragile -- if a packet is late, there is nothing to interpolate toward, requiring extrapolation (which overshoots).
The adaptive-rate approach instead controls the speed of a local timeline:
Calculate how much data is buffered ahead of the timeline.
Compare against the target buffer (the
InterpolationDelay).If too much data is buffered, speed up slightly (drain excess).
If too little data is buffered, slow down slightly (buy time for the next packet).
Clamp the speed deviation to
MaxPlaybackDriftto keep movement looking natural.
This produces extremely smooth, consistent-speed movement even under significant jitter.
Teleport Handling
If the distance between two consecutive snapshots exceeds TeleportThreshold, the interpolator snaps to the new position instantly. This handles respawns, level transitions, or large server corrections without producing a visible fast-forward effect.
Debug Information
Both plSnapshotBuffer and plNetworkInterpolator expose debug accessors:
Use these with the Network Debug Component to visualize interpolation state during development.
plNetworkTransformSnapshot
A single snapshot in the buffer:
Field | Type | Description |
|---|---|---|
|
| Position, rotation, and scale |
|
| Linear velocity at snapshot time |
|
| Angular velocity at snapshot time |
|
| Network time, local time, and sequence number |