re(ui): replicate the keyframe-time shift -- three elements, two screens
The case for reading +36 as "the time the NEXT pose is reached" rested on one element's fade-out shape, then on one element's hold duration. Both splash halves supply more, and they agree. element screen observed hold as decoded shifted palogo_gamearts developer splash 83 f 8 f 80 f palogo_seta developer splash 83 f 6 f 80 f palogo_sqex publisher splash >=77 f * 6 f 102 f * the capture opens mid-hold at frame 1, so 77 is a floor. The readings predict opposite structures. For palogo_gamearts, as decoded: hold 8f, in 80f, hold 2f, out 6f, out 2f -- an eighty-frame FADE-IN and a two-frame hold. Shifted: in 8f, hold 80f, out 2f, out 6f, out 2f. The capture shows an 83-frame hold and no fade-in at all. The elements that cannot discriminate are not contradicted: palogo_gamearts_eff observed in 7f / hold 7f / out 8f, and both readings give 8f phases -- with four blocks the shift only relabels which phase is which. So the glows, which is where Q1's linear law was measured, say nothing either way rather than arguing against. The decoder's default is still unchanged, and the reason is now articulated rather than assumed. The single thing opposing the shift is rest() on ptlogo_eff3, where the shifted reading makes the longest-dwell fallback return the bloom's 200% peak. That fallback is unsound whenever it runs -- it returns an endpoint of a movement, neither of which is held -- and checked: the shift does not fix it either. So the objection was never evidence about the times. Timing had three discriminating measurements; pose selection had a heuristic guessing. For the port: animation timing should use the shift; static composites are unaffected and the five screens' correlations stand. Classified measured, not decoded -- three elements in one screen family, not a disc-wide check.
This commit is contained in:
@@ -27,7 +27,7 @@ authored version can be deleted.
|
||||
|
||||
| | Question | State | Answer / link |
|
||||
|---|---|---|---|
|
||||
| Q1 | keyframe time unit + ramp shape | ✅ answered, 🟡 one gap | ramp is **linear**; **2 units per rendered frame**; **`1 unit = 1/60 s` — settled**, the idle title presents at 28.5 fps so the game is 30 Hz. 🟡 **The interpolation law is settled; the group TIMELINE for multi-keyframe elements is not** — `palogo_gamearts` is still at full alpha 9 frames after its declared `a=32`, and its declared 80-frame fade-in never draws — [`ui-keyframe-time-unit.md`](../re/ui-keyframe-time-unit.md) |
|
||||
| Q1 | keyframe time unit + ramp shape | ✅ answered, 🟡 one gap | ramp is **linear**; **2 units per rendered frame**; **`1 unit = 1/60 s` — settled**, the idle title presents at 28.5 fps so the game is 30 Hz. 🟡 **The interpolation law is settled; the group TIMELINE for multi-keyframe elements is not** — `palogo_gamearts` is still at full alpha 9 frames after its declared `a=32`, and its declared 80-frame fade-in never draws — [`ui-keyframe-time-unit.md`](../re/ui-keyframe-time-unit.md). ✅ **REPLICATED 2026-08-29 — for ANIMATION, read `+36` as the time the NEXT pose is reached.** Three elements across two screens: `palogo_gamearts` and `palogo_seta` hold full alpha for **83 frames** and `palogo_sqex` for **≥77**, where the current reading predicts **6–8** and the shifted one **80–102**. The elements that cannot discriminate (the `_eff` glows, on which the linear law was measured) fit both. ⚠️ Our decoder still defaults to the other reading (`SYLPHEED_KF_TIME_SHIFT=1` to flip) because it changes `rest()` on one element — but that is an unsound fallback guessing either way, so **static rendering is unaffected and animation timing should use the shift** |
|
||||
| Q2 | which build is which screen state | ✅ answered | `GP_TITLE` is **8 screens shipped twice, EN/JP**: 4/7 title art, 2/3 the `PRESS Ⓐ` plate, 5/8 main menu, 6/9 `EXTRAS`, 0/1 and 10/11 two unidentified `DELTASABER` plates — [`ui-title-build-map.md`](../re/ui-title-build-map.md) |
|
||||
| Q3 | paint order for the six screens | ✅ answered, ❔ tie-break | **decoded**: a `u16` layer key at `+0x0A` of each `T8aD` sprite header, stable-sorted with declaration index; unkeyed elements get an implied key. Confirmed on 5 measured orders + `EXTRAS` vs a capture. One residual: the **tie-break** is unknown and bites on one element of the title — [`structures/ui-paint-order-key.md`](../re/structures/ui-paint-order-key.md). ⚠️ **The key does not fully order a screen**: elements sharing a key are tied, and the tie-break is ❔ **undecodable from the bundle** — declaration table, `T8aD` header (exhaustive: every offset 0x00–0x7f at u8/u16/u32, both directions, **0** fields match the measured order against **64** for the control) and the RATC child order all give the same order the game does *not* use. Your exposure is **2 overlapping tied pairs on `EXTRAS`** — [`structures/ui-paint-order-derived-check.md`](../re/structures/ui-paint-order-derived-check.md) |
|
||||
| Q4 | button → GamePart | ✅ answered | **measured** which screen all **5** buttons open — `NEW GAME` → `DIFFICULTY` → `SELECT DATA`, not a hang. The **GamePart id is still a name match**, not a measurement — [`menu-navigation-semantics.md`](../re/menu-navigation-semantics.md) |
|
||||
|
||||
@@ -742,3 +742,11 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the
|
||||
inflated by my own duplicate runs. A slow thing observed under contention looks
|
||||
like a stuck thing, and the correction matters: an hour-scale gate can be run
|
||||
deliberately, a hung one cannot be run at all.
|
||||
* **Separate the question with evidence from the question tangled with it.** The
|
||||
keyframe-time reading was held back for several iterations by one objection:
|
||||
adopting it changes `rest()` on a single element. But `rest()` reaches the times
|
||||
only through a fallback that is unsound whenever it runs, and the shift does not
|
||||
fix that fallback either — so the objection was never about the times. Timing
|
||||
had three discriminating measurements; pose-selection had a heuristic guessing.
|
||||
When a conclusion is blocked, check whether the blocker is actually evidence
|
||||
about the same thing.
|
||||
|
||||
@@ -522,3 +522,9 @@ neighbourhood, not just the line.
|
||||
~45–60 minutes. The 3 h 26 m observed was that work at a load average of 9–14,
|
||||
inflated by my own two duplicate runs.
|
||||
[`test-suite-runtime.md`](test-suite-runtime.md)
|
||||
* "the case for the keyframe-time shift rests on a single element" → **no longer
|
||||
true.** Three elements across two screens discriminate and all favour it:
|
||||
`palogo_gamearts` and `palogo_seta` hold full alpha 83 frames, `palogo_sqex`
|
||||
≥77, against 6–8 predicted by the current reading and 80–102 by the shifted
|
||||
one. The `_eff` glows fit both and argue against neither.
|
||||
[`ui-keyframe-time-unit.md`](ui-keyframe-time-unit.md)
|
||||
|
||||
@@ -333,3 +333,60 @@ of build 7 to verify the result against.
|
||||
group's *timing* as unverified — and specifically should not expect a
|
||||
2-frame hold where the game holds 83 — while `rest()` and `screen render` remain
|
||||
as they are.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Replicated: three elements, two screens, and the shifted reading wins every time
|
||||
|
||||
**2026-08-29.** The case for reading `+36` as *"the time the NEXT pose is
|
||||
reached"* rested on one element's fade-out shape, then on one element's hold
|
||||
duration. Both splash halves supply more, and they all say the same thing.
|
||||
|
||||
Phase durations in frames (2 units/frame, from the `_eff` glow ramp):
|
||||
|
||||
| element | screen | observed hold at `a=255` | as decoded | shifted |
|
||||
|---|---|---|---|---|
|
||||
| `palogo_gamearts` | developer splash | **83 f** | 8 f | **80 f** |
|
||||
| `palogo_seta` | developer splash | **83 f** | 6 f | **80 f** |
|
||||
| `palogo_sqex` | publisher splash | **≥ 77 f** * | 6 f | **102 f** |
|
||||
|
||||
\* the capture opens mid-hold at frame 1, so 77 is a floor, not the length.
|
||||
|
||||
The two readings predict **opposite structures** for these elements. On
|
||||
`palogo_gamearts`, as decoded: `hold 8f, in 80f, hold 2f, out 6f, out 2f` —
|
||||
an eighty-frame *fade-in* and a two-frame hold. Shifted: `in 8f, hold 80f,
|
||||
out 2f, out 6f, out 2f` — an eight-frame fade-in and an eighty-frame *hold*.
|
||||
The capture shows a **83-frame hold** and no fade-in at all.
|
||||
|
||||
### And the elements that cannot discriminate are not contradicted
|
||||
|
||||
`palogo_gamearts_eff` observed `in 7f, hold 7f, out 8f`. As decoded it reads
|
||||
`in 8f, hold 8f`; shifted it reads `hold 8f, out 8f`. Both fit — with only four
|
||||
blocks the shift relabels which phase is which without changing any duration. So
|
||||
the glows, which are what Q1's linear law was measured on, **do not argue against
|
||||
the shift**; they simply say nothing about it.
|
||||
|
||||
### 🟡 Why the decoder's default is still unchanged
|
||||
|
||||
The one thing that opposes the shift is `Element::rest()` on `ptlogo_eff3.t32`,
|
||||
where the shifted reading makes the longest-dwell fallback return the bloom's
|
||||
200 % peak instead of an invisible frame. But that fallback is **unsound whenever
|
||||
it runs** ([resting pose](structures/ui-resting-pose.md)) — it returns an
|
||||
endpoint of a movement, and neither endpoint is held. Checked: the shift does not
|
||||
fix it either, so this is not a case of two readings disagreeing about the times.
|
||||
It is a heuristic guessing, in both.
|
||||
|
||||
**So the two questions are separable, and only one of them has evidence.** The
|
||||
times govern animation; `rest()` picks a static pose through a rule that consults
|
||||
them only after its own precondition has failed.
|
||||
|
||||
### ⚠️ What a port should do
|
||||
|
||||
For **animation timing**, read `+36` as the *next* pose's time: three elements
|
||||
across two screens, each off by an order of magnitude under the other reading.
|
||||
For **static composites**, nothing changes — `screen render` is unaffected, and
|
||||
the five screens' correlations stand ([acceptance](five-screens-acceptance.md)).
|
||||
|
||||
🟡 Classified **measured, not decoded**: this is three elements in one game
|
||||
screen family, not a disc-wide field check, and our own decoder still defaults to
|
||||
the other reading behind `SYLPHEED_KF_TIME_SHIFT=1`.
|
||||
|
||||
Reference in New Issue
Block a user