Three things this iteration, and the middle one is the human's doing. P7 -- GATE MET, with an artifact. The path had been wired for some time (then_video S00A, skipped_chain, after_video -> title, and S00A.ogv in the export) and NOBODY HAD RUN IT. A milestone is done when its artifact exists, not when the wiring reads correctly. Pre-registered: unskipped, S00A is 93.78 s of media, so it should end on its own at ~94 s and hand off to title. Measured: video ended at 94.13 s -- +0.35 s, 0.4 % -- then -> title, plate raised, script complete at 96.83 s. Both predictions held. docs/port/p7-gate.md. And it genuinely decodes, checked because "ends at the right time" does not prove it: 45 frames in a 2.03 s window, 244 in an 18.91 s one. Scales with the window, sub-linearly, at the software fill ceiling -- those two runs predate the GPU. The counts are upper bounds and the port says so itself. Free corroboration of the fill-rate finding, from a direction it was not designed for: the unskipped run reports main_menu at 60.3 fps for 94 s, because the screen never changes during a movie. Same process, same container, same screen: 60.3 fps with one full-screen video texture on top, 9.7 fps drawing the menu's five additive full-screen quads. ❌ THE FINDING-4 FRAME-RATE CANDIDATE IS DEAD, tested rather than argued away. The human activated a hardware GPU in both containers; Godot takes it with no change on our side (NVIDIA GTX 1070 Ti, Vulkan 1.4.312, Forward+): publisher_logo 17.3-25.0 -> 69.4 fps developer_logos 16.7-22.8 -> 69.1 title 12.7-17.2 -> 61.1 main_menu 9.7 -> 59.6 Pre-registered that 5-7 full-screen textured quads at 720p is trivial for that card and the fade would get its full 45 steps. At 69 fps the 45-unit build-in gets 52 drawn steps and the companion glow's 15-unit rise gets 17 -- MORE frames than declared units, so every declared alpha is drawn and the quantisation is absent rather than reduced. So every candidate for finding 4 is now dead: keyframes vindicated against the vertex stream, companion quads drawn, blend space matching, settled pose at 0.01 %, no post-process pass, and the frame rate drawing every declared step. The port has nothing left that is KNOWN to be wrong about the splashes -- which is a statement about our knowledge, not about the port. The human saw something and nothing we can measure reproduces it. The next play-test is now the highest-value thing on this focus, and the rate line will say 60-something. One figure did not improve: main_menu's worst gap is 117 ms on the GPU against 150 ms on llvmpipe, essentially unchanged while the mean improved 6x. A hitch that survives a 6x fill speed-up is not fill. Likely first-frame cost, STATED AS UNTESTED, recorded rather than chased. check-all now asserts the display before any Godot step. Xvfb does not survive a container restart and LEAVES ITS SOCKET BEHIND, so Godot reports "X11 Display is not available", falls back to Wayland, fails that too, and exits non-zero -- and every Godot-backed step would have gone red for that one reason. Cost me one run before I noticed. Checked with xdpyinfo rather than by looking for the socket, because the stale socket is what makes it confusing. Also recorded from the P7 run, neither chased: Godot reports 4 leaked ObjectDB instances at exit on that path, and the menu bed keeps playing under the movie (already an open ask -- does the menu music duck?). Not settled: the 117 ms menu hitch; H6's +0x04 exposure; H1 (with the Decoder); the four red verify-screen rows; and what the human actually saw. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AHUQvXGyNcKonSEWsgWcX
96 lines
4.2 KiB
Markdown
96 lines
4.2 KiB
Markdown
# P7 — the new-game intro plays and returns to a defined state ✅
|
|
|
|
**Status:** ✅ **gate met, with an artifact.** Run 2026-09-01 by the Port at
|
|
`4be90c2` + this commit; HANDOFF on this branch answers `9ca1eb5`.
|
|
|
|
`PORT-MISSION.md` P7: *"New-game intro video after NEW GAME | Plays, then returns
|
|
to a defined state."*
|
|
|
|
The path had been **wired** for some time — `authored/flow.json` gives `ptbtn01`
|
|
a `then_video: "S00A"`, a `skipped_chain`, and `after_video: {goto: "title"}`,
|
|
and `S00A.ogv` is in the export. **Nobody had run it.** A milestone is done when
|
|
its artifact exists, not when the wiring reads correctly, and this file is the
|
|
difference.
|
|
|
|
## Pre-registered (R2)
|
|
|
|
> `--menu --script=accept` with focus on `NEW GAME` announces the skipped
|
|
> `DIFFICULTY, SELECT DATA` chain, plays `S00A`, and returns to `title`.
|
|
> Unskipped, `S00A` is 93.78 s of media, so it should end **on its own** at
|
|
> ≈94 s and hand off.
|
|
|
|
## What happened
|
|
|
|
```
|
|
menu on main_menu, focus ptbtn01
|
|
script[1] accept at 1.00 s
|
|
(NEW GAME) -> the real chain is DIFFICULTY -> SELECT DATA, then the movie.
|
|
Neither screen is in this export.
|
|
-> video S00A at 0.97 s (/work/export/video/S00A.ogv)
|
|
+ voice S00A
|
|
video ended at 94.13 s
|
|
-> title (authored: authored)
|
|
(after the movie) -> title
|
|
overlay press_start raised, settles at t=236
|
|
script complete after 96.83 s on title
|
|
```
|
|
|
|
**94.13 s against 93.78 s of declared media — +0.35 s, 0.4 %.** It ends on its
|
|
own, at the right time, and hands off. Both predictions held.
|
|
|
|
Artifacts: `s_00_start.png` (main menu, `NEW GAME` focused) and `s_01_accept.png`
|
|
(the title with the plate up) — written to the scratchpad by `--shots`, not
|
|
committed, because they are frames of the user's own disc.
|
|
|
|
## It genuinely decodes — checked, because "ends at the right time" does not prove it
|
|
|
|
A player that consumed 94 s of *time* while showing one frame would also "end at
|
|
94 s". So the frame counts, at two window lengths:
|
|
|
|
| window | frames shown | of 2813 |
|
|
|---|---|---|
|
|
| 2.03 s | 45 | 2 % |
|
|
| 18.91 s | **244** | 9 % |
|
|
|
|
Frames scale with the window — it is decoding, not stalled. **Sub-linearly
|
|
though**, 22.2 fps early against 12.9 fps over the longer window, and that is
|
|
the same software fill ceiling documented in
|
|
[`port-frame-rate.md`](port-frame-rate.md); these two runs predate the GPU.
|
|
|
|
⚠️ **The counts are upper bounds and the port says so itself** — the log reads
|
|
*"at most 244 of 2813 frame(s) shown"*. It cannot see inside `VideoStreamPlayer`,
|
|
so it reports what it can bound rather than a number it cannot support.
|
|
|
|
## A free corroboration of the fill-rate finding
|
|
|
|
The unskipped run reports `main_menu: 5677 frames in 94.13 s — **60.3 fps**`.
|
|
The screen never changes during a movie, so the rate line attributes the whole
|
|
playback to it.
|
|
|
|
**The same process, in the same container, on the same screen: 60.3 fps while a
|
|
full-screen video texture is on top, and 9.7 fps while drawing the menu's five
|
|
additive full-screen quads.** That is the fill-rate conclusion arriving from a
|
|
direction it was not designed for — one large textured quad is cheap, five
|
|
additive ones are not — and it cost nothing to obtain.
|
|
|
|
## Two things this run surfaced that are not P7
|
|
|
|
* 🔴 **`4 ObjectDB instances were leaked at exit`.** Godot's own warning, on
|
|
every run of this path. Small and at shutdown, so it costs a player nothing,
|
|
but it is a real signal that something in the video/overlay teardown is not
|
|
freed. **Not chased, recorded.**
|
|
* 🟡 **The menu bed keeps playing under the movie.** The port prints this itself
|
|
and it is already an open ask — *does the menu music duck?* — in
|
|
`BLOCKED.md`. Left audible on purpose rather than guessed at.
|
|
|
|
## What this does not claim
|
|
|
|
* That the skipped chain is right. `DIFFICULTY` and `SELECT DATA` live in
|
|
archives this milestone does not export; the port **announces the skip** rather
|
|
than pretending the sequence is complete, which is the honest half of a gate it
|
|
cannot fully reach.
|
|
* That `after_video: title` is what the game does. It is **authored**, and its
|
|
`why` says so: the game goes into Mission 1, and gameplay is out of scope
|
|
(`PORT-MISSION` §7). "Returns to a defined state" is the gate; `title` is the
|
|
state we defined.
|