Skip to content

fix: NetworkList changes pending during client synchronization are applied twice - #4200

Open
quantum-shubham wants to merge 1 commit into
Unity-Technologies:develop-2.0.0from
quantum-shubham:fix/networklist-pending-sync-duplicates
Open

quantum-shubham wants to merge 1 commit into
Unity-Technologies:develop-2.0.0from
quantum-shubham:fix/networklist-pending-sync-duplicates

Conversation

@quantum-shubham

@quantum-shubham quantum-shubham commented Oct 20, 2026 •

Copy link
Copy Markdown

TITLE:
fix: NetworkList changes pending during client synchronization are applied twice

BODY:

Purpose of this PR

Fixes #4179

If a client is synchronized while a NetworkList<T> still has unsent changes, the synchronization snapshot already contains those changes. On the next tick the same events are sent to the new observer again. Add, Insert, Remove, RemoveAt and Set are not idempotent, so the late-joining client ends up with duplicate entries, and later index-based events land on the wrong elements. #3081 fixed this for NetworkVariable<T> through WriteFieldSynchronization, but NetworkList<T> never overrode it.

NetworkList<T> now overrides WriteFieldSynchronization, mirroring NetworkVariable<T>. While local changes are pending, it writes the list as it was before the first of them. The pending events then bring the client up to date exactly once with the next delta.

The copy is taken just before the first local change after a delta is sent, and the flag is cleared in ResetDirty. It is not refreshed in ResetDirty, because there it could go stale on instances where ResetDirty doesn't run, such as a non-writer that later becomes owner. Paths without locally pending events behave exactly as before: server forwarding of owner-write deltas, NetworkShow (already flushed by ForceSendIfDirtyOnNetworkShow), and spawn.

Tradeoff: each NetworkList<T> keeps one extra native buffer, and the writer does one copy per dirty period.

Jira ticket

N/A (GitHub issue #4179)

Changelog

  • Fixed: Issue where a client synchronized while a NetworkList<T> still had unsent changes applied those changes twice, resulting in duplicate entries and index-based events landing on the wrong elements on that client.

Documentation

  • No documentation changes or additions were necessary.

Testing & QA (How your changes can be verified during release Playtest)

Functional Testing

Manual testing :

  • Manual testing done

Automated tests:

  • Covered by existing automated tests
  • Covered by new automated tests

New NetworkListTests.LateJoinWithPendingChanges (Host / DAHost / Server). It holds deltas back with MinSecondsBetweenUpdates, applies Add/Insert/RemoveAt/Set/Remove, late-joins a client, checks the changes are still pending, releases them, and verifies every client matches.

  • Without the fix, the new test fails in all three modes (Expected: 5, Have: 6 on the late-joined client).
  • With the fix, PlayMode on Unity 6000.0.72f1 (testproject) passed 1044/1044 across the related suites: NetworkVariable*, NetworkList*, NetworkShowHide, NetworkObjectSynchronization, NetworkObjectOwnership, OwnerModified and the permission/hidden variable tests.

Does the change require QA team to:

  • Review automated tests?
  • Execute manual tests?
  • Provide feedback about the PR?

Up-port

The same code exists on develop-3.x.x. I can open the up-port PR once this one is reviewed.

Backports

Not needed.

…plied twice

Override WriteFieldSynchronization in NetworkList<T> so a client synchronized while local changes are still pending receives the list as of the last sent delta, mirroring NetworkVariable<T>. The pending events are then applied exactly once with the next delta.

Fixes Unity-Technologies#4179
@quantum-shubham
quantum-shubham requested a review from a team as a code owner October 20, 2026 06:11
@quantum-shubham quantum-shubham changed the title fix: NetworkList changes pending during client synchronization are ap… fix: NetworkList changes pending during client synchronization are applied twice Oct 20, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant