Feed: use and collect events, per-racer totals #35

Closed
opened 2026-10-20 18:41:26 +00:00 by mintopia · 2 comments
Owner

Events

  • use: one per use of a powerup by any racer: a bolt volley = 3, placing a mine = 1, Nitro/Repair/Shield included. Sources: channel-9 event 0 (fired, ADR 0017), event 4 self-applied (Nitro/Repair, ADR 0016), event 14 (Shield). data: racer, powerup, serial.
  • collect: inferred from the 5 Hz held-queue diff (ADR 0017). A use (or Bribe grant) of a kind never seen held backfills a collect with inferred: true.
  • hit unchanged (one per strike, mine hit separate from its placement).

Totals

Per racer, live in standings and final in race_result, every mode: totals with per-kind maps uses, collections, hits_dealt, hits_taken, hits_shielded, damage_dealt, damage_taken; plus wrecks_dealt, wrecks_suffered (powerup + collision), self_hits. Counted from feed events so they agree on every instance. Decoy counts come with #36.

Acceptance

  • Verified on SP, split-screen and 2-instance LAN with the bot scenarios: counts match event logs.

Rules

  • Wire format: ADR 0019 (docs/decisions/0019-feed-message-contract.md). Repo data/tools: ADR 0020.
  • Fix and verify on BLUR_ENGINE=recomp only.
  • Update docs/state-websocket.md and examples/live-timing for any feed change.
  • Test races: use the scripts/ scenarios (windowed, low settings) once #33 exists.
## Events - `use`: one per use of a powerup by any racer: a bolt volley = 3, placing a mine = 1, Nitro/Repair/Shield included. Sources: channel-9 event 0 (fired, ADR 0017), event 4 self-applied (Nitro/Repair, ADR 0016), event 14 (Shield). `data`: `racer`, `powerup`, `serial`. - `collect`: inferred from the 5 Hz held-queue diff (ADR 0017). A `use` (or Bribe grant) of a kind never seen held backfills a `collect` with `inferred: true`. - `hit` unchanged (one per strike, mine hit separate from its placement). ## Totals Per racer, live in `standings` and final in `race_result`, every mode: `totals` with per-kind maps `uses`, `collections`, `hits_dealt`, `hits_taken`, `hits_shielded`, `damage_dealt`, `damage_taken`; plus `wrecks_dealt`, `wrecks_suffered` (powerup + collision), `self_hits`. Counted from feed events so they agree on every instance. Decoy counts come with #36. ## Acceptance - Verified on SP, split-screen and 2-instance LAN with the bot scenarios: counts match event logs. ## Rules - Wire format: ADR 0019 (`docs/decisions/0019-feed-message-contract.md`). Repo data/tools: ADR 0020. - Fix and verify on `BLUR_ENGINE=recomp` only. - Update `docs/state-websocket.md` and `examples/live-timing` for any feed change. - Test races: use the `scripts/` scenarios (windowed, low settings) once #33 exists.
Author
Owner

Implemented on branch harmonic/task-33 (commit 018dba7).

Events

  • use: channel-9 event 0 (fired; bolt volley = 3, mine placement = 1, Shield included, since it arrives as event 0 kind 7) plus event 4 self-applied (Nitro/Repair). data: racer, powerup, serial. Event 14 is not hooked; event 0 already covers Shield.
  • collect: from the 5 Hz held-queue diff (multiset diff, so reorders are ignored; out-of-range kinds are skipped). A use of a kind never seen held sends collect with inferred:true first, and the later queue gain is not counted twice.
  • hit unchanged, except a strike the game repeats with the same serial and victim is now sent once. Without that, LAN instances disagreed on hit counts.

Totals

  • Added totals to every standings entry, so it is live and also in race_result.standings. Fields: per-kind maps uses, collections, hits_dealt, hits_taken, hits_shielded, damage_dealt, damage_taken, plus wrecks_dealt, wrecks_suffered, self_hits.
  • Self-hits count only in self_hits.
  • Powerup wrecks come from the hit event. Collision wrecks come from the health poll.
  • Totals reset when a race ends, because the first powerups are fired before the feed sees lap 1.

Docs and example

  • docs/state-websocket.md updated.
  • The live-timing example gets HITS and WRECKS columns in the final classification.

Verification (recomp, bot scenarios; I regenerated the recompiled code first because the checked-in copy predated the event-send hook)

  • SP: 298 use / 160 collect / 92 hit events; final totals match the event log for all 20 racers.
  • Split-screen (2 pads): final totals match the event log.
  • 2-instance LAN: use and hit totals identical on both instances after mapping racer indices. Collections differ only by polling noise (one remote out-of-range kind, now filtered). The LAN bot race did not reach a finish within 500 s, so I compared the live standings totals.
  • race_feed, hit_event, game_state and state_ws ctests pass. I did not run the full test suite or /code-review, and I did not check the live-timing page in a browser.
  • Decoy counts are left for #36.
Implemented on branch harmonic/task-33 (commit 018dba7). **Events** - `use`: channel-9 event 0 (fired; bolt volley = 3, mine placement = 1, Shield included, since it arrives as event 0 kind 7) plus event 4 self-applied (Nitro/Repair). `data`: `racer`, `powerup`, `serial`. Event 14 is not hooked; event 0 already covers Shield. - `collect`: from the 5 Hz held-queue diff (multiset diff, so reorders are ignored; out-of-range kinds are skipped). A `use` of a kind never seen held sends `collect` with `inferred:true` first, and the later queue gain is not counted twice. - `hit` unchanged, except a strike the game repeats with the same serial and victim is now sent once. Without that, LAN instances disagreed on hit counts. **Totals** - Added `totals` to every `standings` entry, so it is live and also in `race_result.standings`. Fields: per-kind maps `uses`, `collections`, `hits_dealt`, `hits_taken`, `hits_shielded`, `damage_dealt`, `damage_taken`, plus `wrecks_dealt`, `wrecks_suffered`, `self_hits`. - Self-hits count only in `self_hits`. - Powerup wrecks come from the hit event. Collision wrecks come from the health poll. - Totals reset when a race ends, because the first powerups are fired before the feed sees lap 1. **Docs and example** - `docs/state-websocket.md` updated. - The live-timing example gets HITS and WRECKS columns in the final classification. **Verification** (recomp, bot scenarios; I regenerated the recompiled code first because the checked-in copy predated the event-send hook) - SP: 298 use / 160 collect / 92 hit events; final totals match the event log for all 20 racers. - Split-screen (2 pads): final totals match the event log. - 2-instance LAN: use and hit totals identical on both instances after mapping racer indices. Collections differ only by polling noise (one remote out-of-range kind, now filtered). The LAN bot race did not reach a finish within 500 s, so I compared the live `standings` totals. - `race_feed`, `hit_event`, `game_state` and `state_ws` ctests pass. I did not run the full test suite or `/code-review`, and I did not check the live-timing page in a browser. - Decoy counts are left for #36.
Author
Owner

Completed and merged by Harmonic (task 33).

Completed and merged by Harmonic (task 33).
Sign in to join this conversation.
No description provided.