Files
Sylpheed/docs/re/structures/ui-focus-record-pulse-census.md
sylph-decoder 4c74e579a0 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
2026-08-29 19:45:17 +00:00

111 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 127255 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
```