this container kills long runs Three results, and the middle one is deliberately not upgraded. First: NEW GAME -> DIFFICULTY -> NORMAL -> SELECT DATA -> pick a slot -> a movie plays, with no crash. The previous run's throw at 0x82307128 is therefore not inherent to the menu path -- the same six presses got through it -- which fits the incomplete-cache trigger the corpus already names. n=1 either way, and the note says so. Worth recording because one observation had already hardened once into "A on NEW GAME hangs", and it would have hardened again into "the new-game path crashes". Second: with the path open, the manifest's MS00A -> S00A.wmv finally got a runtime test, and it did NOT reproduce the quality of the attract-movie identification. The first four samples give a clean monotonic S00A playhead of 2, 6, 9, 13 s and the strongest frame matches at 0.916, but the run as a whole is not one advancing timeline, most frames sit at contrast 23-37 where this page's own rule says discrimination is poor, and one high-contrast frame prefers ADV. So it stays amber: consistent with S00A, corroborating the manifest decode, not confirming it. A clean answer needs the 30fps x11grab route rather than 5-second screenshots. Third, and it bounds the rest: the emulator vanished at ~145 s with no crash line in its own log, last entries routine MEM-WATCH at 1.15 GB RSS. Second time this session -- the other was ~50 s into a boot. That is an external kill on a box with ~1 GB free and swap exhausted, not a guest fault. METHOD and the handoff's residue table both now say dynamic experiments here have to fit in about two minutes of guest time, which is why the DELTASABER plates went unseen again: they need a mission load and the run never got there.
160 lines
8.1 KiB
Markdown
160 lines
8.1 KiB
Markdown
# Which movie plays where — the boot intro, the attract loop, the new-game intro
|
||
|
||
**Status:** ✅ `CONFIRMED`. The bindings are **decoded** from the movie manifest,
|
||
and the attract movie is independently **measured** from captured frames. One
|
||
part — whether playback is skippable — is 🟡 and the corpus contradicts itself
|
||
about it; that is written down rather than resolved by assertion.
|
||
|
||
Answers [MISSION Q9](../port/MISSION.md), and contributes to Q6.
|
||
|
||
## The manifest names the boot-side slots — decoded
|
||
|
||
The movie manifest (`dat/tables.pak` entry `0x5b983a08`, schema `0x067025b9`,
|
||
[`movie_manifest.rs`](../../crates/sylpheed-formats/src/movie_manifest.rs)) is an
|
||
array of slots whose **key is the semantic role**, with a parallel array of value
|
||
records in the same order. Its first eight slots are the whole boot-side flow:
|
||
|
||
| slot key | movie | also bound |
|
||
|---|---|---|
|
||
| `LOGO1` … `LOGO4` | `logo1.wmv` … `logo4.wmv` | — |
|
||
| **`ADVERTISE_MOVIE`** | **`ADV.wmv`** | `VOICE_ADV` |
|
||
| `STAFF_ROLL` | `SYLPH_HD720p_8M-CBR_2ch.wmv` | subtitle table |
|
||
| **`MS00A`** | **`S00A.wmv`** | `SUBTITLE_S00A`, `VOICE_S00A`, a `pwterop_s01a.prt` overlay |
|
||
| `MS01A` | `S01A.wmv` | `SUBTITLE_S01A`, `VOICE_S01A` |
|
||
|
||
The alignment is not in doubt here even though the manifest has valueless slots
|
||
elsewhere: `logo1..4` zip 1:1 onto `LOGO1..4`, and `MS00A`→`S00A.wmv`,
|
||
`MS01A`→`S01A.wmv` are the manifest's own anchor rule.
|
||
|
||
**The `logo1`–`logo4` slots are bound to `.wmv` files that are not on the disc** —
|
||
already established, and the reason the developer splash is a screen, not a video.
|
||
|
||
## ✅ The boot intro and the attract movie are the same asset
|
||
|
||
There is **no separate boot-intro slot**. `ADV.wmv` is bound to
|
||
`ADVERTISE_MOVIE` — it *is* the advertise movie, and the boot simply plays it
|
||
first. For the port that means one video, not two.
|
||
|
||
### Measured independently, from captured frames
|
||
|
||
Frames captured 5 s apart during an attract cycle were matched against five
|
||
candidate movies by frame signature (32×18 normalised grayscale, movie frames
|
||
cropped to the 675 of 720 rows the game surface shows, 1 fps sampling).
|
||
`tools/re-capture/frame_match.py`; full table in
|
||
[`data/attract-frame-match.txt`](data/attract-frame-match.txt).
|
||
|
||
**15 of 19 attract frames matched `ADV.wmv`, and the matched timestamps advance
|
||
monotonically at the sampling rate** — 39, 45, 56, 62, 75, 80, 85, 92, 102, 108,
|
||
113, 119, 131, 137 s — ending at 137 s, which is `ADV.wmv`'s full length, after
|
||
which the title returned. That is not a similarity score, it is a playhead.
|
||
|
||
**The control was run first and behaves the same way.** Frames captured during
|
||
the *boot* movie — known to be `ADV.wmv` — matched `ADV` at 116, 121, 129, 134 s.
|
||
Its failure mode is worth stating: on near-black frames the correlation collapses
|
||
(one control frame scored 0.000, another tied `S13A` 0.984 against `ADV` 0.926).
|
||
Those are exactly the 4 attract frames that did not match. **A dark frame carries
|
||
no signature; it is not evidence for the runner-up.**
|
||
|
||
### 🔴 This corrects an earlier claim of mine
|
||
|
||
Two iterations ago I recorded the attract movie as "≈85 s, so probably not
|
||
`ADV.wmv`'s 137 s". That was wrong, and the mistake was arithmetic on an
|
||
unobserved start: my sampling began when the movie was already **39 s in**, so
|
||
what I timed was the *tail* of it, not the whole thing.
|
||
|
||
## ✅ The new-game intro is `S00A.wmv`
|
||
|
||
Slot `MS00A` — the prologue story intro, 93.87 s, with its own subtitle table,
|
||
`VOICE_S00A`, and a text overlay. Decoded from the manifest, **not** measured:
|
||
Ⓐ on `NEW GAME` hangs the emulator
|
||
([`menu-navigation-semantics.md`](menu-navigation-semantics.md)), so this
|
||
binding has not been watched happening.
|
||
|
||
## 🟡 Skippable — the corpus contradicts itself, and I did not settle it
|
||
|
||
* [`canary-scripted-input-traps.md`](canary-scripted-input-traps.md) states
|
||
plainly that "Ⓐ during a movie skips the movie, every time".
|
||
* But `boot_menu.sh` / `skip_intro.sh` as they stand **deliberately do not tap
|
||
during a movie**, logging `movie … -> waiting it out (tapping breaks the
|
||
title)`, and the same document records run G: 88 Ⓐ presses through the boot
|
||
left a permanent black screen.
|
||
|
||
Both cannot be the whole story. **The test**: boot, tap Ⓐ exactly once well
|
||
inside the movie, and record whether the title arrives early. One boot, and it
|
||
was not run this iteration.
|
||
|
||
## ✅ What ends the attract movie
|
||
|
||
Nothing intervenes: it **plays to its end**. The last matched frame is `ADV` at
|
||
137 s — the file's full duration — and the title is back on the next sample. So
|
||
the attract cycle is: title, idle ~8–10 s, fade to black, `ADV.wmv` in full, back
|
||
to the title (which redraws `PRESS Ⓐ BUTTON`).
|
||
|
||
## What this contributes to Q6
|
||
|
||
The manifest is **data the game reads** to sequence the boot side: the slot keys
|
||
are in play order and the key *is* the role. That is not the whole driver — it
|
||
says what plays, not what decides to advance — but it is the first file-side
|
||
piece of Q6's second half, and it means the boot-side asset order does not have
|
||
to be authored.
|
||
|
||
## ✅ Skippable — settled 2026-08-28: **one Ⓐ skips the movie**
|
||
|
||
The test named above was run, and the answer is unambiguous.
|
||
|
||
| | |
|
||
|---|---|
|
||
| baseline: title arrives with **no** input | ~193 s, ~196 s, ~193 s (three boots) |
|
||
| **one Ⓐ tapped at ~45 s into the boot** | **title at ~57 s** |
|
||
|
||
The press is provably the cause and provably singular: Canary's own
|
||
`[RE-INPUT] XamInputGetKeystrokeEx reached the driver` counter went **3 → 4**
|
||
across the tap, so exactly one keystroke was delivered, and the title arrived
|
||
~12 s later instead of ~150 s later.
|
||
|
||
**And the skipped-to title is fully functional**, which is the part that matters
|
||
for the harness folklore: it draws the `PRESS Ⓐ BUTTON` plate (2 408 plate pixels
|
||
by the same probe used elsewhere), and a second Ⓐ opened the main menu normally
|
||
([`title-after-single-A-skip.png`](captures/newgame-path/title-after-single-A-skip.png)).
|
||
|
||
### So what is `skip_intro.sh` protecting against?
|
||
|
||
Not a single tap. The failure recorded in
|
||
[`canary-scripted-input-traps.md`](canary-scripted-input-traps.md) is run G —
|
||
**88 presses at 4 s intervals through the whole boot** — which left a permanent
|
||
black screen. Hammering breaks it; one press does exactly what the button is for.
|
||
The scripts' `waiting it out (tapping breaks the title)` comment is **too broad**,
|
||
and it costs every scripted boot ~2.5 minutes.
|
||
|
||
## 🟡 `S00A.wmv` watched — weakly, and the weakness is the point
|
||
|
||
Reaching the new-game intro finally worked (`SELECT DATA` did not crash this
|
||
time), so the manifest's `MS00A → S00A.wmv` was put to the same frame-signature
|
||
test that identified the attract movie. **It did not reproduce that test's
|
||
quality, and the honest read is "consistent with", not "confirmed".**
|
||
|
||
* The first four samples give a clean monotonic `S00A` playhead — **2, 6, 9, 13 s**
|
||
across four 5-second samples — and `S00A` beats `ADV` on each.
|
||
* The single strongest frame of the run (contrast 47.4) matches `S00A` at
|
||
**0.916** against `ADV` 0.714.
|
||
* But the run as a whole is **not** the clean advancing playhead the attract test
|
||
produced (15 of 19, monotone throughout). Most frames here sit at contrast
|
||
23–37, where the discrimination is poor by this page's own rule, and one
|
||
high-contrast frame matches `ADV` over `S00A`. Two locally-consistent runs
|
||
(2→13 s, then 86→90 s) do not join into one timeline.
|
||
|
||
So the primary evidence that the new-game intro is `S00A.wmv` remains the
|
||
**manifest decode**; this run is weak corroboration and is recorded as such. A
|
||
clean identification needs denser sampling (the 30 fps `x11grab` route from
|
||
[`screen-transitions.md`](screen-transitions.md)) rather than 5-second
|
||
screenshots.
|
||
|
||
### ⚠️ And the run was killed before the mission load
|
||
|
||
The emulator disappeared at ~145 s with **no crash line in its own log** — the
|
||
last entries are routine `MEM-WATCH rss=1153MB` — so this was an external kill,
|
||
not a guest fault. It is the **second** time this session (the first at ~50 s
|
||
into a boot). Long dynamic runs are unreliable in this container, and the
|
||
`DELTASABER` plates of [`ui-title-build-map.md`](ui-title-build-map.md), which
|
||
would need a mission load, were not reached.
|