Files
Sylpheed/docs/re/f1-menu-repeat-harness-built-not-answered.md
sylph-decoder 85d2e93d05 re: F1 harness built and committed; the run did not reach the menu
The port needs an initial delay and a repeat interval and has shipped the
mechanism with -1.0 rather than invent them. This builds the instrument and
does not get the numbers.

The vertex stream is the right instrument: C_PAD_DECODER has no timer on
any direction path, so the repeat is in the layer above and cannot be read
out of that function; a cursor move is a quad changing position, and the
guest's vertex buffer carries that with no Canary processing in the path.

tools/re-capture/menu_repeat_probe.sh arms the logger, drives the boot with
pad-file presses and holds a direction. It ran its whole sequence. But the
boot did not reach the menu: in the settled era every quad shape holds a
constant y, and the shapes are near-full-screen rects rather than a button
list. No cursor, so nothing to repeat.

Two instrument errors worth more than the failed run.

The first attempt ARMED NOTHING and said nothing -- xdotool search --class
... --window %1 F10 behind a || true. The run completed normally and only
the ABSENT log revealed it. The working form looks the window up by name,
activates it, and sends F10 to the window and globally; a missing window is
now fatal rather than tolerated, because a silent arming failure is
indistinguishable from a screen that draws nothing.

My first cursor detector measured the wrong change: presents where the SET
of quads changed, which fired on 157 of 161 adjacent pairs because during a
build-in everything animates. Tracking one quad shape's POSITION instead
correctly reports no motion. That is the play-test's own lesson landing on
me -- an instrument that measures change can still measure the change of
the wrong thing.

Next run must not drive the boot blind: gate the presses on a classifier or
join with boot_menu.sh, which reaches the menu but takes screenshots rather
than draw logs. Blind was chosen because screenshots cost ~10 s each while
xenia runs; wrong trade, since a mistimed press costs the whole run.

Reach: the negative is about this run, not the game. F1 stays open and the
port should keep its -1.0 constants.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
2026-09-02 16:41:55 +00:00

3.9 KiB
Raw Blame History

F1, the menu repeat rate — the harness works, the boot did not reach the menu

Status: not answered. Instrument built and committed; the run did not land. 2026-09-02. Instrument: ⟨capture⟩ attempted via tools/re-capture/menu_repeat_probe.sh.

The port needs two numbers — initial delay and repeat interval — and has shipped the mechanism with -1.0 constants rather than invent them. This iteration built the instrument to measure them and did not get them.


Why the vertex stream is the right instrument for this

C_PAD_DECODER has no timer on any direction path (pad-decoder-double-tap-not-key-repeat.md), so the repeat is in the layer above and cannot be read out of that function. A cursor move is observable as a quad changing position, and the guest's own vertex buffer carries that with no Canary processing in the path — the same instrument that settled the splash.

What the harness does, and it now works

Arms the draw logger, drives the boot with pad-file presses (press=A, then a held press=DOWN), and records per-frame vertex geometry throughout. The run completed its whole sequence:

armed at 8s (win=4194307)      A #1 at 21s      A #2 at 28s
A #3 at 31s      HOLDING DOWN at 36s      released at 48s      done at 51s

🔴 Why it still did not answer F1

The boot did not reach the menu. In the settled era (frames 520596) every quad shape holds a constant y:

quad shapes present: (1.77,0.78) (1.75,0.73) (1.43,0.32) (0.06,0.05) (1.55,0.29) (1.08,0.05)
moving shapes: none

Those are near-full-screen rects, not a list of menu buttons, and no quad moves at all — so there was no cursor to repeat. The blind timings did not land; the presses went somewhere other than where they were aimed.

⚠️ Two instrument errors on the way, both worth more than the failed run

1 — the first attempt armed nothing, and said nothing. It used xdotool search --class xenia_canary key --window %1 F10 behind a || true. The run completed normally and only the absent log revealed it. The working form, copied from ui_draw_capture.sh, looks the window up by name, activates it, and sends F10 to the window and globally. A failure to find the window is now fatal rather than tolerated — a silent arming failure is indistinguishable from a screen that draws nothing.

2 — my first cursor detector measured the wrong change. I counted presents where the set of quads changed, and got a change on 157 of 161 adjacent pairs. That is not the cursor: during a build-in everything animates, so set-membership tracks animation. Replacing it with "track one quad shape's position over time" correctly reports no motion — which is the right answer for a screen with no cursor, and is why the second detector is trustworthy where the first was not.

📌 This is the play-test's own lesson landing on me: an instrument that measures change can still measure the change of the wrong thing. motion-census exists because three port instruments measured a pose or a throughput; mine measured change, and still needed the change to be of the cursor.

What the next run should do differently

Do not drive the boot blind. The presses need gating on a screen classifier, or the documented boot_menu.sh path — which reaches the menu reliably but takes screenshots rather than draw logs, so the two harnesses need joining. The blind route was chosen because screenshot costs ~10 s per grab while xenia runs; that trade was wrong here, because a mistimed press costs the whole run.

Reach

The negative is about this run, not about the game: it says the presses did not land, not that a held direction fails to repeat. The human watched the real game and reports it does. F1 remains open, and the port should keep its -1.0 constants rather than take a number from anything here.