re: settle_time measured -- the title is drawn at 2 s, not at rest.t s 4.18
The port s boot sequencer paces every screen off rest.t, which is the last hold keyframe rather than when a screen arrives. Measured on one cold boot: the container had no Xenia storage root at all, so this is a fresh profile with no shader cache, the slowest case. title build-in (first ink -> art fully drawn) 0.23 s title settled -> PRESS A plate on 2.247 s (disc declares 120 units) plate pulse period ~2.37 s main menu build-in 0.531 s B -> title 0.482 s A -> menu 3.763 s DO NOT AUTHOR, see below The title s rest.t is 251 units = 4.183 s and its art is finished at about 2 s, so a sequencer pacing off rest.t holds it roughly twice as long as the game does. Instrument controlled before the run: 9/9 on the content classifier including the movie-frame and difficulty-screen negatives, 4/4 on the plate detector; the run sampled 7.99 fps against a requested 8 with an independent one-shot grab cross-checking every 20 s. Records a refutation attempt of mine that FAILED. The probe s own marks gave a plate delay of 3.203 s against the corpus s 2.13 s, which on a cold-cache boot looked like a real effect. It was the instrument: the plate pulse period is an internal clock for presentation rate and measures 2.369 s here against the corpus s 2.3, so the run is not slowed, and re-measuring from content gives 2.247 s. The probe s title_static mark fires during the crossfade out of the attract movie, before the wordmark has drawn -- glyph was still 0 when it fired. Also a third independent reproduction of the A-path load stall: 13 frames, 1.53 s, surface mean 26.631 against the earlier 14/1.53 and 12/1.39 at 26.626. This boot had no shader cache, so it is not a warm-cache artefact. Noted that the earlier pair agreed to six decimals and mine agrees to three. Reach: one run. The menu build-in and B->title rest on it alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
@@ -462,6 +462,55 @@ is stays open and is mine.
|
||||
second, and the second citing the first would have made it look corroborated by
|
||||
two documents. It was caught only because you measured your own claim.
|
||||
|
||||
## ✅ 2026-08-29 — `settle_time()` MEASURED. Stop pacing off `rest.t`.
|
||||
|
||||
Your top ask, from one cold boot — container had no Xenia storage root at all, so
|
||||
this is a fresh profile with **no shader cache**, the slowest case.
|
||||
[`boot-settle-times-measured.md`](../re/boot-settle-times-measured.md) ·
|
||||
[frame log](../re/data/boot-settle-run1.tsv) · `tools/re-capture/settle_analyse.py`
|
||||
|
||||
**Classification: measured.** None of it is on the disc as a settle time; you are
|
||||
authoring these from this page.
|
||||
|
||||
| | measured | |
|
||||
|---|---|---|
|
||||
| title build-in (first ink → art fully drawn) | **0.23 s** | 1.63 s if you start from where the crossfade begins |
|
||||
| **title settled → `PRESS Ⓐ` plate on** | **2.247 s** | matches the disc's declared **120 units** |
|
||||
| plate pulse period | **≈2.37 s** | |
|
||||
| **main menu build-in** | **0.531 s** | |
|
||||
| **Ⓑ → title** | **0.482 s** | |
|
||||
| Ⓐ → menu | 3.763 s | 🔴 **do not author** — contains a 1.53 s emulator load stall |
|
||||
|
||||
🔴 **`rest.t` is confirmed to be the wrong landmark, with the number you need.**
|
||||
The title's `rest.t` is 251 units = **4.183 s**; its art is finished at ~2 s and
|
||||
the plate is on at **2.247 s**. Your sequencer holds the title about twice as
|
||||
long as the game does. That is the defect you described, measured.
|
||||
|
||||
**Instrument controlled first**: 9/9 on the content classifier including the
|
||||
movie-frame and difficulty-screen negatives, 4/4 on the plate detector; the run
|
||||
sampled 7.99 fps against a requested 8 with an independent grab cross-checking
|
||||
every 20 s, so this is not the backlog mode that voided four durations before.
|
||||
|
||||
🟢 **A refutation attempt of mine that FAILED, and you should know it failed.**
|
||||
The probe's own marks gave a plate delay of **3.203 s** against the corpus's
|
||||
2.13 s — a 50 % disagreement I expected to be a real cold-cache effect. It was my
|
||||
instrument. The plate **pulse period** is an internal clock for presentation
|
||||
rate, and it measures 2.369 s here against the corpus's ≈2.3 s, so the run is not
|
||||
slowed; re-measured from content, the delay is **2.247 s**. ⚠️ The cause is worth
|
||||
your knowing: the probe's `title_static` mark fires during the **crossfade out of
|
||||
the attract movie, before the wordmark has drawn** — glyph was still 0 when it
|
||||
fired. Do not use `title_static` for a duration.
|
||||
|
||||
🟢 **And your load stall reproduces a third time, on a cold cache** — 13 frames,
|
||||
1.53 s, surface mean 26.631, against the earlier 14/1.53 s and 12/1.39 s at
|
||||
26.626. So it is not a warm-cache artefact, and "do not author an Ⓐ→menu dwell"
|
||||
stands. ⚠️ Honest qualification: the earlier pair agreed to six decimals; mine
|
||||
agrees to three.
|
||||
|
||||
⚠️ **Reach: one run.** The plate delay and the load stall are cross-checked
|
||||
against independent prior evidence. **The menu build-in and Ⓑ→title rest on this
|
||||
run alone** — re-take them before anything depends on them closely.
|
||||
|
||||
## Status
|
||||
|
||||
| | Question | State | Answer / link |
|
||||
|
||||
119
docs/re/boot-settle-times-measured.md
Normal file
119
docs/re/boot-settle-times-measured.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# ✅ `settle_time()` — when each boot screen actually arrives, measured
|
||||
|
||||
**Classification: measured.** None of this is on the disc as a settle time. The
|
||||
disc declares *keyframes*; when a screen visibly arrives is a property of the
|
||||
running game, and the port authors these numbers from this page.
|
||||
|
||||
Answers the port's standing ask: its boot sequencer paces every screen off
|
||||
`rest.t`, which is the **last hold keyframe** and not when a screen arrives — it
|
||||
holds the title for 4.350 s where the build-in is over at about 2 s.
|
||||
|
||||
**Run:** one cold boot, 2026-08-29. Container had **no Xenia storage root at
|
||||
all**, so this is a fresh profile (`--create_profile_if_none`) with no shader
|
||||
cache — the slowest case, deliberately.
|
||||
Frame log committed at [`data/boot-settle-run1.tsv`](data/boot-settle-run1.tsv);
|
||||
analysis `tools/re-capture/settle_analyse.py`.
|
||||
|
||||
## The instrument was controlled first, and then caught being wrong
|
||||
|
||||
`title_timing_probe.py --control` passed **9/9** on the content classifier —
|
||||
including the movie-frame and `difficulty-screen` negatives — and **4/4** on the
|
||||
plate detector, before the run. The run itself sampled **2 107 frames in 263.7 s
|
||||
= 7.99 fps against a requested 8**, with an independent one-shot grab every 20 s
|
||||
agreeing with the stream to under 1 grey level. So this is not the backlog
|
||||
failure mode that cost this corpus four withdrawn durations.
|
||||
|
||||
🔴 **And the probe's own `title_static` mark is still biased early — do not use
|
||||
it for a duration.** It fires when the classifier first labels a frame
|
||||
`title_*` *and* motion is low, which happens **during the crossfade out of the
|
||||
attract movie, before the wordmark has drawn**. In this run it fired at
|
||||
`t=242.655` while the green-glyph count was still **0**; the title art does not
|
||||
reach its steady state until `243.595`. Any `title_static → plate` figure from
|
||||
this probe is therefore inflated by about a second.
|
||||
|
||||
## The landmarks, taken from content rather than from the probe's marks
|
||||
|
||||
The robust landmark is the **glyph plateau**: the title art alone scores a steady
|
||||
`glyph = 154` (the corpus's `live-title-build4-no-plate.png` scores 159), and the
|
||||
plate takes it past 700.
|
||||
|
||||
| landmark | t (s) | how |
|
||||
|---|---|---|
|
||||
| attract movie ends, first title ink | 243.362 | glyph leaves 0 |
|
||||
| **title art fully drawn** | **243.595** | glyph reaches its steady 154 |
|
||||
| **`PRESS Ⓐ` plate on** | **245.842** | glyph crosses 400 → 771 |
|
||||
| Ⓐ pressed | 250.983 | |
|
||||
| ⚠️ guest load stall | 251.601 – 253.135 | 13 byte-identical frames |
|
||||
| **main menu arrives** | **254.707** | classifier |
|
||||
| **main menu settled** | **255.238** | motion below a run-calibrated floor |
|
||||
| Ⓑ pressed | 262.864 | |
|
||||
| **title back** | **263.346** | |
|
||||
|
||||
### What the port should author
|
||||
|
||||
| | measured | ⚠️ |
|
||||
|---|---|---|
|
||||
| title build-in (first ink → fully drawn) | **0.23 s** | from first ink; **1.63 s** from the first frame the classifier calls `title_*`, which is where the crossfade starts |
|
||||
| **title settled → plate on** | **2.247 s** | matches the disc's declared **120 units** |
|
||||
| plate pulse period | **≈2.37 s** | trough-to-trough, 248.098 → 250.467 |
|
||||
| **main menu build-in** | **0.531 s** | |
|
||||
| **Ⓑ → title** | **0.482 s** | |
|
||||
| Ⓐ → menu | 3.763 s | 🔴 **do not author** — contains a 1.53 s emulator load stall, below |
|
||||
|
||||
🔴 **`rest.t` is confirmed to be the wrong landmark.** The title's `rest.t` is 251
|
||||
units = 4.183 s; its art is finished at ~2 s and the plate is on at 2.25 s. A
|
||||
sequencer pacing off `rest.t` holds the title roughly twice as long as the game
|
||||
does.
|
||||
|
||||
## 🟢 A refutation attempt that FAILED — the corpus's 2.13 s plate delay survives
|
||||
|
||||
The probe's own marks gave a plate delay of **3.203 s** (`title_static` 242.655 →
|
||||
`plate` 245.858), against the corpus's two committed runs at **2.138 / 2.132 s**
|
||||
and a declared 120 units ≈ 2.0 s. A 50 % disagreement, from a cold-cache boot, is
|
||||
exactly where you would expect the corpus to be wrong.
|
||||
|
||||
**It is not. The instrument was.** Two checks:
|
||||
|
||||
* **The presentation rate is not depressed in this run.** If the boot were
|
||||
running slow, everything timed in game units would stretch together. The plate
|
||||
**pulse period** is an internal clock for that, and it measures **2.369 s**
|
||||
here against the corpus's ≈2.3 s. The run is not slowed.
|
||||
* **Re-measured from content instead of from the probe's mark**, steady title art
|
||||
(`243.595`) → plate on (`245.842`) is **2.247 s** — inside the corpus's range
|
||||
once the ±0.125 s sample interval is allowed for.
|
||||
|
||||
✅ So the 2.13 s stands, the 120-unit reading stands, and the 3.203 s is
|
||||
`title_static` firing during a crossfade. Recorded because a failed refutation is
|
||||
worth as much as a successful one, and because the next person to read the
|
||||
probe's `title_static` will otherwise repeat it.
|
||||
|
||||
## 🟢 And the load stall reproduces — third independent run, cold cache
|
||||
|
||||
[`title-plate-delay-measured.md`](title-plate-delay-measured.md) records a frozen
|
||||
frame on the Ⓐ path in two runs: **14 frames (1.53 s)** and **12 frames
|
||||
(1.39 s)**, both at surface mean **26.626**, and concludes any Ⓐ→menu figure from
|
||||
this harness is an emulator load time rather than a game constant.
|
||||
|
||||
This run is a third: **13 frames, 251.601 – 253.135 = 1.53 s, surface mean
|
||||
26.631**, labelled `title_plate` throughout.
|
||||
|
||||
✅ The claim survives, and is now stronger in a way the earlier runs could not
|
||||
show: this boot had **no shader cache at all**, so the stall is not a warm-cache
|
||||
artefact. ⚠️ One honest qualification — the earlier note says its two runs agreed
|
||||
"to six decimals"; mine agrees only to three (26.631 vs 26.626), so the mean is
|
||||
reproducible but not byte-identical across all three.
|
||||
|
||||
## Reach
|
||||
|
||||
* **One run.** The durations above are one cold boot. The two that are
|
||||
cross-checked against independent evidence — the plate delay, against the
|
||||
corpus's two runs and the disc's 120 units; the load stall, against two prior
|
||||
runs — are the ones to lean on. The menu build-in (0.531 s) and Ⓑ→title
|
||||
(0.482 s) rest on **this run alone** and should be re-taken before anything
|
||||
depends on them closely.
|
||||
* **Sampling is 8 fps**, so every landmark carries ±0.125 s, and the guest's own
|
||||
presentation rate cannot be measured from it — 8 fps is far below the ~28 fps
|
||||
the game presents at, so every sample is a distinct guest frame and repeats
|
||||
only appear when the guest itself stalls.
|
||||
* The splash dwells are **not** re-measured here; they are already in
|
||||
[`boot-order-and-splash-dwell.md`](boot-order-and-splash-dwell.md).
|
||||
2136
docs/re/data/boot-settle-run1.tsv
Normal file
2136
docs/re/data/boot-settle-run1.tsv
Normal file
File diff suppressed because it is too large
Load Diff
81
tools/re-capture/settle_analyse.py
Executable file
81
tools/re-capture/settle_analyse.py
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Offline: when does each screen ARRIVE, and when does it SETTLE?
|
||||
|
||||
`rest.t` is the last hold keyframe, not when a screen stops moving -- the port
|
||||
paces its boot sequencer off it and is late. This reads the timing probe's TSV
|
||||
and reports, per screen segment:
|
||||
|
||||
arrive first frame the classifier labels that screen
|
||||
settle first frame after `arrive` where inter-frame motion stays below the
|
||||
quiet threshold for SETTLE_HOLD consecutive frames
|
||||
dwell how long the label persists
|
||||
|
||||
The quiet threshold is CALIBRATED FROM THE RUN, not assumed: it is a multiple of
|
||||
the motion floor observed while a label is stable and late in its segment.
|
||||
"""
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
SETTLE_HOLD = 4 # consecutive quiet frames before calling it settled
|
||||
|
||||
def main(path):
|
||||
rows = []
|
||||
meta = []
|
||||
for ln in open(path):
|
||||
if ln.startswith("#"):
|
||||
meta.append(ln.rstrip())
|
||||
continue
|
||||
f = ln.rstrip("\n").split("\t")
|
||||
if len(f) < 8:
|
||||
continue
|
||||
rows.append((float(f[0]), int(f[1]), float(f[2]), float(f[3]), f[7]))
|
||||
if not rows:
|
||||
print("no data rows"); return 2
|
||||
t = np.array([r[0] for r in rows])
|
||||
motion = np.array([r[3] for r in rows])
|
||||
labels = [r[4] for r in rows]
|
||||
n = len(rows)
|
||||
fps = n / (t[-1] - t[0]) if t[-1] > t[0] else 0
|
||||
print(f"{n} frames, {t[-1]-t[0]:.1f} s, {fps:.2f} fps")
|
||||
for m in meta:
|
||||
if m.startswith("#summary") or m.startswith("#event"):
|
||||
print(" " + m)
|
||||
|
||||
valid = motion[motion >= 0]
|
||||
if valid.size == 0:
|
||||
print("no motion data"); return 2
|
||||
floor = float(np.percentile(valid, 10))
|
||||
quiet = max(floor * 3.0, 0.05)
|
||||
print(f"\nmotion floor (10th pct) {floor:.4f} -> quiet threshold {quiet:.4f}")
|
||||
|
||||
# Segment by contiguous label.
|
||||
segs = []
|
||||
i = 0
|
||||
while i < n:
|
||||
j = i
|
||||
while j + 1 < n and labels[j + 1] == labels[i]:
|
||||
j += 1
|
||||
segs.append((labels[i], i, j))
|
||||
i = j + 1
|
||||
|
||||
print(f"\n{'screen':<14} {'arrive':>8} {'settle':>8} {'build-in':>9} {'leaves':>8} {'dwell':>8} {'frames':>7}")
|
||||
for lab, a, b in segs:
|
||||
if b - a < 2:
|
||||
continue
|
||||
settle = None
|
||||
run = 0
|
||||
for k in range(a, b + 1):
|
||||
if 0 <= motion[k] < quiet:
|
||||
run += 1
|
||||
if run >= SETTLE_HOLD:
|
||||
settle = t[k - SETTLE_HOLD + 1]
|
||||
break
|
||||
else:
|
||||
run = 0
|
||||
build = f"{settle - t[a]:9.3f}" if settle is not None else " -"
|
||||
s = f"{settle:8.3f}" if settle is not None else " -"
|
||||
print(f"{lab:<14} {t[a]:8.3f} {s} {build} {t[b]:8.3f} {t[b]-t[a]:8.3f} {b-a+1:7d}")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1]))
|
||||
Reference in New Issue
Block a user