port: P5 end to end -- and the port's title never says PRESS (A)
The P5 gate walk starts on a screen. This runs the whole objective instead, and
it is the only thing that would have found what it found:
xvfb-run -a godot --path port -- --boot --play \
--script=accept,down,down,down,down,accept,cancel,cancel --shots=/tmp/e2e
publisher wordmark -> developer logos -> ADV (151.9 s) -> title -> (A) -> main
menu -> navigate -> (A) -> EXTRAS -> (B) with focus restored to ptbtn05 -> (B)
-> title. 166.76 s, exit 0, nine frames. Shared as 1788003274-e68367e787d5.
THE PORT'S TITLE DOES NOT TELL THE PLAYER TO PRESS (A). The boot's last step is
`title` = GP_TITLE build 4, and build 4 has NO `PRESS (A) BUTTON` plate. P5 has
just made (A) the only way off that screen.
Not a guess about the art -- both states are captured off the running game and
differ by exactly that plate (live-title-build4-no-plate.png vs
live-title-press-a.png), and the plate is ALREADY EXPORTED as `press_start`,
build 2, sitting in export/screens/title/ unused by anything.
RECORDED, NOT FIXED, and the distinction is the point. This is P3's gate that
P5 exposed, and fixing it needs two things the port does not have:
* WHICH state an idle post-boot title shows -- build 4 alone, build 4 with the
plate over it, or build 4 THEN the plate after a delay -- is BEHAVIOURAL.
The game demonstrably has both states and nothing says which follows the
intro. The port has no oracle for a sequence; that is the Decoder's.
* showing it means DRAWING TWO BUILDS AT ONCE, which this port has never done
-- every mode loads exactly one screen. That is a change to ScreenView, not
a line in flow.json, and it is not being smuggled in under a navigation
milestone on the strength of "it looks more right".
Filed in BLOCKED.md. P5's gate is (A) into a submenu and (B) back; both work.
Two smaller things the same run found, both fixed:
* the boot step's `why` still said "nothing takes the title's place until P5
gives it somewhere to go". P5 has. Now says what is true: `--boot` STOPS on
the title (a boot that ends by fading to black looks like a crash) and
`--play` HANDS THE HELD TITLE OVER -- the stop is not a bug and the handover
is not another boot step.
* an empty focus printed as a line that trailed off, reading like a value had
gone missing rather than like there is none. The title is a screen with no
`buttons` that still takes (A), so it now prints
"(none -- this screen has no focusable item)".
Also confirmed: entering a submenu directly (`--menu=extras`) and pressing (B)
enters the parent at its AUTHORED initial focus, not a restored one. There is no
history to restore and MenuFlow.cancel only claims a restored focus when the
stack agrees about where it is going.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CtmUw5N5LJaMW1Njb8Ziey
This commit is contained in:
@@ -342,7 +342,7 @@ func _menu_enter(name: String, fresh: bool) -> void:
|
||||
_menu.enter(name, view.screen.get("buttons", []))
|
||||
view.focused_id = _menu.focus()
|
||||
view.queue_redraw()
|
||||
print(" menu on %s, focus %s" % [name, view.focused_id])
|
||||
print(" menu on %s, focus %s" % [name, _focus_label(view.focused_id)])
|
||||
if not _script.is_empty() and not _script_started:
|
||||
_script_started = true
|
||||
_run_script()
|
||||
@@ -366,7 +366,7 @@ func _menu_arrive() -> void:
|
||||
_menu.stack[_menu.stack.size() - 1]["focus"] = String(action["restore_focus"])
|
||||
view.focused_id = _menu.focus()
|
||||
view.queue_redraw()
|
||||
print(" menu on %s, focus restored to %s" % [name, view.focused_id])
|
||||
print(" menu on %s, focus restored to %s" % [name, _focus_label(view.focused_id)])
|
||||
else:
|
||||
_menu_enter(name, true)
|
||||
|
||||
@@ -393,6 +393,14 @@ func _has_display(flag: String) -> bool:
|
||||
return false
|
||||
|
||||
|
||||
## How a focus reads in the log. The title has no focusable item at all -- it is
|
||||
## a screen with no `buttons` that still takes (A) -- and an empty string there
|
||||
## printed as a line that trailed off, which reads like the value went missing
|
||||
## rather than like there is none.
|
||||
static func _focus_label(id: String) -> String:
|
||||
return id if id != "" else "(none -- this screen has no focusable item)"
|
||||
|
||||
|
||||
func _capture(path: String) -> void:
|
||||
# Two frames: the first is the one this callback is still inside of.
|
||||
await RenderingServer.frame_post_draw
|
||||
@@ -483,7 +491,7 @@ func _run_script() -> void:
|
||||
return
|
||||
await _shoot("%02d_%s" % [i + 1, token])
|
||||
print("script complete after %.2f s on %s, focus %s"
|
||||
% [_elapsed, _menu.current(), view.focused_id])
|
||||
% [_elapsed, _menu.current(), _focus_label(view.focused_id)])
|
||||
get_tree().quit(0)
|
||||
|
||||
|
||||
@@ -530,4 +538,4 @@ func _shoot(label: String) -> void:
|
||||
push_error("cannot write %s" % tmp)
|
||||
return
|
||||
DirAccess.rename_absolute(tmp, path)
|
||||
print(" shot %s (%s, focus %s)" % [path, _menu.current(), view.focused_id])
|
||||
print(" shot %s (%s, focus %s)" % [path, _menu.current(), _focus_label(view.focused_id)])
|
||||
|
||||
Reference in New Issue
Block a user