re: the black gap between screens is NOT a load -- measured, three legs

sylpheed-port's BLOCKED ask #2. The gap was the one quantity in the transition
with no rule: measured at 0, 3 and 2 frames across three transitions, and I had
proposed it might be a load, which would make it emulator- and storage-dependent
and unauthorable.

Leg 1, bundle size runs the wrong way. If the gap were the incoming bundle
arriving, the biggest bundle would gap longest. Build 4 is 12 278 666 B and gaps
ZERO frames; build 5 is 6 977 437 B and gaps 3 and 2.

Leg 2, ran title->menu a second time from cold. The outgoing ramp is
byte-identical (63, 127, 191, 255) and the gap is 3 frames in BOTH runs.

Leg 3, and the two runs are not a null comparison -- which is the objection leg 2
invites. The captures refute it themselves: press-to-first-change differs by ~12
frames between them (~25 against ~10). Something in this transition really is
cache-sensitive and moved by 0.4 s, while the gap did not move at all. The
control comes from inside the measurement rather than from an assumption that
conditions differed.

So the gap is deterministic to the frame and not a load. It is also not constant
across transitions (0, 3, 2, 3) and not in the fade group -- the port reports 866
keyframes across 16 screens with 0 untimed. A deterministic game quantity with no
rule found; black_hold_units stays 0, and "not a load" must not become a reason
to author a constant.

The load proposal in screen-transitions.md is marked refuted rather than deleted.

Also fills in docs/game/navigation.md, which the standing brief asks me to keep
and which I had not touched while measuring four transitions: a player-side
section on what a screen change looks like, and three scripting traps -- that
`pkill -f xenia_canary` kills the shell that ran it (cost a launch today, and the
same trap is already in METHOD for pgrep), that screen_id.py reports `menu`
during the attract loop, and that it cannot tell EXTRAS from the main menu.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
sylph-decoder
2026-08-30 14:28:00 +00:00
parent 6afe0c4ab8
commit e803930e88
4 changed files with 192 additions and 18 deletions

View File

@@ -248,7 +248,7 @@ that the game does not have.
## ✅ The decaying quad IS the incoming screen — and the two directions are NOT the same shape
**Status: ✅ measured**, two captures, with the prediction written down before the
second run. Data: [`data/fade-three-transitions.txt`](data/fade-three-transitions.txt).
second run. Data: [`data/fade-four-transitions.txt`](data/fade-four-transitions.txt).
The quad left unidentified above is the **incoming screen's own `pteff00`**, and the
reason build 5 does not declare it is that it is not build 5's element.
@@ -356,10 +356,69 @@ fit that, and I cannot explain it.
🔴 **The black gap is the quantity with no rule yet**: none, 3 frames, 2 frames
across three transitions. It is not a per-button property and not a constant.
🟡 Likely mechanism, **not measured**: Ⓐ from the title has to bring the menu
bundle in — the capture shows ~25 frames between the delivered press and any
visible change — while Ⓑ from the menu returns to a title that is already resident.
That would make the black interval a *load*, not a designed hold. Untested.
## ✅ The black gap is NOT a load — measured 2026-08-30 (the port's ask #2)
**Status: ✅ measured.** Three legs, one of them a repeat run that carries its own
internal control. Data:
[`data/fade-four-transitions.txt`](data/fade-four-transitions.txt).
### Leg 1 — bundle size runs the wrong way
If the gap were the cost of bringing the incoming bundle in, the biggest bundle
would have the longest gap. It has **none**:
| incoming build | bytes | black gap |
|---|---|---|
| 4 (title) | **12 278 666** | **0 frames** |
| 5 (menu) | 6 977 437 | 3 frames |
| 5 (menu) | 6 977 437 | 2 frames |
The 12.3 MB screen arrives with no gap at all while the 7.0 MB one gaps twice.
### Leg 2 — the same transition, twice, and the gap does not move
`title → menu` via Ⓐ, run twice from cold:
| quantity | run 1 | run 2 |
|---|---|---|
| outgoing quad rise | 6770: 63, 127, 191, 255 | 6467: **63, 127, 191, 255** |
| frames fully black | 70, 71, 72 = **3** | 67, 68, 69 = **3** |
| incoming decay | 255, , 127, 84, 63 | 255, 169, 127, 84, 42 |
| **press → first change** | ~25 frames | **~10 frames** |
**The gap is 3 frames in both, and the outgoing ramp is byte-identical.**
### Leg 3 — and the runs are *not* a null comparison
The obvious objection to leg 2 is that two runs under the same conditions prove
nothing. **The captures refute that themselves**: the press-to-first-change latency
differs by **~12 frames** between them (~25 against ~10). Conditions demonstrably
were not identical — something in this transition *is* I/O- or cache-sensitive and
moved by 0.4 s — and the black gap did not move at all. That is the control the
comparison needs, and it comes from inside the measurement rather than from an
assumption about the machine.
### What this establishes, and what it does not
***Not a load.** It does not scale with bundle size, and it does not move when
the transition's own latency moves by 12 frames.
***Deterministic**, to the frame, across runs.
***What it *is* remains open.** It is not in the fade quad's keyframes — the
port reports 866 keyframes across 16 screens with **0 untimed**, so there is no
hidden duration left in that group — and it is not constant across transitions
(0, 3, 2 frames). So: a deterministic quantity, not from the fade group, with no
rule yet. The port should keep `black_hold_units` at **0** rather than author a
constant; "not a load" removes the excuse for a machine-dependent number without
supplying a game-dependent one.
⚠️ **Reach:** two runs of one transition plus single runs of two others, all in
Xenia, all `GP_TITLE`. "Not a load" is measured against *this* emulator's variance;
a real console could differ, and nothing here reaches the other nine transitions.
🔴 **This section used to propose that the black interval was a LOAD.** That is
now **refuted** — see the three legs above. The ~25-frame press-to-change latency
is real and *is* variable (it measured ~10 in a second run), but it is a different
quantity from the gap, and the gap does not move with it.
### ⚠️ What this does to "sequence, not overlap"