re(flight): the clock factor is universal — angular matches too once corrected in-run

pitch_gametime.py brackets each turn phase with HUD screenshots, so the mission
clock's own advance converts wall seconds to game seconds within the same run:

  this run's clock: TIME 00:33.68 -> 00:44.12 = 10.44 s game in 7.96 s wall = 1.311

  pitch @ min speed  88.9 deg/wall-s  /1.311 -> 67.8 deg/game-s  vs AV_PitchMinus_Min 75
  pitch @ max speed  53.6            /1.311 -> 40.9             vs AV_PitchMinus_Max 40

Both land on the definition (the slow phase 10% low, consistent with including the
AA_* ramp in an 8 s window), so the clock explanation covers angular motion as well:
every stated rate is per GAME second.

The ratio is not a machine constant — 1.260 in the earlier flight, 1.311 here — so it
must be measured in the same run as whatever it corrects. Bonus: the same shots show
the HUD reading 102 at full LT against MinimumVelocity 100.

Also documents the trap that cost three runs: a killed Canary leaves both its shm
image and its last frame on screen, so a dead emulator looks alive and the scans
report "0 moving triples" like a tooling bug. pgrep -x matches zombies, so
speed_law.require_live_emulator() checks the process state letter and refuses to
measure a corpse.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NptfmpjdpNCKEez6d2xvA9
This commit is contained in:
2026-08-13 17:56:16 +00:00
parent ae5f322c03
commit 8b10c0451f
4 changed files with 458 additions and 3 deletions

View File

@@ -342,3 +342,45 @@ Either that agreement was luck inside a noisy sample (the per-window rates spann
6196), or angular integration is frame-based where linear is time-based. The check:
re-measure pitch and convert wall→game seconds with the clock ratio, expecting ~94
if the clock explanation is universal.
---
# ✅ The clock factor applies to the ANGULAR side too — and it varies per run
The open question was whether the ~1.26× mission-clock factor explains only the
linear measurements. Measuring **both in the same run** settles it
([`tools/re-capture/pitch_gametime.py`](../../tools/re-capture/pitch_gametime.py):
HUD screenshots bracket each turn phase, so the mission clock's own advance converts
wall seconds to game seconds):
```
this run's clock: TIME 00:33.68 -> 00:44.12 = 10.44 s game in 7.96 s wall = 1.311
```
| phase | wall-time rate | ÷ 1.311 → game-time | definition |
|---|---|---|---|
| pitch, minimum speed | 88.9 °/s | **67.8 °/s** | `AV_PitchMinus_Min` **75** (0.90×) |
| pitch, maximum speed | 53.6 °/s | **40.9 °/s** | `AV_PitchMinus_Max` **40** (1.02×) |
So with the clock correction both land on the definition (the slow phase runs 10 %
low, consistent with the `AA_*` ramp being included in an 8 s window). **The clock
explanation is universal**: every rate the game states is per **game** second, and a
probe that divides by wall seconds reads high by that run's ratio.
**And the ratio is not a constant of the machine — it varies with scene load**:
1.260 in the earlier flight, **1.311** here. It has to be measured *in the same run*
as whatever it is correcting, which is why this probe brackets its own phases with
HUD screenshots.
Bonus confirmation from the same screenshots: at full `LT` the HUD reads **102**,
against `MinimumVelocity` **100** — the throttle law's lower endpoint, in the game's
own units.
## The trap that cost three runs: a dead emulator looks alive
A killed Canary leaves **both** its `/dev/shm/xenia_memory_*` image *and* its last
frame on the X display. So the screenshot shows a mission in progress, the memory
image still parses, and the scans quietly report `0 moving triples` / "player entity
not found" — which reads like a tooling bug. `pgrep -x xenia_canary` does **not**
help: zombies match it. `speed_law.require_live_emulator()` now checks the process
*state letter* and refuses to measure a corpse, naming the stale image in its error.