Repository navigation
Description
Description
With UseHalfFloatPrecision and UseUnreliableDeltas both on, a non-authority NetworkTransform can lose a half-float base update and then decode every following delta against the old base. The object is drawn about 2 m off (one MaxDeltaBeforeAdjustment step) until the next unreliable frame sync, up to a second later.
How it happens (line numbers from 2.13.3; the same code is in develop-3.x.x today):
- When an axis's delta reaches
NetworkDeltaPosition.MaxDeltaBeforeAdjustment(2 m), the delta collapses into a new base. That state is flaggedSynchronizeBaseHalfFloatand sent reliably (NetworkTransformState.NetworkSerialize,NetworkTransform.cs:739-747:UseHalfFloatPrecision && NetworkDeltaPosition.CollapsedDeltaIntoBase→ReliableSequenced = true). - The deltas that follow go unreliably. Under jitter or a lost packet, a newer unreliable delta can arrive before the reliable base update.
- When the base update then arrives, it has an older tick than the state already applied.
OnNetworkStateChangeddrops it (NetworkTransform.cs:3326):Teleports and frame syncs are exempt, but a base sync isn't.if (UseUnreliableDeltas && oldState.NetworkTick > newState.NetworkTick && !newState.FlagStates.IsTeleportingNextFrame && !newState.FlagStates.UnreliableFrameSync) { return; }
- The non-authority's
NetworkDeltaPositionkeeps the old base, so every later half-float delta decodes about 2 m off until a frame sync corrects it.
Reproduce Steps
- A player prefab with an owner-authoritative
NetworkTransform:UseHalfFloatPrecisionon,UseUnreliableDeltason, position synced on all axes, interpolation on. - Host + 1 client (client-server). Simulate a poor connection on the host: about 75 ms delay with ±20 ms jitter and 2% packet loss (Unity Transport's simulator pipeline, or the Multiplayer Tools network simulator).
- The client walks in a straight line at about 4.5 m/s for 20–30 s.
- On the host, compare its copy of the client's player with the client's real position (log both every frame).
Actual Outcome
The host's copy usually trails by about 0.6 m, but every few seconds it jumps 2 m or more off for up to a second. In our measurements it was 2.5–4.6 m behind during those stretches. Logging NetworkDeltaPosition on both sides during one of them: the host's base on the walking axis was 4.17 m while the client's was 6.25 m (one 2 m step plus the delta).
Expected Outcome
A late base update is still applied (at least its base), so later deltas decode against the right base. Two possible fixes:
- exempt
SynchronizeBaseHalfFloatstates from the out-of-order rule, as teleports and frame syncs are; - or apply the base of a dropped state to
NetworkDeltaPositioneven when its position is ignored.
Screenshots
None. The numbers above come from per-frame logs.
Environment
- OS: Windows 11 Pro
- Unity Version: 6000.3.27f1
- Netcode Version: 2.13.3 (also present in
develop-3.x.xand 3.2.0: the same check is atNetworkTransform.cs:3345there) - Netcode Commit: the v2.13.3 release
- Netcode Topology: Client-Server (host)
Additional Context
- Unity Transport 2.7.4.
- With full-precision positions (half floats off, unreliable deltas kept) the host's copy stays within 0.82 m over the same walk, so the drops come from the base sync.
- Our workaround: never combine half floats with unreliable deltas on a
NetworkTransform. - Earlier half-float fixes (fix: NetworkTransform half float synch #2791, fix: unreliable deltas half float synch jitter #2922) don't cover this ordering case, as far as we can tell.
Activity