re: 210 focus records pulse, not 2 -- and 8 of them fail in a way that looks right

The port censused focus-record alpha over its own export -- 34 elements, 2
varying, both `ptbtn00f` -- and concluded there is nothing to fix. That is
correct and correctly scoped. This asks the same question of the whole disc.

1 130 focus records, 2 664 timed elements, 210 with a varying alpha. 202 have
`rest()` returning the PEAK, the `ui-settle-time` pathology. By pak:
PILOTLOG 116, MOVIE_THEATER 54, HANGAR_ARSENAL 30, LEADERBOARD 8, GP_TITLE 2.

So the port's 2 is right because GP_TITLE has 2. The scope was load-bearing
and was not stated as a limit -- "only 2 have a varying alpha" reads as a fact
about the format and is a fact about one pak. The pathology is concentrated in
exactly the screens a wider port reaches next.

The 8 LEADERBOARD ones are the worse mode. `py_ranking_btn01f` swings
255->127->255 with no two adjacent keyframes equal, so `rest()` falls through
to its longest-dwell rule and returns 244 -- neither the peak nor the trough.
A glow stuck at its peak is visibly wrong; one stuck at 244 of a 127..255
range looks entirely plausible and nothing reports it.

Verified rather than asserted: two hits dumped keyframe by keyframe, and a
control on `ptbtn01f`, which is genuinely constant across its cycle and is
correctly NOT flagged. `py_ranking_btn01f` also confirms the loop-length
decode independently -- its ramp ends at t=90 inside a declared 120-unit
cycle, holding bright for 30 units.

Reach stated: 210 is a floor. Focus records are matched by the `Xf.rat` name
rule, and elements with constant alpha but varying scale, rotation or
position have the same problem and are not counted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
sylph-decoder
2026-08-29 19:45:17 +00:00
parent 07e93ce041
commit f9638a05cf
4 changed files with 402 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
# Every focus record that pulses — and why `rest()` is wrong for 210 of them
**Classification: decoded.** A census of the whole disc, with a control on a
record the census does *not* flag, and two hits verified keyframe by keyframe.
## Why this exists
The `PRESS Ⓐ` plate's focus record `ptbtn00f` pulses 0 → 80 → 0, so its last hold
keyframe is the **peak**, and `rest()` leaves it at maximum brightness forever —
the pathology of [`ui-settle-time.md`](ui-settle-time.md) applied to a focus glow.
The port checked this over its own export and found **34 focus-record elements, 2
of them varying** — both `ptbtn00f`, EN and JP — and concluded there is nothing to
fix. **That is correct, and correctly scoped.** For the five screens the menu port
ships it is the whole story.
It does not survive leaving `GP_TITLE`.
## Disc-wide
[`focus-record-alpha-census.txt`](../data/focus-record-alpha-census.txt)
| | count |
|---|---|
| focus records (`Xf.rat` where `X.rat` also exists) | **1 130** |
| their elements carrying timed keyframes | **2 664** |
| **with a varying alpha** | **210** |
| …of which `rest()` returns the **peak** | **202** |
| …of which `rest()` lands **mid-ramp** | **8** |
| pak | varying focus elements |
|---|---|
| `GP_DEBRIEFING_PILOTLOG` | 116 |
| `GP_MOVIE_THEATER` | 54 |
| `GP_HANGAR_ARSENAL` | 30 |
| `GP_LEADERBOARD` | 8 |
| `GP_TITLE` | **2** |
So the port's 2 is right — and it is 2 because `GP_TITLE` has 2. The pathology is
concentrated in exactly the screens a wider port needs next.
## The three behaviours, verified by hand
**1. A seamless breathing loop** — `GP_MOVIE_THEATER` `px_movie_tn000f`:
```
t=0 a=64 t=4 a=80 t=26 a=238 t=30 a=255
t=60 a=255 t=70 a=236 t=110 a=80 t=120 a=64 cycle +08 = 120
```
Starts and ends at 64 and fills its declared cycle exactly, so it loops with no
seam. `rest()` returns **255** — the peak. 54 elements in this pak do this.
**2. A ramp that holds** — `GP_LEADERBOARD` `py_ranking_btn01f`:
```
t=0 a=255 t=8 a=244 t=42 a=140 t=50 a=127
t=56 a=140 t=84 a=244 t=90 a=255 cycle +08 = 120
```
The ramp ends at t=90 inside a 120-unit cycle, so it holds bright for 30 units —
another instance of [`ui-record-loop-length.md`](ui-record-loop-length.md). Here
`rest()` returns **244**, which is **neither the peak (255) nor the trough (127)**.
No two adjacent keyframes are equal, so `rest()` falls through to its longest-dwell
rule and lands mid-ramp.
🔴 **This is the worse failure mode.** A glow stuck at its peak is at least
visibly wrong. A glow stuck at 244 of a 127–255 range looks entirely plausible and
nothing reports it.
**3. The control — genuinely constant** — `GP_TITLE` `ptbtn01f`, one of the five
main-menu focus records:
```
ptbtneff01.t32 t=0 a=255 t=120 a=255
ptbtn01f.t32 t=0 a=255
```
Constant across its whole cycle. The census does **not** flag it, which is the
check that the census is detecting variation rather than flagging every focus
record it meets.
## What this does and does not change
* ✅ **Nothing about the menu port.** `GP_TITLE`'s two are the plate's, the port
draws the plate through its loop path, and the other 32 elements in its export
are constant-alpha. Its conclusion stands for its scope.
* 🔴 **The scope is load-bearing and was not stated as a limit.** "Only 2 have a
varying alpha" reads as a fact about the format; it is a fact about `GP_TITLE`.
Extending the port to the Hangar, the Movie Theater or the Pilot Log meets 200
of these, and 8 of them fail in a way that looks correct.
* ⚠️ **A pulsing element has no resting pose at all.** For these records the
question `rest()` answers is malformed rather than mis-answered: the element's
state is a phase, not a value. `pose_at(t)` with `t` inside the record's own
declared cycle is the only well-formed query.
## Reach
⚠️ **"Focus record" here is a name rule** — `Xf.rat` where `X.rat` is also
present, the same pairing `mark_focused_states` uses. A record that animates while
focused but is not named that way is not counted, so 210 is a floor.
⚠️ **Varying alpha only.** An element with constant alpha and a varying scale,
rotation or position has the same problem and is not counted here.
## Reproducing
```bash
cargo run -p sylpheed-formats --example focus_alpha_census
```