mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
feat(multiplayer): Phase 3 task 3.7 - debug net overlay extension
Extends net_debug_overlay.gd (Phase 1's RTT/offset display) with the rest of task 3.7's list: jitter (new RFC3550-style EWMA in NetworkManager, computed from raw per-sample RTT before Phase 1's own min-filtering, since that filter is deliberately jitter-insensitive by design), input buffer depth and input_lead (both already tracked client-side for task 3.3), snapshot loss (a new EWMA in networked_match.gd over each received snapshot's own server_tick gap - snapshots go out at a steady one-tick cadence, so a gap is direct evidence of a drop or reorder), snapshot age (computed on demand from the same bias-corrected tick estimate the interpolator itself uses), and bandwidth (new rolling per-second byte counters in MatchSim, on the two 60Hz hot-path channels only). Prediction error is deliberately omitted with a comment explaining why: there's no client-side prediction to measure until Phase 4. Verified values are live and plausible, not just present, by calling get_net_debug_stats() directly in a real two-process test and checking the numbers make sense: bandwidth matched the wire format's own byte math almost exactly (measured ~2400 B/s sent against a computed 40B x 60Hz, ~3540 B/s received against 59B x 60Hz), and buffer depth/lead/loss all moved in the correct direction between a clean LAN run and one under simulated 60ms latency + 10% loss. Full regression suite re-run clean.
This commit is contained in:
@@ -71,6 +71,14 @@ var clock_offset_ms := 0.0 # add to a local Time.get_ticks_msec() reading to
|
||||
var _clock_samples: Array[Dictionary] = []
|
||||
var _ping_accum_sec := 0.0
|
||||
|
||||
# Jitter (task 3.7's debug overlay): RFC3550-style EWMA of the deviation
|
||||
# between consecutive RAW (not min-filtered) RTT samples — rtt_ms itself is
|
||||
# a min-RTT, deliberately insensitive to jitter by design (§4.7), so a
|
||||
# separate, unfiltered running estimate is needed to actually see it.
|
||||
const JITTER_EWMA_ALPHA := 1.0 / 16.0 # matches RFC3550's own smoothing factor
|
||||
var jitter_ms := 0.0
|
||||
var _last_raw_rtt_ms := -1.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
get_tree().set_multiplayer_poll_enabled(false)
|
||||
@@ -162,6 +170,8 @@ func shutdown() -> void:
|
||||
clock_offset_ms = 0.0
|
||||
_clock_samples.clear()
|
||||
_ping_accum_sec = 0.0
|
||||
jitter_ms = 0.0
|
||||
_last_raw_rtt_ms = -1.0
|
||||
|
||||
|
||||
@rpc("any_peer", "call_remote", "reliable")
|
||||
@@ -192,6 +202,10 @@ func _pong(client_send_ms: int, server_now_ms: int) -> void:
|
||||
var now_ms := Time.get_ticks_msec()
|
||||
var sample_rtt := float(now_ms - client_send_ms)
|
||||
var sample_offset := float(server_now_ms) + sample_rtt / 2.0 - float(now_ms)
|
||||
if _last_raw_rtt_ms >= 0.0:
|
||||
var deviation := absf(sample_rtt - _last_raw_rtt_ms)
|
||||
jitter_ms += (deviation - jitter_ms) * JITTER_EWMA_ALPHA
|
||||
_last_raw_rtt_ms = sample_rtt
|
||||
_clock_samples.append({"t": now_ms, "rtt": sample_rtt, "offset": sample_offset})
|
||||
|
||||
var cutoff := now_ms - int(CLOCK_WINDOW_SEC * 1000.0)
|
||||
|
||||
Reference in New Issue
Block a user