FOUR THINGS, and the first is what MISSION section 3 calls the measure of
progress.
DELETED `exit_ramp_units` AND `exit_ramp_seconds`. They were authored because the
disc had no time slot on a group's final keyframe, so the ramp into it was the
one unknown duration per screen. Under the corrected record layout that keyframe
does not exist -- a group is an 8-byte header then frames x {u32 time; 36-byte
pose} and every pose is timed. VERIFIED DEAD BEFORE DELETING: setting it to 9999
(166 s) moved the boot's transitions by 0.04 s, which is wall-clock jitter, and
both uses in ScreenView are gated on a condition that no longer fires on any of
the export's 866 keyframes.
INVERTED THE FORMAT'S OWN RULE. `check.rs` enforced "the final keyframe has no
`t`; the disc has no time slot there" and FORMAT.md stated it. Both are now
backwards, and the validator fired 150 times on a re-export. I had not run
`check` between pinning the tag and measuring against the oracle -- the pixel
harness was green while the format validator was failing on every screen with a
multi-keyframe group. A correctness harness does not replace a format one; they
fail at different layers.
GUARDED A SCALE-0 LEAF, which the Decoder hit in its own renderer: its leaf
branch marked the element drawn unconditionally while the blit returned early on
zero scale, so a scale-0 leaf suppressed its parent and blanked the element --
live on all four loading screens. This port did not have the bug only because
authored/rendering.json happens not to list pgloading_loop5. That is an accident
of a gate written for another reason, not a defence, so `_draw_leaf` now reports
whether it drew and `_draw` falls back to the parent.
ISOLATED THE PACING QUESTION rather than leaving it as a suspected regression.
Legacy association: publisher 4.70 agrees, developer 3.92 DIFFERS. Corrected:
publisher 4.26 DIFFERS, developer 3.62 agrees. Both misses are ~0.03 s outside a
composite bound. The association traded which screen is marginally out; it did
not regress the pacing.
Bumped the pin c -> d for the parser and audio changes. Its headline renderer
change does not reach this port: sylpheed-cli builds from the workspace crate.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
120 lines
6.2 KiB
JSON
120 lines
6.2 KiB
JSON
{
|
|
"format": "sylpheed.timing/1",
|
|
"keyframe_units_per_second": 60,
|
|
"why": [
|
|
"HANDOFF Q1. The disc says a keyframe is at `t=30`; it does not say what a",
|
|
"`t` is. The unit was MEASURED off the running game, not decoded: a declared",
|
|
"15-unit fade lands on round(255*k/15) for all seven of its samples with k",
|
|
"stepping 2,4,6,8,10,12,14 on seven consecutive submitted frames -- so 2",
|
|
"units per rendered frame -- and the idle title presents at 28.3-28.8 fps,",
|
|
"a 30 Hz game, giving 60 units per second. A second line agrees: the",
|
|
"transition quad is declared black for 12 units, and a capture measured the",
|
|
"pure-black plateau at 0.17-0.23 s, where 12/60 = 0.20 s.",
|
|
"",
|
|
"Expressed as units-per-second rather than seconds-per-unit so the value is",
|
|
"exact rather than a repeating decimal a reader has to recognise.",
|
|
"",
|
|
"DELETE THIS FILE when a field on the disc is found that states the unit.",
|
|
"Nothing here is on the disc."
|
|
],
|
|
"kind": "measured",
|
|
"source": "/reborn docs/port/HANDOFF.md Q1, docs/re/ui-keyframe-time-unit.md",
|
|
"ramp": "linear",
|
|
"ramp_why": [
|
|
"Also HANDOFF Q1, and part of the same measurement: the fade lands on the",
|
|
"linear value at every one of the seven sampled frames, so there is no ease."
|
|
],
|
|
"dwell_seconds": null,
|
|
"dwell_why": [
|
|
"NOT SET, and not needed. A screen's dwell is its OWN keyframe group: the",
|
|
"publisher wordmark reaches its hold at t=235 (3.92 s) and the developer logos",
|
|
"at t=190 (3.17 s), both read from the disc. Adding a hold on top of that would",
|
|
"be inventing a number nobody measured, so the sequencer holds for zero extra",
|
|
"time and the pacing you see is the disc's own.",
|
|
"",
|
|
"If a capture ever times the real boot, this is where that number goes."
|
|
],
|
|
"looping_focus_records": {
|
|
"_": [
|
|
"WHICH focus records the port draws unconditionally, and loops. CHOSEN, and",
|
|
"deliberately a LOOKUP rather than a rule -- delete an entry the day the disc",
|
|
"or a capture states it.",
|
|
"",
|
|
"THE PRESS (A) PLATE GLOWS AND PULSES. Measured on the running game:",
|
|
"`ptbtn00f`, the plate's focus record, ramps alpha 0x00->0x50 and back, and",
|
|
"its period was timed four times at 2.12 / 2.19 / 2.34 / 2.31 s. You cannot",
|
|
"measure a period unless the thing repeats, so THAT IT LOOPS IS MEASURED. The",
|
|
"port drew nothing at all here, because press_start has no `buttons` and",
|
|
"nothing is focused.",
|
|
"",
|
|
"WHY A LOOKUP AND NOT A RULE, which is the part worth keeping. The spinning",
|
|
"ring is a RULE in the renderer (`spin_period_units`) because it has a",
|
|
"disc-wide check: 16 of 212 elements match its shape and all 16 are focus",
|
|
"rings, zero false positives. The obvious rule for a pulse -- a group whose",
|
|
"keyframes vary only in alpha and whose first and last alpha are equal -- was",
|
|
"CENSUSED BEFORE BEING WRITTEN and it fails: 82 OF 212 ELEMENTS MATCH,",
|
|
"including ptcopyright, palogo_sqex, ptmsg and every _eff fade-in. A renderer",
|
|
"rule on that shape would make the copyright notice pulse.",
|
|
"",
|
|
"Narrowing to focus records leaves exactly ONE distinct element (ptbtn00f,",
|
|
"plus its JP twin), and a rule justified by n=1 is a special case wearing a",
|
|
"rule's clothes. So it is written here, per element, by name."
|
|
],
|
|
"press_start/ptbtn00": {
|
|
"record_element": "ptbtn00f",
|
|
"period_units": 129,
|
|
"kind": "chosen",
|
|
"why": [
|
|
"129 units = the element's own group under the port's existing timing model:",
|
|
"its last timed keyframe is t=105 and the final untimed keyframe is reached",
|
|
"`exit_ramp_units` (24) later. NO NEW CONSTANT is introduced -- 24 is the",
|
|
"same authored value every other element's exit already uses.",
|
|
"",
|
|
"129 units is 2.150 s at 60 units/s, and 2.295 s at the ~28.1 fps that",
|
|
"emulator presents (56.2 units/s), against measurements of 2.12 / 2.19 /",
|
|
"2.34 / 2.31 s. It sits inside that spread at either rate.",
|
|
"",
|
|
"IT IS A CHOICE, and here is the alternative the data CANNOT rule out: the",
|
|
"cycle could restart at the group's first keyframe (t=6) rather than at 0,",
|
|
"giving 123 units = 2.050 s / 2.189 s at emulator rate. That ALSO sits",
|
|
"inside the measured spread. Nothing available separates them, so t=0 is",
|
|
"taken because it is where every other group in this port starts -- which is",
|
|
"consistency, not evidence.",
|
|
"",
|
|
"A fifth reading exists and is NOT averaged in: the Decoder re-picked its",
|
|
"troughs and got 2.628 s, having previously reported 2.369 from the same",
|
|
"run. It withdrew the estimate as too weak to resolve better than ~7%, so it",
|
|
"is recorded here and not used.",
|
|
"",
|
|
"WHAT DELETES THIS ENTRY: a capture that times the pulse against a landmark",
|
|
"in the same frame, or a loop flag decoded on the disc."
|
|
]
|
|
}
|
|
},
|
|
"exit_ramp_deleted_why": [
|
|
"DELETED 2026-08-29, and the deletion is the point.",
|
|
"",
|
|
"`exit_ramp_seconds` (~0.4 s) and `exit_ramp_units` (24) were AUTHORED because",
|
|
"the disc had no time slot on a group's final keyframe, so the ramp into it was",
|
|
"the one unknown duration per screen. Under the corrected record layout",
|
|
"(formats-pin-2026-08-29c onward) there IS no untimed keyframe -- a group is an",
|
|
"8-byte header then frames x {u32 time; 36-byte pose}, so every pose is timed",
|
|
"including the last. The unknown the constant stood in for does not exist.",
|
|
"",
|
|
"MISSION section 3: 'When the RE agent later decodes something you had",
|
|
"authored, delete the authored entry and let the exporter emit it. That",
|
|
"deletion is the measure of progress.'",
|
|
"",
|
|
"VERIFIED DEAD BEFORE DELETING, not assumed: setting it to 9999 (166 seconds)",
|
|
"changed the boot's transitions by 0.04 s -- wall-clock jitter, not a 166 s",
|
|
"ramp. Both of its uses in ScreenView were gated on `not last_frame.has('t')`,",
|
|
"which no longer fires on any of the export's 866 keyframes.",
|
|
"",
|
|
"The measurement it recorded is not lost: HANDOFF Q7's ~0.4 s fade-out and the",
|
|
"0.17-0.23 s black hold are still measured facts, and the hold is still used --",
|
|
"`tools/port/verify-dwell` compares a transition INTERVAL against the oracle's",
|
|
"visible SPAN plus that hold. What is deleted is the port's need to invent a",
|
|
"duration the disc now states."
|
|
]
|
|
}
|