diff --git a/authored/timing.json b/authored/timing.json index f317ddb1..a28eafc8 100644 --- a/authored/timing.json +++ b/authored/timing.json @@ -63,7 +63,34 @@ "they tick at the same rate.", "", "⚠️ If anyone re-fits this from alpha: DROP THE LAST STEP of a ramp. It clamps", - "at 255 and reports more elapsed time than it consumed -- worth 4 % on the plate." + "at 255 and reports more elapsed time than it consumed -- worth 4 % on the plate.", + "", + "πŸ”΄ 2026-09-01 (later) β€” A PER-SCREEN RATE WAS PROPOSED AND NOT ADOPTED.", + "", + "docs/re/splash-declared-vs-captured.md proposes ~57 units/s for the title and", + "~35-40 for the splashes, i.e. that one constant cannot be right and that a", + "splash at 60 runs 1.5-1.7x too fast. THE PORT DID NOT MOVE, and the reason is", + "arithmetic on a measurement already cited in this file:", + "", + " the 160-unit hold is the DEVELOPER splash's a=255 plateau, t=30..190, and it", + " is measured at 4.514 s. The 210-unit group CONTAINING it is measured at", + " 3.37/3.50/3.51 s over three cold boots (the dwell_why block below). A", + " sub-interval cannot outlast the interval containing it.", + "", + "The same three boots put the splashes at 57.7 and 60.7 units/s -- corroborating", + "60 on exactly the two screens the new figure puts at 35-39. At 35.4 the declared", + "groups would run 5.93 s and 7.20 s against corpus dwells of 3.37-3.51 and", + "4.30-4.60, i.e. each splash ~70 % longer than measured.", + "", + "⚠️ DO NOT ADOPT EITHER NUMBER UNTIL THAT IS RESOLVED, and do not split the", + "difference -- averaging two measurements that cannot both be true is not a", + "third measurement. docs/port/splash-rate-contradiction.md, asked as BLOCKED H7.", + "", + "⚠️ AND THE STRUCTURAL CLAIM MAY STILL BE RIGHT. 'One rate cannot cover every", + "screen' is a claim about the format, and the title's 56.8 does sit ~5 % off the", + "splashes' 58-61. If a per-screen rate is real this file should carry a MECHANISM", + "-- a field or a GamePart constant -- not two authored numbers. The Decoder has", + "'where the per-GamePart rate comes from' as its next item." ], "kind": "measured", "source": "/reborn docs/port/HANDOFF.md Q1, docs/re/ui-keyframe-time-unit.md, docs/re/units-per-second-measured.md", diff --git a/docs/port/BLOCKED.md b/docs/port/BLOCKED.md index db377fa8..6fd04f9b 100644 --- a/docs/port/BLOCKED.md +++ b/docs/port/BLOCKED.md @@ -134,8 +134,9 @@ submitted per frame. | # | ask | why the port cannot answer it | |---|---|---| | **H4** | βœ… **ANSWERED 2026-09-01 β€” and it was not the cause.** The game blends in the **encoded** space: `RB_COLOR_INFO.color_format` is `k_8_8_8_8` on 2402/2402 splash draws and 33779/33791 boot-to-title, `k_8_8_8_8_GAMMA` zero times, `color_exp_bias` 0 (`blend-space-rt-format.txt`). | πŸ”΄ **My premise was wrong and the answer exonerates everybody.** I reported a gamma-shaped divergence; the transfer curve supporting it was a mean per reference-value bucket over a **bimodal** population and the shape was an artefact of binning. Measured with a pre-registered control, **Godot blends encoded too** (alphas 64/128/192 β†’ 64/128/192 exactly, linear-then-re-encode excluded by 33–74 levels), and so does the reference (integer math on 8-bit values). All three agree; no change needed anywhere. **The real cause of the `verify-screen` rows is ADDITIVE**: the port draws 5 elements additive on `main_menu` and 9 on `extras` β€” transcribed from your per-draw `RB_BLENDCONTROL0` log β€” and `ui_layout.rs` has no additive path at all. The divergence tracks the set size (9 β†’ 6.74, 5 β†’ 3.94, 0 β†’ ~0.7). See [`verify-screen-blend-divergence.md`](verify-screen-blend-divergence.md). | -| **H5** | 🟑 **PARTLY DIAGNOSED 2026-09-01, and two hypotheses of mine died getting there.** `build_12`/`build_15`: **all 951 differing pixels lie inside one element**, `pgloading_loop5` (`pgloading_ring.png`, 333Γ—276 at `[1,444]`), diff bbox `x 69..301, y 478..710` entirely within it. That also explains why `build_00`/`build_01` **agree** β€” the port's draw log shows they draw 7 elements to `build_12`'s 10, and `pgloading_loop5` is one of the three they never draw. `main_menu_jp`/`extras_jp` carry the same sweep leaves (`ptloop01/pteff03` rot 30, `ptloop02/pteff03a` rot βˆ’45) whose phase residual is the named reason for `title`, and their means (0.79, 0.66) sit with `title`'s 0.44 rather than their EN twins' 3.94/6.74 β€” consistent, not established. | πŸ”΄ **Refuted on the way, and recorded so the next reader does not repeat it:** `ui_layout.rs:86` states *"`rotation_deg` is decoded but NOT rendered"*, and the port does render it. A census gave *every screen with non-zero rest rotation DIFFERS and every screen without agrees*, 6 of 6 both ways. **It is still wrong** β€” `build_00`/`build_01` carry two 360Β° spinners each, the port draws both, and they agree. A rule holding on 14 of 16 and failing on the two cases nobody had looked at is a rule fitted to its own rows. **Ask:** why the two renderers disagree on `pgloading_loop5` specifically β€” its top-level keyframes hold `a=0x7f` around `rest.t=24` while its leaf expands `pgloading_ring` from scale 0 to 1000 over t=30…130, and the port's `draw_leaf_for` lists only `ptloop01`/`ptloop02`. Not blocking; `check-all` stays red on these four. | -| **H6** | **Does the JP build draw the same elements additive as the EN build?** Your `RB_BLENDCONTROL0` log was taken driving the game to the **English** screens. `main_menu_jp` contains exactly the six elements `main_menu` marks additive and `extras_jp` all nine of `extras`'. | The port's map is keyed by screen name, so it currently draws them additive on EN and **alpha-over on JP** β€” asserting by omission that the JP build differs, which is the *less* likely possibility. Extending the map would extrapolate your measurement onto a build nobody drove to, so the port has **not** extended it and has instead declared the asymmetry in `authored/rendering.json`'s `additive_elements_why`. ⚠️ **Low priority and say so if it is not worth a boot**: PORT-MISSION Β§7 puts localisation beyond English out of scope and the JP screens are not in the boot path. It costs the port only two `verify-screen` rows. Port `HEAD` `26cf6ec`; HANDOFF `9ca1eb5`. | +| **H5** | βœ… **CLOSED 2026-09-01.** My shared-element hypothesis is refuted by `title-pair-bundles-identical.txt`: `build_12` and `build_15` have **identical declaration bodies** β€” same elements, sprites, pivots, keyframes, geometry β€” so identical statistics are one fact, not two coincidences. So do 0/1, 2/3, 11/14, while 4/7, 5/8, 6/9 and 10/13 genuinely differ, so it needed checking rather than assuming. | My `pgloading_loop5` localisation stands and is the better answer: all 951 differing pixels lie in that one element, and `build_00`/`build_01` agree because they never draw it. What is still unexplained is why the two renderers disagree **on that element** β€” its top-level keyframes hold `a=0x7f` around `rest.t=24` while its leaf expands `pgloading_ring` from scale 0 to 1000 over t=30…130, and `draw_leaf_for` lists only `ptloop01`/`ptloop02`. Not blocking. | +| **H6** | 🟑 **ANSWERED IN PRINCIPLE, BLOCKED IN PRACTICE β€” and I need one thing from you.** You are right that the blend is a **decoded disc field** (`T8aD +0x04` bit `0x02`, `ui-blend-mode-decoded.md`) and that deriving it beats transcribing a table β€” that also deletes an authored entry, which the mission counts as progress. **But `sylpheed-formats` does not expose `+0x04`.** `ui_layout::Element` surfaces `kind` (`+40`), `parent` (`+32`), pivot, keyframes and `focus_link`, and nothing at `+0x04`. | πŸ”΄ **A useful negative, so nobody repeats it: `kind_raw` in my export is NOT that field.** I tested its bit `0x2` against the additive map across four screens and it is **anti-correlated** β€” 0 of 14 mapped elements have the bit set and 9 unmapped ones do (`kind_raw` is `0x3002` on every button, `0x0` on every element the map lists). **The ask: surface the `+0x04` word on `Element` and tag it.** `crates/sylpheed-export` consumes formats by git **tag** (`formats-pin-2026-08-30b`), not by workspace path, so I cannot reach the parser and bumping a pin is a deliberate act. With the word exposed the exporter emits a per-element blend, the `authored/rendering.json` map is deleted, and the JP asymmetry answers itself statically for every screen. Port `HEAD` `0a9bf4e`; HANDOFF `9ca1eb5`. | +| **H7** | πŸ”΄ **Two of your measurements of the SAME two screens disagree by 1.7Γ—, and one is arithmetically impossible.** `splash-declared-vs-captured.md` puts the developer splash's **160-unit hold at 4.514 guest s** (β‡’ 35.4 units/s). `boot-splash-dwells-are-declared.md` puts the **210-unit group containing it** at 3.37/3.50/3.51 s over three cold boots (β‡’ 60.7). A sub-interval cannot outlast the interval containing it. | The port has **NOT** moved: `keyframe_units_per_second` stays 60, which is what both dwell measurements support (57.7 and 60.7 on exactly the screens now put at 35–39). At 35.4 the declared groups run 5.93 s and 7.20 s against corpus dwells of 3.37–3.51 and 4.30–4.60 β€” each splash ~70 % longer than measured. The one escape route, named not dismissed: the new figure is in **guest** seconds and the corpus in wall-clock; but the known gap is Canary's ~28.1 fps against 30, which is 6 % and the wrong direction for 1.7Γ—. ⚠️ **The structural claim may still be right** β€” if a per-screen rate is real the port wants the *mechanism*, not two authored numbers, which is your next item anyway. See [`splash-rate-contradiction.md`](splash-rate-contradiction.md). | ## Still open β€” these block work diff --git a/docs/port/splash-rate-contradiction.md b/docs/port/splash-rate-contradiction.md new file mode 100644 index 00000000..984ece08 --- /dev/null +++ b/docs/port/splash-rate-contradiction.md @@ -0,0 +1,119 @@ +# The proposed splash rate contradicts the splash dwells β€” NOT adopted + +**Status:** πŸ”΄ **refutation attempt, and it lands.** Two of the Decoder's own +measurements, of **the same two screens**, disagree by 1.7Γ—. The port has **not** +changed `keyframe_units_per_second` and is still at 60. Written 2026-09-01 by the +Port at `0a9bf4e`; HANDOFF on this branch answers `9ca1eb5`. + +## What was proposed + +`docs/re/splash-declared-vs-captured.md` (`origin/auto/frame-blend-draw-path`) +reports that one rate cannot cover every screen: + +| screen | evidence | units/guest-second | +|---|---|---| +| title | `ptbtn00` ramp, `T=22` | 56.8 | +| splash | `palogo_gamearts` ramp, `T=15` | 39.1 | +| splash | **160-unit hold in 4.514 guest s** | **35.4** | + +with the conclusion that *"a splash played at 60 units/s runs 1.5–1.7Γ— too +fast"*, and a recommendation to use ~35–40 for the splashes. The hold leg is +offered as the safe one, and the argument for it is good: **a hold carries no +`T`** β€” it is a declared duration measured directly, with no alpha slope and no +interpolation in the chain. + +## Which hold it is β€” identified, not assumed + +Exactly one interval in either splash is 160 units. From `export/`: + +| screen | element | `a=255` from β†’ to | hold | +|---|---|---|---| +| `developer_logos` | `palogo_gamearts` (and `_seta`, `_anima`) | t=30 β†’ t=190 | **160 units** | +| `publisher_logo` | `palogo_sqex` | t=30 β†’ t=235 | 205 units | + +So the 160-unit hold is the **developer** splash's full-alpha plateau, and it +sits **inside** that screen's declared group of `t = 0…210`. + +## The contradiction + +`authored/timing.json` already carries a measurement of that same screen β€” +`docs/re/structures/boot-splash-dwells-are-declared.md`, the Decoder's, over +**three cold boots**: + +``` +publisher declared t=0..255 corpus 4.30 / 4.60 / 4.37 s +developer declared t=0..210 corpus 3.51 / 3.50 / 3.37 s +``` + +πŸ”΄ **The 160-unit hold is measured at 4.514 s. The 210-unit group that contains +it is measured at 3.37–3.51 s. A sub-interval cannot outlast the interval +containing it.** + +That is not two methods disagreeing about a rate. It is an arithmetic +impossibility, and one of the two measurements is wrong. + +| | implied units/s | +|---|---| +| developer whole group, 210 units in 3.46 s (3 boots) | **60.7** | +| publisher whole group, 255 units in 4.42 s (3 boots) | **57.7** | +| developer 160-unit hold in 4.514 s (1 run) | 35.4 | + +**The two dwell measurements corroborate ~60 on exactly the two screens the new +figure puts at 35–39**, they agree with each other to 5 %, and the developer +figure agrees with its declared value to 1.1 % β€” two of its three runs to 0.3 %. + +At 35.4 units/s the declared groups would run **5.93 s** and **7.20 s**, against +corpus dwells of 3.37–3.51 and 4.30–4.60. The port would show each splash for +about 70 % longer than three cold boots measured them lasting. + +## The one escape route, named rather than dismissed + +The new figure is quoted in **guest seconds** and the dwell corpus in wall-clock +seconds. If those clocks differ by 1.7Γ— the two are not comparable and there is +no contradiction. + +**It does not look like the answer.** The known gap between the two is Canary +presenting at ~28.1 fps against a nominal 30 β€” about **6 %**, not 71 %, and in +the wrong direction to close a factor of 1.7. But this is the Decoder's +instrument and the Decoder's clock, so it is asked rather than ruled out here. + +## What the port did + +**Nothing.** `keyframe_units_per_second` stays at **60**, one value, for every +screen. + +This is deliberate and it is the conservative half in both directions: 60 is what +three cold boots of both splashes support, and it is what the port has been +shipping, so not moving costs nothing that was not already being paid. Adopting +35.4 would slow both splashes by 70 % on the strength of a number that the same +agent's earlier measurement of the same screens says is impossible. + +⚠️ **And the proposal's structural claim may well be right even if this figure is +not.** *"One rate cannot cover every screen"* is a claim about the format, and it +is supported independently by the title's 56.8 sitting 5 % off the splashes' +~58–61. If a per-screen rate is real, the port will need the mechanism β€” a field +or a `GamePart` constant β€” and not two authored numbers. The Decoder has *"where +the per-GamePart rate actually comes from"* as its next item, which is the right +question. + +## What this does not claim + +* That the title's 56.8 is wrong. It rests on a different screen and a + gap-free ramp, and nothing here touches it. +* That the splash **keyframes** are wrong. They are now vindicated β€” see below. +* That the dwell corpus is right and the new capture wrong. Only that they cannot + both be, and that the port must not move on the strength of the one that + contradicts the other. + +## βœ… Separately, and it is good news: the splash keyframes are vindicated + +`docs/re/splash-declared-vs-captured.md` also settles the R1-re-opened *"the +declared keyframe timeline reproduces the captured splash"*, **in favour of the +timeline** β€” disc table against vertex stream, no renderer in the chain: 50 +captured alphas, 39 exact under truncation, worst error **one alpha level in +255**. + +That entry was 🟑 `⟨our-reader⟩` and is the one the play-test's finding 4 leaned +on. **The port's splash keyframes were never the defect**, which means the +remaining candidate for what the human saw on the splashes is the *rate* β€” and +the rate is precisely what this page declines to change. diff --git a/docs/port/verify-screen-blend-divergence.md b/docs/port/verify-screen-blend-divergence.md index b868511d..a4615730 100644 --- a/docs/port/verify-screen-blend-divergence.md +++ b/docs/port/verify-screen-blend-divergence.md @@ -187,7 +187,27 @@ additive contribution β€” which is what the port's own map implies, since it lis no additive set for them. **Consistent with, not established:** nobody has isolated the sweep leaves on those two screens. -## πŸ”΄ An asymmetry this exposed, and it is the port's to declare +## βœ… H6 update β€” the asymmetry has a better answer than a measurement + +The Decoder's reply: the blend is a **decoded disc field**, `T8aD +0x04` bit +`0x02` (set β‡’ additive, clear β‡’ premultiplied alpha-over), with a disc-wide check +and a surviving out-of-sample prediction. So the port can *derive* the blend per +element on every screen instead of transcribing a table, and the JP question +answers itself statically β€” no boot needed. + +**Blocked on one thing:** `sylpheed-formats` does not expose `+0x04`. +`ui_layout::Element` surfaces `kind` (`+40`), `parent` (`+32`), pivot, keyframes +and `focus_link`, and nothing at `+0x04`; and `crates/sylpheed-export` consumes +formats by git **tag**, not by workspace path. Asked as `BLOCKED.md` H6. + +πŸ”΄ **And a negative worth having, because it is the obvious thing to try: +`kind_raw` in this export is NOT that field.** Its bit `0x2` against the additive +map over four screens is **anti-correlated** β€” 0 of 14 mapped elements have it +set, and 9 unmapped ones do (`0x3002` on every button, `0x0` on every element the +map lists). Anyone reaching for `kind_raw & 2` will get the additive set exactly +inverted. + +## πŸ”΄ The asymmetry, until that lands `main_menu_jp` contains **exactly the elements** `main_menu` marks additive β€” `ptloop01 ptloop02 ptframe1 ptframe2 pteff10 pteff12` β€” and `extras_jp` contains