diff --git a/Assets/Scripts/Network/MatchManager.cs b/Assets/Scripts/Network/MatchManager.cs index 906a7bf..8210a95 100644 --- a/Assets/Scripts/Network/MatchManager.cs +++ b/Assets/Scripts/Network/MatchManager.cs @@ -704,7 +704,7 @@ public class MatchManager : MonoBehaviour { _skipPhase = false; // drop a stale debug-skip from the previous phase; only this phase may set it float t = seconds; - float pingTimer = radarPingInterval; // first sweep one interval into Seek + int pingsSent = 0; // sweeps fired so far; boundaries anchored to _seekStartTime (the HUD's ping anchor) while (t > 0f) { if (_pendingHiders.Count == 0) yield break; @@ -712,11 +712,16 @@ public class MatchManager : MonoBehaviour if (radarPingInterval > 0f) { - pingTimer -= Time.deltaTime; - if (pingTimer <= 0f) + // Fire on absolute interval boundaries from Seek start (n*interval), sharing the exact anchor the + // HUD countdown uses (LocalNextPingIn's modulo) - so the on-screen ping timer hits 0:00 the same + // moment the sweep fires. An accumulating countdown would discard each cycle's overshoot and drift + // seconds late over a match (worse with frame spikes). A missed boundary (huge hitch) is skipped, + // not caught up - one late sweep, never a burst. + int due = Mathf.FloorToInt((Time.time - _seekStartTime) / radarPingInterval); + if (due > pingsSent) { BroadcastRadarPings(); - pingTimer = radarPingInterval; + pingsSent = due; } }