fix: half float delta position dither up port - #4129
Open
NoelStephensUnity wants to merge 4 commits into
Open
Conversation
NetworkDeltaPosition carries the half float rounding loss of each update into the next one, which keeps the average transmitted position accurate while a value is moving. The loss alone is enough to change the encoded delta, so once the value stops moving that mechanism keeps changing what is sent even though the position has not moved. The encoded value alternates between neighbouring representable values and a stationary object is transmitted as one that oscillates. The rounding loss is now only carried forward while the value moves by at least one representable step. MaxDeltaBeforeAdjustment also determined the transmitted resolution, since a half float's step size grows with its magnitude. At 64 the coarsest step was 31.25mm, so objects away from their base position were reproduced in ~3cm increments. At 2 it is 0.977mm. Folding the delta into the base more often costs no bandwidth with reliable deltas because both sides apply the same rule to the same value, and the reconstructed position is unchanged by the fold. UseUnreliableDeltas forces a full precision base synchronization per fold, so those projects will send those more often. Measured on 10 settling physics objects with half float enabled: 28-42mm of oscillation before, none after, matching the same scene with half float disabled. Objects in motion improve as well, peak error dropping from 12.5mm to 0.587mm. Sender and receiver must agree on MaxDeltaBeforeAdjustment, so this is not compatible across builds. NetworkConstants.PROTOCOL_VERSION already participates in the connection config hash, so mismatched versions cannot connect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two NetcodeIntegrationTest cases, one for an object moving in steps too small for the encoding to represent and one for an object at rest. Both move the authority forwards only and require non-authority instances to follow without ever moving backwards. Interpolation cannot overshoot, so movement opposite to the authority's has to have come from the encoding. That also avoids a tolerance that would need revisiting whenever the resolution changes. Two setup details are needed for these to detect anything. The object has to travel away from the base position established when it spawned, since resolution is fine near the base. It then has to step by an amount the encoding cannot represent before coming to rest, because a position a half float represents exactly leaves no rounding loss and so cannot exhibit the problem: resting on 30.0 produces no backwards movement at all while resting on 30.0007 produces 15.6mm. Verified in both directions. Without the fix all four cases fail on the intended assertion, reporting 7.9mm to 10.1mm of backwards movement. With the fix all four pass. These do not use the time travel harness because the behavior only appears over multiple real state update and interpolation cycles. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6 tasks
Updated the changelog to include issue #4129 regarding the precision of NetworkTransform synchronization.
Fixed jitter issue with NetworkTransform.UseHalfFloatPrecision on non-authority instances.
NoelStephensUnity
marked this pull request as ready for review
August 19, 2026 01:36
Codecov ReportAttention: Patch coverage is
@@ Coverage Diff @@
## develop-3.x.x #4129 +/- ##
=================================================
+ Coverage 78.01% 78.06% +0.04%
=================================================
Files 153 153
Lines 26254 26267 +13
=================================================
+ Hits 20483 20505 +22
+ Misses 5771 5762 -9
Flags with carried forward coverage won't be shown. Click here to find out more.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose of this PR
This is an up-port of #4128.
(Refer to that PR for the details)
Jira ticket
NA
Changelog
NetworkTransform.UseHalfFloatPrecisionappeared to jitter on non-authority instances while they were stationary or coming to rest, even though the authority was not moving them.NetworkTransform.UseHalfFloatPrecisionnow synchronizes position with a resolution of approximately 1mm regardless of how far an object has travelled. Previously the resolution could degrade to approximately 3cm. This does not increase bandwidth, but projects usingNetworkTransform.UseUnreliableDeltaswill send full precision position updates more often.Documentation
Testing & QA (How your changes can be verified during release Playtest)
Functional Testing
Manual testing :
Manual testing done- NGO Examples physics ball stress test, standalone IL2CPP client against an editor host, comparing before and after builds.Automated tests:
Covered by existing automated tests- the full testproject and runtime test runners pass. Note that these did not previously cover this behaviour.Covered by new automated tests-NetworkTransformHalfFloatPrecisionTests, two cases across Host and DAHost.The new tests were verified in both directions. Without the fix all four cases fail on the intended assertion, reporting 7.9mm to 10.1mm of backwards movement. With the fix all four pass.
Does the change require QA team to:
Review automated tests? - the tests assert that the client never moves opposite to the authority rather than asserting a position tolerance. Interpolation cannot overshoot, so backwards movement can only have come from the encoding, and the assertion does not need revisiting when the resolution changes. They also depend on two setup details that look arbitrary but are not, both commented: the object has to travel away from its spawn position, and it then has to step by an amount the encoding cannot represent before coming to rest. A position that a half float represents exactly leaves no rounding loss and so cannot exhibit the problem.Execute manual tests? - specifically a project usingUseUnreliableDeltastogether withUseHalfFloatPrecision, which is the one configuration that sends more data after this change.Provide feedback about the PR?These tests do not use the time travel harness, since the behaviour only appears over multiple real state update and interpolation cycles. Runtime is roughly 3.5s per case.
Up-port
No up-port is required.
Backports
Not needed since this is an up-port.