port: P7 -- the new-game intro plays, and the two screens it skips are named out loud
S00A has been exported since P4; what P7 needed was something to play it and a
defined place to land. Both are here, and the interesting part is the gap.
The real chain is NEW GAME -> DIFFICULTY -> SELECT DATA -> (A) on a save slot ->
~4.5 s -> S00A. DIFFICULTY and SELECT DATA are MEASURED destinations that are not
GP_TITLE builds, so no screen file exists to go to. The port jumps from NEW GAME
to the one thing in that chain it has -- and the whole design is about not
letting that read as a sequence:
* MenuFlow.accept returns a new kind, `video`, rather than folding this into
`blocked`, because the caller has to announce the skip and a distinct kind is
what forces it to;
* the runtime prints the skipped screens by name on every run;
* flow.json carries `skipped_chain` as DATA, so what is missing lives beside
the decision instead of inside a GDScript string.
After the movie the port returns to the title. Authored, and it has to be: the
game goes into mission 1 and gameplay is out of scope. The ~4.5 s before the
movie is left EMPTY on purpose -- GP_TITLE does carry a loading screen and 4.5 s
is about the right shape for one, which is exactly why that belongs in BLOCKED.md
and not in flow.json.
`--script`'s 20 s per-step timeout would have killed every movie run at step 1.
Raising the constant would have been wrong the other way: a movie stuck at frame
0 would then hang the job, and a job that waits is worse than one that fails. The
test is now LIVENESS -- while get_stream_position() advances the deadline moves
with it, and a stalled movie still trips the same 20 s.
Found while looking: GP_TITLE's four unnamed builds (entries 0, 1, 12, 15) are
LOADING screens -- every element in all four is pgloading_*, and LOADING is one of
the three names the decoder read out of the title part's state function. NOT
renamed here: which member of each pair is which locale is an inference, and a
name stops being questioned once written. Handed over.
One of them is a second casualty of the rest.t problem, and a worse one:
pgloading_eff00.prm rests OPAQUE BLACK at t=38, so anything drawing that screen
at its declared rest paints a black rectangle over all of it. The title's case
only dimmed a frame.
REFUTATION, attempted and SURVIVED: HANDOFF says "exactly the six screen builds
carry the black .prm quad while the six overlays do not". Counting bundles with a
full-screen black primitive gives 8 and 4 -- build_12/15 carry one too. But
theirs runs black -> held -> clear where the transition quad runs black -> clear
-> black, so read strictly as "the quad whose group is the transition" the claim
holds. Recorded anyway: there are two kinds, and the naive census over-counts.
Gate: NEW GAME -> S00A plays 93.75 s against a declared 93.9 -> title, with
98.453 s recorded off the Master bus. What that does NOT show is that S00A's own
audio is in the mix -- bed and movie were not separated in this run, and the
write-up says so.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WM5XL4HfrHuxz8RiMWdCMC
This commit is contained in:
@@ -110,6 +110,10 @@ func move(step: int, buttons: Array) -> bool:
|
||||
## {"kind": "blocked", "label": …, "why": …} -- a real destination
|
||||
## that is not in this
|
||||
## export
|
||||
## {"kind": "video", "video": …, "skipped": […], -- the destination is
|
||||
## "after": {…}} absent but its chain
|
||||
## ends in a movie we
|
||||
## DO have (P7)
|
||||
## {"kind": "none"} -- nothing bound
|
||||
##
|
||||
## `blocked` is not an error and is not an unknown. Those five destinations were
|
||||
@@ -127,6 +131,24 @@ func accept(buttons: Array) -> Dictionary:
|
||||
return NONE
|
||||
var label := String(button.get("label", focus()))
|
||||
if button.get("goto", null) == null:
|
||||
# A destination this export does not carry, but whose CHAIN ends in
|
||||
# something it does: `NEW GAME` opens `DIFFICULTY`, then `SELECT DATA`,
|
||||
# and only then the new-game movie. The port has the movie and neither
|
||||
# screen (P7).
|
||||
#
|
||||
# This is returned as its own kind rather than folded into `blocked`,
|
||||
# because the caller has to announce the skip. A port that quietly
|
||||
# jumped from `NEW GAME` to the intro would be showing a sequence the
|
||||
# game does not have, and nothing on screen would say so.
|
||||
if button.get("then_video", null) != null:
|
||||
return {
|
||||
"kind": "video",
|
||||
"label": label,
|
||||
"video": String(button["then_video"]),
|
||||
"skipped": button.get("skipped_chain", []),
|
||||
"skippable": bool(button.get("skippable", false)),
|
||||
"after": button.get("after_video", {}),
|
||||
}
|
||||
return {"kind": "blocked", "label": label, "why": String(button.get("blocked", ""))}
|
||||
return {"kind": "enter", "goto": String(button["goto"]), "label": label}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user