Skip to main content

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.position and player.forward from 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_* and data.* 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

  1. Stand up a GSI listener. Minimal localhost HTTP server (any of the existing GSI libs is fine as a reference: CounterStrike2GSI C#, cs-gamestate Python). Log every payload with a local receive-timestamp.
  2. Configure GSI for max responsiveness. Set the throttle/heartbeat low and enable position + forward-direction with adequate precision. Record the config used.
  3. Play a real session (~10 min, mixed movement: walking, fast flicks, jumps, round resets / respawns). One human, one machine.
  4. 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?).
  5. 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).
  6. 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