Real-Time Coverage — Tier-0 Pose Feasibility Spike (CS2 GSI / demo-tail)
This spike validates the enabling step for the Real-Time Spatial Coverage proposal: can we get usable, low-latency local-player camera pose live, while the player is actually playing (not spectating), at a rate and stability good enough to drive a real-time coverage HUD — using only sanctioned, non-injecting interfaces?
If yes, the cheap, accurate Tier-0 path (engine-truth coverage on replay-API
titles) is unblocked and becomes the low-risk wedge for the whole feature. If GSI is
too slow/jittery while playing, we fall back to demo-tail (reading the .dem
the engine writes during the match) and characterise its latency instead.
Why this is the enabling step: Tier-0 coverage is just frustum carving against a known pose — no neural net, trivial compute (see proposal §5). The entire question is therefore "do we have a good-enough live pose?" Everything else in the realtime layer is cheap once pose exists. This spike answers exactly that and nothing more.
Scope
In scope: getting (position, forward-direction) for the local player live, on
one machine, and measuring it. Out of scope: multi-entity world-state (other
players) — GSI does not expose that during live play; it stays a post-game
demo-parse job. Also out of scope: the coverage engine, the renderer, and Tier-1
estimation — they have their own spikes.
Two paths under test
- Path A — Game State Integration (GSI). Drop a GSI config into the CS2 config
dir; CS2 POSTs JSON game-state to a localhost HTTP endpoint we run. Read
player.positionandplayer.forwardfrom the local player. Sanctioned by Valve, no process injection, no memory reads.- Known limitation (must be confirmed, not assumed): while playing, GSI exposes only the local player's block; full roster appears only when spectating. For Tier-0 ego-coverage this is sufficient.
- Open question this spike answers: update rate and jitter under live play.
GSI is throttled by the config
output.precision_*anddata.*and a heartbeat/throttle interval; we need to know the realistic effective Hz and the latency distribution, not the advertised one.
- Path B — demo-tail (fallback). Have the client record a demo and parse it incrementally as the file grows, extracting camera pose per tick. Higher latency (file-flush bound, expect a few hundred ms) but exact and full-fidelity.
Protocol
- Stand up a GSI listener. Minimal localhost HTTP server (any of the existing
GSI libs is fine as a reference:
CounterStrike2GSIC#,cs-gamestatePython). Log every payload with a local receive-timestamp. - Configure GSI for max responsiveness. Set the throttle/heartbeat low and enable position + forward-direction with adequate precision. Record the config used.
- Play a real session (~10 min, mixed movement: walking, fast flicks, jumps, round resets / respawns). One human, one machine.
- Measure from the logged stream:
- effective update rate (median + p5/p95 inter-arrival),
- latency proxy (compare GSI timestamps vs local receive time; note clock caveats),
- behaviour across round reset / respawn / death-cam / map change — the events that break naïve odometry and that Tier-0 must handle cleanly,
- confirm the local-player-only limitation empirically (does any other-player data ever appear while playing?).
- Demo-tail comparison. Record the same session to a demo; parse it incrementally; measure parse-to-availability latency and confirm pose matches the GSI stream where they overlap (sanity cross-check).
- Feed both into the mock's coverage update offline (replay the logged pose stream through the coverage engine prototype) to confirm the carve looks right against a known route.
Success criteria
Tier-0 via GSI is a go if, during live play:
- effective pose rate ≥ ~8–10 Hz median with p95 inter-arrival under ~250 ms (a coverage HUD updates at 2–5 Hz, so this is comfortable headroom),
- pose is stable through flicks and continuous movement (no large dropouts),
- round-reset / respawn / map-change are detectable from the stream so we can reset the frontier/coverage frame cleanly,
- local-player pose is present and correct throughout.
If GSI rate/jitter fails the bar, demo-tail is the go path provided its parse-to-availability latency is within a few hundred ms and pose is exact — a coverage HUD tolerates that latency.
A no-go on both would mean Tier-0 needs an unsanctioned interface, which we will not pursue — in that case Tier-0 is deferred and we re-scope around Tier-1.
What to build (spike deliverables)
- A throwaway GSI listener + logger (localhost), with the config used.
- A short measurement script producing the rate/latency/robustness numbers above.
- A demo-tail latency probe (can be rough).
- A one-page results note appended here (numbers + go/no-go + the chosen Tier-0 pose path), feeding proposal §7 item 1 and §8 spike 1.
Decision this unblocks
A go turns "Tier-0 realtime coverage" from aspirational into a scheduled build: pose tap (proposal §7.1) → coverage engine (§7.2) → overlay (§7.3). It also fixes which interface the recorder integrates (GSI vs demo-tail), which is the only real unknown in the Tier-0 path.
References
- Proposal: Real-Time Spatial Coverage
- Spine: State-Estimation Ladder (Tier 0 = engine truth)
- Recorder constraints: pure-v2 capture pipeline
- CS2 GSI reference: Valve Developer Community — Game State Integration;
CounterStrike2GSI(field reference).