port: fix two capture bugs, and the second was hiding a missing PRESS (A) plate
1. --capture with --script photographed before the first press (t=0.133 s, 10 of 16 elements transparent). Two runs differing by two presses came out bit-identical and I read it as 'runtime focus never changes'. Deferred to the end of the script; verified max 235 and t=82 units. 2. --boot --capture= wrote NO FILE: _finish_boot() is reachable only from the overlay-quit branch, but line 412 quit first because _overlay_spec is cleared when the overlay is raised. Pre-existing, confirmed by stashing. Fixed by also requiring _overlay_quit_at < 0.0. 3. The artifact that now exists shows the boot's end frame is bit-identical to the title alone -- no plate. ptbtn00 is opaque for 8 units (236-244) and the boot captures at 246.54, because it waits for build 4 to finish fading at t=261. Both halves of that are sound and they are incompatible. NOT changed; filed, since what settles it is what the game does after t=244. Defect 3 was invisible while defect 2 existed: a capture flag that writes nothing cannot show a missing element. Also records that runtime focus is FINE -- my contrary reading came from 410 files whose names did not match the flag I passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7FiFFFwbvG2uxdcEh8HyF
This commit is contained in:
@@ -512,3 +512,30 @@ shipped game would do. That reasoning is what makes an invented answer feel safe
|
||||
⚠️ Related but separate, and already authored with a `why`: the bed **loops by
|
||||
restart**, seam and all (`authored/audio.json`, `loop_why`). That is a known-ugly
|
||||
deliberate choice pending a loop point, not this question.
|
||||
|
||||
---
|
||||
|
||||
## Does the `PRESS Ⓐ` plate stay up, or blink once and go?
|
||||
|
||||
*Derived from HANDOFF `9ca1eb5`. Raised 2026-08-29 by the port.*
|
||||
|
||||
`ptbtn00`'s group makes the plate opaque for **8 units only** — alpha 0 until
|
||||
t=214, 255 at t=236 and t=238, back to 0 by t=244 — and its group then ends. So
|
||||
in the port the plate flashes for 0.133 s and is gone, and the boot's end-state
|
||||
capture (taken at t=246.54, once build 4 has finished fading up at t=261) contains
|
||||
**no plate at all**.
|
||||
|
||||
🔴 The two states cannot share a frame: the plate's window closes 17 units before
|
||||
the title stops presenting. The port captures the title, by an earlier and sound
|
||||
decision it is not reversing.
|
||||
|
||||
What would settle it: **a capture of the real title held for several seconds after
|
||||
the plate first appears.** Three outcomes, all decisive — the plate stays up; it
|
||||
pulses on a period (`authored/timing.json` already carries a *speculative*
|
||||
`looping_focus_records` entry for `press_start/ptbtn00` at 120 units, which is
|
||||
what a pulse would need); or it genuinely blinks once and vanishes, in which case
|
||||
the port is right and this closes ✅.
|
||||
|
||||
⚠️ Note the port already draws a looping focus record for this element. If the
|
||||
answer is "blinks once", **that entry is wrong and should be deleted**, not kept
|
||||
as harmless — it is the only thing making the plate reappear at all.
|
||||
|
||||
@@ -5754,3 +5754,77 @@ silently ran 39 % long would have put every such observation at the wrong instan
|
||||
and the bed-loop result above would have been the first casualty. It survived only
|
||||
because the seam was read off the **recording's** clock, which the bed's own known
|
||||
length calibrates.
|
||||
|
||||
## Two harness bugs, and the defect the second one was hiding
|
||||
|
||||
### 1. `--capture` with `--script` photographed the frame *before* the script
|
||||
|
||||
`--capture` fired in `_ready` and quit. With `--script` that is **before the
|
||||
first press**: at t=0.133 s, with 10 of 16 elements still transparent. Two runs
|
||||
differing by two `down` presses came out **bit-identical**, and I read that as
|
||||
*"runtime focus never changes"* — a confident wrong finding that `--shots`
|
||||
contradicted within a minute.
|
||||
|
||||
Fixed: with a script, the capture defers to the end of the run, through the same
|
||||
`_capture_to` member the boot path already used. Verified — the two runs now
|
||||
differ at max 235, and the capture lands at t=82 units instead of t=8.
|
||||
|
||||
### 2. `--boot --capture=` wrote no file at all
|
||||
|
||||
`_finish_boot()` is reachable only from the overlay-quit branch, but the boot
|
||||
quit first: line 412 exits when `_film == "" and _overlay_spec.is_empty()`, and
|
||||
`_overlay_spec` is **cleared when the overlay is raised**. So a plain `--boot`
|
||||
ended at 10.99 s, 1.2 s before its own scheduled 12.21 s, and the capture never
|
||||
happened.
|
||||
|
||||
Confirmed pre-existing by stashing my changes and re-running. Fixed by also
|
||||
requiring `_overlay_quit_at < 0.0`. The boot now runs to 12.19 s, prints *"boot
|
||||
ends on title + press_start"*, and writes the file.
|
||||
|
||||
⚠️ The flag has a doc comment explaining that it exists so the boot has an
|
||||
artifact of its own instead of a 600-PNG filmstrip. **It has been producing
|
||||
nothing.** A flag that silently writes no file is the same failure as
|
||||
`ScreenView.skipped` and `stop_bed`: provided, plausible, and never exercised.
|
||||
|
||||
### 3. 🔴 And the artifact it now produces shows the plate is missing
|
||||
|
||||
The boot's end frame is **bit-identical** to `--screen=title` at the same instant
|
||||
— max difference 0. The `PRESS Ⓐ` plate is not in the port's end state.
|
||||
|
||||
`ptbtn00`'s own fade explains it exactly:
|
||||
|
||||
| t | 0 | 214 | **236** | **238** | 244 |
|
||||
|---|---|---|---|---|---|
|
||||
| alpha | 0 | 0 | **255** | **255** | 0 |
|
||||
|
||||
The plate is visible for **8 units — 0.133 s** — and the boot captures at
|
||||
**t=246.54**, two and a half units after it has gone.
|
||||
|
||||
That is not an accident of frame timing; the code chose it. `_overlay_quit_at`
|
||||
takes `max(view.settle_time(), overlay.settle_time())`, and its comment says why:
|
||||
*"the plate arrives at t=238 and build 4 is still fading up from black until
|
||||
t=261 … quitting when the plate lands photographs a title that has not finished
|
||||
presenting."* Both halves are true, and together they mean **the two states
|
||||
cannot both be in one frame.** The port picked the title, and the consequence —
|
||||
that the plate is in no artifact at all — was never written down.
|
||||
|
||||
⚠️ I am **not** moving the trigger. The earlier reasoning is sound and the
|
||||
measurement it protects is real; picking the other instant would trade a missing
|
||||
plate for a visibly dark title, which is the swap that was already made once and
|
||||
regretted. What settles it is what the *game* does with the plate after t=244 —
|
||||
filed.
|
||||
|
||||
📌 Worth naming: defect 3 was **invisible while defect 2 existed**. A capture flag
|
||||
that writes nothing cannot show you a missing element. The broken tool was hiding
|
||||
the thing the tool was built to find, and neither was noticed because the absence
|
||||
of a file looks exactly like not having run the command.
|
||||
|
||||
### What was *not* wrong, and how I nearly recorded that it was
|
||||
|
||||
Runtime focus works. Per-step `--shots` across `down,down` differ at max 232–233,
|
||||
with the differing boxes tracking down the button column. My contrary reading came
|
||||
from analysing 410 `f_NNN` files after asking for `--shots=…/s` — **the filenames
|
||||
did not match the flag I passed, and that was visible in my first `ls`.** A
|
||||
verbatim re-run produces six correctly-named per-step shots. I do not know where
|
||||
those 410 files came from, which is itself the point: I drew a conclusion from a
|
||||
file set whose provenance I never checked.
|
||||
|
||||
@@ -274,11 +274,28 @@ func _ready() -> void:
|
||||
overlay.time_units = float(args["time"]) * overlay.units_per_second
|
||||
overlay.queue_redraw()
|
||||
|
||||
# `--boot --capture=` is deferred to the end of the sequence (`_finish_boot`);
|
||||
# in every other mode the frame worth having is this one.
|
||||
# `--boot --capture=` is deferred to the end of the sequence (`_finish_boot`),
|
||||
# and so is `--script --capture=`.
|
||||
#
|
||||
# 🔴 The second half of that was missing, and the comment here used to assert
|
||||
# the opposite -- "in every other mode the frame worth having is this one".
|
||||
# With `--script` it is emphatically not: the capture fired **before the
|
||||
# first press**, at t=0.133 s, with 10 of 16 elements still transparent, and
|
||||
# then quit. Two runs differing by two `down` presses came out BIT-IDENTICAL,
|
||||
# because neither had run its script when it was photographed.
|
||||
#
|
||||
# That is not a harmless default. It is a well-formed answer to a different
|
||||
# question, and it produced a confident wrong finding -- "runtime focus never
|
||||
# changes" -- that `--shots` immediately contradicted. A flag combination
|
||||
# that silently photographs the wrong instant is worse than one that errors.
|
||||
if args.has("capture") and _capture_to == "":
|
||||
await _capture(args["capture"])
|
||||
get_tree().quit(0)
|
||||
if not _script.is_empty():
|
||||
# Defer to the end of the script, through the SAME member the boot
|
||||
# path already uses, rather than adding a second mechanism.
|
||||
_capture_to = String(args["capture"])
|
||||
else:
|
||||
await _capture(args["capture"])
|
||||
get_tree().quit(0)
|
||||
|
||||
|
||||
var _frozen := false
|
||||
@@ -392,7 +409,7 @@ func _process(delta: float) -> void:
|
||||
# than one that exits.
|
||||
if _play:
|
||||
_menu_enter(String(_sequence[_step].get("screen", "")), true)
|
||||
elif _film == "" and _overlay_spec.is_empty():
|
||||
elif _film == "" and _overlay_spec.is_empty() and _overlay_quit_at < 0.0:
|
||||
get_tree().quit(0)
|
||||
elif not view.holding and view.time_units >= view.exit_time() + _black_hold:
|
||||
# 🔴 THE BLACK HOLD, which this port had never implemented. A transition
|
||||
@@ -836,6 +853,10 @@ func _run_script() -> void:
|
||||
await _shoot("%02d_%s" % [i + 1, token])
|
||||
print("script complete after %.2f s on %s, focus %s"
|
||||
% [_elapsed, _menu.current(), _focus_label(view.focused_id)])
|
||||
# The frame worth having from a scripted run is the one the script ARRIVED
|
||||
# at, not the one it started from. See the note beside the early capture.
|
||||
if _capture_to != "":
|
||||
await _capture(_capture_to)
|
||||
get_tree().quit(0)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user