From 4c6a452f9d14ff04ec1ed1c6e3c024729c246519 Mon Sep 17 00:00:00 2001 From: MelekTaus Moribundus Date: Wed, 8 Jul 2026 20:40:48 +0200 Subject: [PATCH] Fix late joiners never seeing earlier peers behind the paint reveal gate Applying a snapshot now also raises the replica's sequence horizon: a snapshot covers all events up to its captured cutoff. Previously the horizon only advanced with the live stamp stream, so the server replica of a player who never painted served snapshots with cutoff 0 - late joiners then waited forever for the published baseline cutoff and the reveal gate never opened (third client could not see the second). Co-Authored-By: Claude Fable 5 --- Assets/Scripts/Network/PlayerPaintSync.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Assets/Scripts/Network/PlayerPaintSync.cs b/Assets/Scripts/Network/PlayerPaintSync.cs index 81c03bf..56dc4f3 100644 --- a/Assets/Scripts/Network/PlayerPaintSync.cs +++ b/Assets/Scripts/Network/PlayerPaintSync.cs @@ -263,6 +263,11 @@ public class PlayerPaintSync : NetworkBehaviour _snapReadyToApply = false; _painter.ApplyPaintSnapshot(_snapBuffer, _snapBaselineId); if (_snapCapturedSeq > _appliedCutoff) _appliedCutoff = _snapCapturedSeq; // receiver-side reveal gate + // The snapshot accounts for every event up to its cutoff, so raise this replica's horizon too. + // The SERVER replica serves late-join snapshots with _seqHorizon as the cutoff; without this a + // baseline that arrived AS a snapshot (owner publish, no live stamps since) would be served with + // a stale cutoff below the owner's published baseline, permanently reveal-gating the joiner. + if (_snapCapturedSeq > _seqHorizon) _seqHorizon = _snapCapturedSeq; if (logSync) LogSync($"applied snapshot baseline {_snapBaselineId}; replaying buffered events"); FlushBuffered(); _snapBuffer = null;