# Play-test, 2026-09-01 — a human, a real controller, the port **The first time a person played this port on real hardware.** It found four things. Two were fixed on the spot by the human; two are open and are the **current focus of both agents**. ⚠️ This page is a record of observations, not a mission change. `PORT-MISSION.md` and the loop briefs carry the objective. ## What was found | # | finding | status | |---|---|---| | 1 | **Ⓐ and Ⓑ did nothing on the pad.** Could not skip the intro, could not open a submenu. | ✅ fixed by the human — `port/scripts/gamepad.gd` | | 2 | **The left stick moved the cursor far too fast.** | ✅ fixed by the human — latched to one step per deflection | | 3 | **The `PRESS Ⓐ` plate appears too late.** | 🔴 **OPEN** | | 4 | **The splash fade/blur is wrong** — the game's is *more pronounced*. | 🔴 **OPEN** | ## 1 & 2 — why no check caught them, which matters more than the fixes > **`--script` sends `InputEventAction`, which BYPASSES the input map.** Every check the port had asserted the code *below* the input map and nothing about the map itself. The map turned out to have **no joypad binding for `ui_accept` or `ui_cancel` at all** — measured on Godot 4.7.2, not remembered, because the remembered answer was wrong: ``` ui_accept key:Enter, key:Kp Enter, key:Space <- no joypad button at all ui_cancel key:Escape <- no joypad button at all ui_up key:Up, JOYBTN:11, JOYAXIS:1- <- d-pad AND left stick ui_down key:Down, JOYBTN:12, JOYAXIS:1+ ``` Four actions reached the pad and two did not. Ⓐ was dead for the whole of P5 while the unattended walk passed on every iteration. The **same blind spot** hid finding 2: an `InputEventAction` is not an analog axis, so nothing could observe that a stick held at deflection emits an event per *jitter*, each reporting the action as pressed — one cursor step per jitter. Now asserted by `tools/port/verify-input`, with a control that removes each check's own subject. (Its first version inverted all nine assertions when only two depended on the fix, and reported seven correct checks as broken. Three rows now say plainly they are **not controllable** — they assert Godot's own bindings — and one is a **negative carrying a positive control** rather than a faked inversion.) ### The standing rule that follows **Synthetic input is not a test of input.** Anything injected below the input map is evidence about the code above it and nothing else. A test of input must go in at the device level — `InputEventJoypadButton`, `InputEventJoypadMotion`, `InputEventKey` — or must assert the map directly. ## 3 — the plate is late The port raises the plate at `t=236`, **3.93 s** after the shared clock starts, which it derives as `238 − 118 = 120 units = 2.000 s` after the title's build-in ends. A human watching both says it is **late**. This lands in a spot the corpus already knows is soft. All of the following are live: * `REFUTED.md`: *"a screen has SETTLED at its `rest.t`"* → ❌ — believing `rest.t` had already put a port's plate **3.97 s late** once. * `REFUTED.md`: the 2.13 s figure was *"a wall-clock reading stretched by Canary presenting at ~28.1 fps"*, corrected to 120 units. **So the conversion between units and seconds is load-bearing here and is exactly what [`TEMPORAL-VERIFICATION.md`](TEMPORAL-VERIFICATION.md) says not to trust from a wall clock.** * The keyframe **time-unit shift** is unresolved (`ui-keyframe-time-unit.md`). * 🔴 After the 2026-09-01 R1 pass, *"the declared keyframe timeline reproduces the captured splash"* is **🟡 `⟨our-reader⟩`**, not ❌ — the record-layout fix re-times a group's final pose and the entry was never re-derived under it. **Candidate causes, none established:** the unit→seconds constant; the clock origin (do both builds really start together?); `rest.t` again; the record layout. Settle it by **ordering and counts**, not by a stopwatch. ## 4 — the splash fade/blur The port applies **no blur at all**. It draws declared keyframe alphas. So *"more pronounced in the game"* is consistent with a post-process the export does not describe, a different ramp shape, or both — and nothing in the export can distinguish those. 🔴 **And the two splashes are the ONLY screens that reach `rest()`'s plateau-less fallback** — title, main menu and `EXTRAS` reach it zero times. So finding 4 lands precisely where our resting-pose heuristic is least trustworthy, and the R1 pass just re-opened that question **in both directions** (see the `rest()` pair in `REFUTED.md`). That is not a coincidence to step around. ## The human's verdict on method > *"It seems the agents were essentially guessing and trying to copy what one > would see, but while they did get close it still is not quite right."* Close-but-not-right is the signature of reproducing **appearance** instead of deriving **mechanism**. A ramp tuned until it looks right is wrong in a way nobody can name and has no reach to the next screen. The instruction that follows: for the splashes, **find out what the game is doing** — is there a post-process pass, how many, what shader, what blend, what render targets, and where do its parameters come from — before proposing any curve. See the Decoder's brief.