fix: Unify SyncVar and SyncCollection replay across host visibility, scene re-observation, and pooled respawn#4118
fix: Unify SyncVar and SyncCollection replay across host visibility, scene re-observation, and pooled respawn#4118MrGadget1024 with Copilot wants to merge 48 commits into
Conversation
|
@copilot Error: Assets/Mirror/Core/SyncDictionary.cs(371,42): error CS0103: The name 'newItem' does not exist in the current context |
|
@copilot Fix errors related to failed tests |
Addressed in 52f22a7. |
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (74.94%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## master #4118 +/- ##
==========================================
+ Coverage 42.22% 42.84% +0.61%
==========================================
Files 156 156
Lines 15100 15496 +396
==========================================
+ Hits 6376 6639 +263
- Misses 8724 8857 +133
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
@copilot Extend the new tests to move host client player out of AOI range, Assert that the test object is no longer observed, change the SyncVar value or make a change to the Sync Collection, Assert no hooks / actions, move host client player into range again, Assert hooks / actions invoked again the same as previously, e.g. same original oldValue as if the host client is seeing it for the first time again. |
... Fixed in d83f910. The SyncCollection replay-pending scoping change stopped host AOI re-observation from marking SyncVar-only behaviours for replay, so that test could miss the second in-range hook. |
|
@Lymdun I think we've covered everything now. |
|
@MrGadget1024 re-ran evals: Cross-member duplication really is fixed now. I verified be2f07c (per-hook pending), 956a0f6 (per-SyncObject pending), and d83f910 (AOI replay regression) in code, and the earlier pooling fix in ae5c2fd still holds. But re-running the evaluation at d83f910 leaves two transition cases, and one is exactly what you asked copilot to ensure against: a SyncCollection can still double-run its Add actions. 1. [P1] Two changes to the same member straddling The new fixes and tests all cover one pending member plus a different immediately-delivered member (SyncVar test, collection test). The same-member ordering behaves differently for the two kinds:
Suggested shape for both: if the member is already replay-pending, stay deferred instead of live-firing during the observer-entry → spawn-processing window. The replay then delivers exactly once with correct values ( 2. [P1] Pending replays are still consumed without a local player
Suggested regressions: two same-member changes (one SyncVar, one list Add) straddling Everything else from my earlier reviews is resolved on my side. Every claim and line anchor in it is verified against the actual code at d83f910 — the lhes described (the setter's pending-clear at line 690, AddOperation's ungated immediatefire, the full-list replay, and the gated vs. ungated flush paths). |
|
@copilot Review this comment |
Addressed in d41bf4c and 0a75f09. The linked review was actionable: host replay now stays deferred until the host can actually observe, and same-member SyncVar/SyncCollection changes no longer live-fire during the AddPlayer/spawn transition. I also added focused regressions for both the straddle-AddPlayer case and the ready-without-player runtime-spawn case. |
|
@Lymdun We good now? |
|
@copilot In the Room example, there is a Spawner static class |
Addressed in 1fab2fc with the test follow-up in 310425d. Host-mode |
@MrGadget1024 re-ran all evals, all good now ✅ |
|
@copilot Update the Title and Description of this PR reflecting the goals we achieved and describing the work completed. |
Use this updated PR metadata: Title Description
Example behavior after this change: [SyncVar(hook = nameof(OnValueChanged))]
public int value = 42;
// Mutated before the host can observe it
value = 100;
value = 200;
// When the host first observes or re-observes the object:
// OnValueChanged(42, 200)That wording matches the behavior covered by the final test set and the host/remote example scenarios fixed in this PR. |
SyncVar hooks and SyncCollection callbacks could diverge between host and remote clients when visibility, scene-object reuse, or pooled respawn got involved. This PR brings those paths back into alignment so observation-driven replay behaves consistently across host mode, remote clients, AOI hide/show, and runtime
UnSpawn/respawn reuse.Preserve correct SyncVar baselines
oldValuea fresh observer would.Defer host callbacks until actual observation
Replay re-observation as a fresh observation
Addactions again on re-observation, instead of remembering prior observation state.Handle pooled runtime-object reuse in host mode
NetworkServer.UnSpawn/respawn of pooled runtime objects now marks SyncVar hooks and SyncCollection replays pending before visibility is lost.RandomColor) and current SyncCollection contents again, even without AOI.Preserve server delta queues and avoid duplicate callbacks
Regression coverage
Example behavior after this change: