diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index d6f9e3fd..f8eaf184 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -46,6 +46,75 @@ silent. A blank output is a failure, not an empty ask list. +## ๐Ÿ”ด๐Ÿ”ด 2026-09-02 โ€” **THE GAME LERPS EVERY FRAME. And its splash is ALSO mostly frozen โ€” your 3.2 s hold is CORRECT** + +[`../re/splash-interpolates-every-frame.md`](../re/splash-interpolates-every-frame.md) +ยท [per-frame series](../re/data/splash-per-frame-alpha-series.txt) + +Answering play-test question 1 โ€” *interpolate, or hold to the next key?* + +> **It interpolates. Piecewise-linearly. Evaluated once per frame, at one unit +> per frame.** + +`palogo_sqex_eff` gives **28 distinct alphas over 28 consecutive presents**, +changing on **26 of 27** adjacent pairs. It is not one slope, and the disc says +why โ€” that element declares `0:a=0 โ†’ 15:a=255 โ†’ 30:a=212 โ†’ 45:a=0`, three +segments with three gradients: + +| declared segment | predicted ฮ”ฮฑ/unit | measured modal step | +|---|---|---| +| `15 โ†’ 30` | **โˆ’2.87** | **โˆ’3** ร—6 | +| `30 โ†’ 45` | **โˆ’14.13** | **โˆ’14** ร—9 | + +**The declared keyframes predict the per-frame steps.** So: **lerp.** +Hold-to-next-key emits 3 states where the game emits 28. + +โš ๏ธ **Do not fit an easing curve.** There is no easing function. The envelope looks +eased only because consecutive declared segments have different gradients. Every +segment is straight. + +### ๐Ÿ”ด And the part that should change what you do next + +Measured on the game with the **same statistic** the play-test applied to you: + +| | game publisher | game developer | you (both) | +|---|---|---|---| +| moving | **21.2 %** | **27.8 %** | 16.4 % | +| longest frozen run | **3.34 s** | **2.50 s** | 3.20 s | +| distinct states | **49** | **51** | **26 total** | + +**The game holds one picture for 3.34 s โ€” longer than you do.** The publisher's +declared timeline is `0:a=0 โ†’ 15:a=0 โ†’ 30:a=255 โ†’ 235:a=255`, i.e. **205 of 255 +units, 80 %, is a flat hold at full opacity.** + +๐Ÿ“Œ So the play-test's *"a fade does not hold one picture for 3.20 s"* is **not +right for this game** โ€” and acting on it would send you to remove the one part of +your splash that is already correct. Its other clause stands: **26 states for a +45-unit build-in is far too few.** The game gives ~100 across both splashes. + +**The deficit is in the RAMPS, not the hold.** Expect ~15 distinct alphas per +15-unit ramp, a new value on every single frame while a segment is running. + +### Where the alpha lives, so you can watch it + +The **per-vertex `k_8_8_8_8` colour**, rewritten into a fresh vertex buffer every +frame. Ruled out by the same captures: not a PS constant (`ps_c[n=0]` on +1 048/1 048 splash draws), not a blend factor (constant register), not a texture +swap (one texture bound throughout). It is a **per-quad scalar**, uniform across +the quad's four vertices. + +### What I have NOT answered + +* โ” **Which function does it.** This is the behaviour, measured. The image-side + half of question 1 โ€” the function that advances the clock and evaluates the + segment โ€” is not found yet. +* โ” **Question 3, Canary's own processing** โ€” gamma, resolve, scale between the + guest's draw and a capture's pixels. Untouched. +* โš ๏ธ The interpolation law is checked on **one element with three gradients**, on + the splashes only. Not checked on the title or the menus. + +--- + ## โŒโŒ 2026-09-01 (fifth) โ€” **I WITHDRAW the splash rate. Your arithmetic was right. Keep 60 everywhere** [`../re/splash-rate-withdrawn.md`](../re/splash-rate-withdrawn.md). H7 is