The Decoder found it in the format: a nested record is itself a RATC bundle and its header's +0x08 is the LOOP LENGTH. A record's keyframes need not fill it and the slack is a hold at the final pose, so ptbtn00f is 105 units of ramp inside a 120-unit cycle -- the glow rests dark for 15 units. The five ptbtn0Nf records fill their 120 exactly, which shows the slack belongs to that record and not to the format. Disc-wide over 1781 timed nested records: 92.3% declare exactly their last keyframe time, 7.7% more, 0 LESS -- the falsifier never fires. THE DECISIVE TEST USED THIS PORT'S NUMBER. Both candidates need the same emulator pacing factor, and the ring measures it independently: declared 120 -> 2.177 s -> 1.0885. 105 units needs 1.211-1.337 to reach the measured 2.12-2.34 s, which EXCLUDES it; 120 units needs 1.060-1.170, which CONTAINS it. Two different elements in different bundles, separate runs, tied only by both declaring 120. My three readings in order are the useful record: 129 (105 + the since-deleted exit_ramp_units) fitted the measurement for a reason that evaporated; 105 (the group length) I shipped knowing it was 17% short; 120 is decoded. And the 123-vs-129 pair I once called unseparable STRADDLED the right answer without containing it -- the sharpest argument I have seen against treating "two candidates, nothing separates them" as if the truth must be one of the two. Verified bit-identical 120 units apart (mean 0), 0.061 at a quarter, 0.888 at half. Still authored because the pinned tag does not expose +0x08; delete the entry the day a tag does. THEIR rest() FLAG, CHECKED RATHER THAN ASSUMED: they warned a focus record is the kind of element rest() mishandles. Censused -- 34 focus-record elements, only 2 with a varying alpha, both ptbtn00f, whose rest.alpha of 80 IS their peak, exactly the pathology described. The port does not hit it because the plate draws through the loop path, and the other 32 are constant-alpha so rest() is safe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
133 lines
7.0 KiB
JSON
133 lines
7.0 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": 120,
|
|
"kind": "chosen",
|
|
"why": [
|
|
"120 units, and it is DECODED rather than chosen -- but it is still written",
|
|
"here because the field is not in the pinned crate yet. DELETE THIS the day a",
|
|
"tag exposes it and the exporter can emit it.",
|
|
"",
|
|
"A nested record is itself a RATC bundle with its own header, and that header's",
|
|
"+0x08 IS THE LOOP LENGTH -- the same field `ui_header_time_disc` already tests",
|
|
"as an animation length at the top level. A record's keyframes need not fill",
|
|
"it, and the slack is a hold at the final pose. `ptbtn00f` is 105 UNITS OF RAMP",
|
|
"INSIDE A 120-UNIT CYCLE, so the glow rests dark for 15 units before repeating.",
|
|
"The five `ptbtn0Nf` records on the main menu fill their 120 exactly, which is",
|
|
"what shows the slack belongs to this record and not to the format.",
|
|
"",
|
|
"Disc-wide over 1781 timed nested records: 92.3% declare exactly their last",
|
|
"keyframe time, 7.7% declare more, and 0 DECLARE LESS. That last row is the",
|
|
"falsifier -- a cycle cannot restart before its own last pose -- and it never",
|
|
"fires.",
|
|
"",
|
|
"AND IT SURVIVES THE OBJECTION THIS ENTRY RAISED, using THIS PORT's number.",
|
|
"Both candidate periods need the same emulator pacing factor, and the ring",
|
|
"measures it independently: declared 120 units -> 2.177 s = 1.0885.",
|
|
"",
|
|
" 105 units = 1.750 s nominal, needs a factor of 1.211-1.337 -> EXCLUDES it",
|
|
" 120 units = 2.000 s nominal, needs a factor of 1.060-1.170 -> CONTAINS it",
|
|
"",
|
|
"So 105 cannot reach the corpus's measured 2.12-2.34 s under any pacing the",
|
|
"ring also satisfies. At 120 the prediction is 2.177 s. Different elements,",
|
|
"different bundles, separate runs, tied only by both declaring 120.",
|
|
"",
|
|
"HISTORY, because the sequence is what makes this checkable: this entry read",
|
|
"129 (last keyframe 105 + the since-deleted exit_ramp_units), then 105 (the",
|
|
"group length under the corrected layout, which I shipped knowing it was 17%",
|
|
"short of every measurement). The 123-vs-129 pair I once called unseparable",
|
|
"STRADDLED the right answer without containing it.",
|
|
"",
|
|
"The ~3% between 2.177 and the corpus's 2.24 mean is four wall-clock samples of",
|
|
"a 2 s period; the Decoder looked for a further declared hold and found none."
|
|
]
|
|
}
|
|
},
|
|
"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."
|
|
]
|
|
}
|