feat: RFC 3339 timestamps, quoted switch names, buttons-only switch log
All GAMELOG lines (EV/SHOT/SCORES/AWARD in mode.log, the runtime's MODE START/END and AWARD lines) and every switch.log line now carry the wall clock as RFC 3339 UTC with millisecond precision; the +Nms stamps relative to runtime load are gone (dur= on MODE END stays: it is a duration). The timestamp comes from a new gl_rfc3339() in the runtime: clock_gettime (CLOCK_REALTIME) plus the civil-from-days algorithm, no libc time calls. switch.log now logs only the human-activated buttons (34 lockdown, 36 start, 62/63 flippers) with quoted names. The upper-flipper button switches (64/65) fire in parallel with the main flipper buttons on this cabinet and are left out with every non-button switch. Deployed and verified on the machine: the boot banner reads 2026-10-13T01:39:39.640Z against the machine's own UTC clock. Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
# stern-event-agent
|
||||
|
||||
A passive gameplay-event logger for Stern Spike 2 pinball, developed against
|
||||
**King Kong LE 0.97**. It records the game's own events with millisecond
|
||||
timestamps — the game is not modified, nothing scores, nothing blocks.
|
||||
**King Kong LE 0.97**. It records the game's own events with RFC 3339 UTC
|
||||
timestamps (millisecond precision) — the game is not modified, nothing scores,
|
||||
nothing blocks.
|
||||
|
||||
The logger is a PAD mode: a small shared object (`mode.so`) that the game
|
||||
process loads via `LD_PRELOAD`. It hooks function sites inside the game, and
|
||||
@@ -44,24 +45,24 @@ framework) and added to `ports/king_kong_le-0.97.port`.
|
||||
|
||||
### `/dump/mode.log` (deployed)
|
||||
|
||||
Append-only, millisecond stamps relative to the runtime loading, survives
|
||||
Append-only, RFC 3339 UTC stamps with millisecond precision, survives
|
||||
reboots:
|
||||
|
||||
```
|
||||
[pad] port ...: king_kong_le 0.97, 121 sites, 55 shots <- runtime armed (all hook words verified)
|
||||
[GAMELOG] up: game king_kong_le 0.97, 55 named shots; event ids 77/37/52/40/200/198; extra_ball_award=13
|
||||
[GAMELOG] +2408751ms EV game_start - GAME START
|
||||
[GAMELOG] +2408751ms EV ball_start player=1 ball=1 score=0
|
||||
[GAMELOG] +2424007ms SHOT X1 player=1 ball=1 score=7,349,830 <- all 55 named shots
|
||||
[GAMELOG] +2644003ms EV ball_end player=1 ball=1 score=91,153,090
|
||||
[GAMELOG] +2644003ms EV bonus_end
|
||||
[GAMELOG] +2644003ms SCORES P1=95,421,190 P2=0 P3=0 P4=0
|
||||
[GAMELOG] +...ms EV tilt_warning player=1
|
||||
[GAMELOG] +...ms EV tilt player=1 ball=2
|
||||
[pad] gamelog: MODE START 5 (Island Scene Escape the Swamp) player=1 score=...
|
||||
[pad] gamelog: MODE END 5 (Island Scene Escape the Swamp) player=1 score=... mode_score=... dur=...ms
|
||||
[GAMELOG] +...ms AWARD EXTRA BALL (id=13) player=1 <- next ball logs as "ball N (EXTRA BALL)"
|
||||
[GAMELOG] +...ms AWARD id=<n> player=1 score=... <- every award screen
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z up: game king_kong_le 0.97, 55 named shots; event ids 77/37/52/40/200/198; extra_ball_award=13
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z EV game_start - GAME START
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z EV ball_start player=1 ball=1 score=0
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z SHOT X1 player=1 ball=1 score=7,349,830 <- all 55 named shots
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z EV ball_end player=1 ball=1 score=91,153,090
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z EV bonus_end
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z SCORES P1=95,421,190 P2=0 P3=0 P4=0
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z EV tilt_warning player=1
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z EV tilt player=1 ball=2
|
||||
[pad] gamelog: 2026-10-12T20:45:12.123Z MODE START 5 (Island Scene Escape the Swamp) player=1 score=...
|
||||
[pad] gamelog: 2026-10-12T20:45:12.123Z MODE END 5 (Island Scene Escape the Swamp) player=1 score=... mode_score=... dur=...ms
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z AWARD EXTRA BALL (id=13) player=1 <- next ball logs as "ball N (EXTRA BALL)"
|
||||
[GAMELOG] 2026-10-12T20:45:12.123Z AWARD id=<n> player=1 score=... <- every award screen
|
||||
```
|
||||
|
||||
Bus event ids (King Kong 0.97): `game_start`=0x4d, `ball_start`=0x25,
|
||||
@@ -86,18 +87,22 @@ flow exactly as stock (and are logged once), and the logger adds no scores of
|
||||
its own. Known cosmetic issue: the boot banner still prints the upstream "score
|
||||
reports stay on this machine" line — the later `passive gate` line is the truth.
|
||||
|
||||
### `/dump/switch.log` (implemented, not yet deployed)
|
||||
### `/dump/switch.log` (deployed)
|
||||
|
||||
The runtime's switch-edge handler writes **every edge of every switch** to
|
||||
`/dump/switch.log` — buttons included, attract included:
|
||||
The runtime's switch-edge handler writes every edge of the human-activated
|
||||
buttons to `/dump/switch.log` — the lockdown/action button (34), the start
|
||||
button (36) and the two flipper buttons (62/63), attract included. Names are
|
||||
quoted; the upper-flipper button switches (64/65) are wired in parallel with
|
||||
the main flipper buttons on this cabinet, so they are left out:
|
||||
|
||||
```
|
||||
<ms> SW <id> <NAME> level=<0|1> hit=<0|1> game=<0|1>
|
||||
2026-10-12T20:45:12.123Z SW <id> "<NAME>" level=<0|1> hit=<0|1> game=<0|1>
|
||||
```
|
||||
|
||||
`level` is the switch's raw state after the edge, `hit` is the game's own
|
||||
"counts as a hit" verdict, `game` whether a player is up. Names come from
|
||||
`switch_names.inc`; an id not in the table logs `?`.
|
||||
"counts as a hit" verdict, `game` whether a player is up. The logged ids are
|
||||
the `gl_buttons[]` list in the runtime's switch-edge handler; names come from
|
||||
`switch_names.inc`.
|
||||
|
||||
## Build
|
||||
|
||||
|
||||
Reference in New Issue
Block a user