mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
Golden gate: Linux baselines, canonical save, gate hardening (D521-D532)
Linux reference-frame set for all 21 levels and the cross-platform golden rule (D521); golden tooling made non-destructive (D524); the gate pins a canonical in-tree save (D529) and the PRNG seed (D532); the capture tool's per-level re-pin bug fixed and the Linux set re-captured under the canonical save (D530, D531); no-arg verify.sh exits non-zero. README and docs visual/consolidation passes; the 15 MB preview gif replaced by stills. Refs: D521 D523 D524 D525 D526 D527 D528 D529 D530 D531 D532
This commit is contained in:
1 parent
aa5a1b81fe
commit
452fa1025a
203 files changed
+2046
-433995
No files matched your search
@@ -38,7 +38,7 @@ More is already in place than "audio not started" suggests:
|
||||
`osAiGetLength()` in `port/src/libultra.c:852-862` discard everything
|
||||
(`osAiGetLength` returns 0), and `port/src/audio.c` never opens an SDL
|
||||
device. `main.c:141-142` already calls `audioInit()` / `mixerInit()`.
|
||||
- **The PD reference is local** at `C:\Users\james\Source\Repos\pd_port`,
|
||||
- **The PD reference is local** at `<repos>\pd_port`,
|
||||
with the full audio stack: `port/src/audio.c` (75 lines, SDL device +
|
||||
queue), `port/src/mixer.c` (~720 lines, software RSP-audio-ucode), and the
|
||||
wiring trick in `include/PR/abi.h`.
|
||||
@@ -201,4 +201,4 @@ M-50) → v0.4.0".
|
||||
| `port/src/libultra.c:848-863` | `osAi*` shims — wire to audio.c (Phase 1) |
|
||||
| `port/src/libultra.c:1237` | M_AUDTASK branch — stays a completing no-op; hosts `GE_AUDIOTRACE` |
|
||||
| `port/src/ucode.c` | Dummy `aspMain*` markers stay forever under CPU-bypass — document decision |
|
||||
| `C:\Users\james\Source\Repos\pd_port\port\src\{audio,mixer}.c`, `include\PR\abi.h` | PD ground truth: device glue + DSP cores + the macro-swap pattern |
|
||||
| `<repos>\pd_port\port\src\{audio,mixer}.c`, `include\PR\abi.h` | PD ground truth: device glue + DSP cores + the macro-swap pattern |
|
||||
@@ -5,7 +5,7 @@ this session; verification in `docs/dev/findings.md` D356 (GE_WSPROBE_RESET
|
||||
front + in-stage probes, regressions, build). Supersedes the "BOND FILE"
|
||||
section introduced in D353. Baselines: Turok PC port options (Nightdive, list
|
||||
provided by the maintainer), the PD port's `port/src/optionsmenu.c`
|
||||
(`C:\Users\james\Source\Repos\pd_port`), and plan §6 of
|
||||
(`<repos>\pd_port`), and plan §6 of
|
||||
`docs/dev/OPTIONS-MENU-PLAN.md` (the original "align with Turok" note).
|
||||
|
||||
## 1. Goal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# D357 — Settings thresholds & values: align display units/defaults with the PD port + Turok PC
|
||||
|
||||
Status: **IMPLEMENTED 2026-09-30 (findings D443) for mouse sens ×, deadzone whole-%, volume step, FOV degrees, MSAA 16×, Restart game; texture filter unchanged by decision; frame-rate cap deferred (§0 presets + custom = separate project). Approved with changes; see §0.** Proposal dated 2026-09-27. Baselines: the PD port
|
||||
checkout (`C:\Users\james\Source\Repos\pd_port`, `port/src/optionsmenu.c` +
|
||||
checkout (`<repos>\pd_port`, `port/src/optionsmenu.c` +
|
||||
`input.c`/`video.c` config registrations), the Turok PC (Nightdive) list from
|
||||
the maintainer's notes (`docs/dev/notes/OPTIONS-MENU-PLAN.md` §6 — *taken from
|
||||
user notes, not checked independently*), and the N64 watch (ground truth for
|
||||
|
||||
+17
-12
@@ -1,5 +1,10 @@
|
||||
# HANDOFF ARCHIVE — session-by-session narrative
|
||||
|
||||
> **Local machine paths are genericised** in this archive: `<repo>` = this repo's
|
||||
> working directory, `<repos>` = the local source-repos root, `<games>` / `<videos>`
|
||||
> = the local games / video roots, `<python>` = the local CPython install, `<temp>`
|
||||
> = a writable native temp dir. Session facts are unchanged.
|
||||
|
||||
> **Reference only.** Current state lives in the [README](../../README.md)
|
||||
> "Status" section and `docs/dev/LEVEL-STATUS.md`; per-finding detail is in
|
||||
> [`findings.md`](findings.md) §F/§H — look up via
|
||||
@@ -985,7 +990,7 @@ In KEEP-A test (sky quad only), the band shows (98,97,128) = fog color. This mea
|
||||
### Environment & build
|
||||
|
||||
- Build: `export PATH="/c/msys64/mingw64/bin:$PATH" && cmake --build build-pc -j 8`
|
||||
- Python: `"C:\Users\james\AppData\Local\Programs\Python\Python313\python.exe"` (has numpy+PIL)
|
||||
- Python: `"<python>\python.exe"` (has numpy+PIL)
|
||||
- Run: from repo root, ROM in `./data/`. Level: `-level_36`
|
||||
- Frame capture: F12 → `ppm/frame_NNN.ppm`; or `GE_PCDUMP=lo-hi:step`
|
||||
- Input script: `GE_INPUTSCRIPT="120:START;..."` (M-99: CANNOT reach mouselook)
|
||||
@@ -1081,7 +1086,7 @@ Facility = `-level_34` (stageId 34 = `LEVELID_FACILITY`; `boss.c` decodes `-leve
|
||||
4. Diff behaviour vs a level whose opening beat DOES work (e.g. Dam `-level_33`) to isolate "Facility data" vs "general beat machinery".
|
||||
5. Any fix: port-only unless it's the documented ABI/layout class; new finding = D266+; append to `docs/porting-notes.md` if a new bug class emerges.
|
||||
|
||||
**Environment (unchanged from prior sessions):** build `export PATH="/c/msys64/mingw64/bin:$PATH" && cmake --build build-pc -j 8` (or `./build-pc.sh ntsc-final`); kill any running `ge007*` before linking. Exe `build-pc/ge007.x86_64.exe`, run from repo root (ROM in `./data/`). Headless: `GE_INPUTSCRIPT` (tokens A/B/Z/START/UP/DOWN/LEFT/RIGHT/CUP/CDOWN/CLEFT/CRIGHT/SDOWN/SNONE, `tick:TOKEN;…`, pulse = 6 reads), `GE_PCDUMP=lo-hi:step`, `GE_INPUTLOG=1`, F12 → `ppm/shot_NNN.ppm`. Python (PIL/numpy) at `/c/Users/james/AppData/Local/Programs/Python/Python313/python.exe`; **cast uint8 arrays to int32 before bit shifts**.
|
||||
**Environment (unchanged from prior sessions):** build `export PATH="/c/msys64/mingw64/bin:$PATH" && cmake --build build-pc -j 8` (or `./build-pc.sh ntsc-final`); kill any running `ge007*` before linking. Exe `build-pc/ge007.x86_64.exe`, run from repo root (ROM in `./data/`). Headless: `GE_INPUTSCRIPT` (tokens A/B/Z/START/UP/DOWN/LEFT/RIGHT/CUP/CDOWN/CLEFT/CRIGHT/SDOWN/SNONE, `tick:TOKEN;…`, pulse = 6 reads), `GE_PCDUMP=lo-hi:step`, `GE_INPUTLOG=1`, F12 → `ppm/shot_NNN.ppm`. Python (PIL/numpy) at `<python>`; **cast uint8 arrays to int32 before bit shifts**.
|
||||
|
||||
---
|
||||
|
||||
@@ -1345,7 +1350,7 @@ will do a full manual playtest in lieu of the `verify.sh` sweep.
|
||||
3. **Steam Deck test session (~1 hr, needs the hardware — who has the Deck?):** install tarball via USB, Facility walk+fire (D203 repro profile), gamepad check, `Video.DisplayFPS` on Dam + Streets, grab `ge007.crash.log` if anything faults.
|
||||
4. Tag `v0.2.0-pre`; publish pre-release with known issues: D243 (Dam end race), D230 (music quality), D245 (water seam), D246 (edge strips), D197 (face wrap on Silo), D75 (front-end models), the D251 4K ghost row, and "not yet verified on real Deck hardware". Flip to final after the user's playtest passes.
|
||||
|
||||
**Environment:** build as before (`/c/msys64/usr/bin/bash.exe -lc 'export PATH=/c/msys64/mingw64/bin:$PATH; cd /c/Users/james/Source/Repos/gh-fullhist && ./build-pc.sh ntsc-final'`). CI (`.github/workflows/ci.yml`) builds Linux per push — the `linux-build` job's artifact is the bundle source for the tarball if local Linux testing isn't available.
|
||||
**Environment:** build as before (`/c/msys64/usr/bin/bash.exe -lc 'export PATH=/c/msys64/mingw64/bin:$PATH; cd <repo> && ./build-pc.sh ntsc-final'`). CI (`.github/workflows/ci.yml`) builds Linux per push — the `linux-build` job's artifact is the bundle source for the tarball if local Linux testing isn't available.
|
||||
|
||||
## F10 overlay QoL session (2026-09-13, shipped in v0.2.0-pre) — D251; known bug: intermittent 4K-fullscreen "repeat of top entry" at panel bottom (MSAA×fullscreen driver suspect, unverified)
|
||||
|
||||
@@ -1373,7 +1378,7 @@ will do a full manual playtest in lieu of the `verify.sh` sweep.
|
||||
**Environment / state notes:**
|
||||
- User's live `data/ge007.ini` already has `Fullscreen = 1`, `MSAA = 4` (backup at `/tmp/ge007.ini.bak` — I did not modify their ini). Monitor: single display 3072×1728, window fullscreen at 0,0.
|
||||
- `ppm/user4k.png` exists from a PowerShell `CopyFromScreen` capture but was taken with the overlay **closed** — low value; user asked to stop analyzing captures.
|
||||
- Build: `/c/msys64/usr/bin/bash.exe -lc 'export PATH=/c/msys64/mingw64/bin:$PATH; cd /c/Users/james/Source/Repos/gh-fullhist && ./build-pc.sh ntsc-final'`. Launch from repo root: `./build-pc/ge007.x86_64.exe &` (needs `./data/` ROM).
|
||||
- Build: `/c/msys64/usr/bin/bash.exe -lc 'export PATH=/c/msys64/mingw64/bin:$PATH; cd <repo> && ./build-pc.sh ntsc-final'`. Launch from repo root: `./build-pc/ge007.x86_64.exe &` (needs `./data/` ROM).
|
||||
- Design doc for the overlay: `docs/dev/OPTIONS-MENU-PLAN.md` (approach C: port-layer overlay, zero src/ menu edits).
|
||||
|
||||
## M-123 (2026-09-14) — D194 ① log mined + wrap-spike fixed; spazz NOT in our writes (they're rock-stable); next: live capture with the new residue/autoaim logging, then user A/B playtest
|
||||
@@ -1398,7 +1403,7 @@ will do a full manual playtest in lieu of the `verify.sh` sweep.
|
||||
|
||||
## M-122 (2026-09-13) — D194 GEPD-mirror aim IMPLEMENTED + user-confirmed "mechanically works"; three items left: ① crosshair/arm spazz glitch, ② aim-mode FPS drop (perf.ps1), ③ sensitivity tuning. Next session starts at ①.
|
||||
|
||||
**The aim rewrite landed.** After four failed stick-synthesis models (absolute → dial → relative-angle → velocity-mapped stick; see M-121 + commits `8a8d066b`/`650b7f63`/`7f65ed15`), the session found and read **GEPD's actual source** (`C:\Users\james\Games\Emulators\Nintendo 64\1964_GEPD_Edition\1964\source.tar.xz` → `MouseInjectorPlugin/games/goldeneye.c`, extracted copy at `/c/Users/james/AppData/Local/Temp/gepd-src/`) and mirrored its model exactly. **User verdict: "mechanically it works... the aim mode works how we'd want."** Committed as `ef49d9e6` on `fix/d194-mouse-dt-decouple` (branch is up to date with main; PR #75/#76 already merged in).
|
||||
**The aim rewrite landed.** After four failed stick-synthesis models (absolute → dial → relative-angle → velocity-mapped stick; see M-121 + commits `8a8d066b`/`650b7f63`/`7f65ed15`), the session found and read **GEPD's actual source** (`<games>\Emulators\Nintendo 64\1964_GEPD_Edition\1964\source.tar.xz` → `MouseInjectorPlugin/games/goldeneye.c`, extracted copy at `<temp>/gepd-src/`) and mirrored its model exactly. **User verdict: "mechanically it works... the aim mode works how we'd want."** Committed as `ef49d9e6` on `fix/d194-mouse-dt-decouple` (branch is up to date with main; PR #75/#76 already merged in).
|
||||
|
||||
**The model (all in `port/src/input.c`, `aimGepdCompute()` ~line 1377):** mouse delta moves a crosshair POSITION accumulator (`s_gepdCrossX/Y`, clamped ±`GEPD_CROSSHAIR_LIMIT`=5.16); each tick it writes `crosshair_x/y_pos` + `gun_azimuth_angle/turning` (GEPD formulas, failsafe weapon offsets 0.15/0, RATIOFACTOR=1 for our 4:3, `GEPD_BASE_FOV`=90) and edge-scrolls the camera only past 72% toward the screen edge (`(ratio-0.72)*475*dt*(fov/90)`). **No look stick is emitted while aiming.** On aim release we stop writing and the game's own damping eases crosshair+arm back to centre; every non-aim tick adopts `crosshair_x/y_pos` so re-entry starts where the game left it (GEPD does the same).
|
||||
|
||||
@@ -1437,7 +1442,7 @@ will do a full manual playtest in lieu of the `verify.sh` sweep.
|
||||
**RMB aim-mode (D194 continuation): two more attempts this session, both did not land, session ended mid-plan on the weekly usage limit.**
|
||||
|
||||
- **Attempt 1 (small, safe): raised `AIM_MOVE_THRESH` 0.3->2.5px and lowered `Input.MouseAimSpeed` default 16->14 (matching the user's live ini, which had drifted to 50).** User's verdict: **"didn't actually fix anything"** — confirms the core problem isn't a magnitude/gain issue, it's the shape of the response.
|
||||
- **Real root cause found via code reading (still valid, not invalidated by what follows):** `bondviewProcessInput(s8 stick_x, s8 stick_y, ...)` in `src/game/bondview2.c` takes a **signed 8-bit stick** — the smallest representable nonzero aim-turn value is a hard jump to 10% speed (stick=61; `(stick-60)/10` is exactly 0 at stick<=60). No threshold/curve tuning on the port's synthesis side can produce a smooth ramp through an integer that can only be 60 or >=61. Confirmed via `pd_port` (`C:\Users\james\Source\Repos\pd_port`) reference: PD's own mouse-look (`src/game/player.c:3669`, `src/game/bondeyespy.c:945`) never synthesizes an N64 stick at all -- it's `theta += mdx * scale`, a continuous float angle accumulator, no floor, no int8 quantization anywhere.
|
||||
- **Real root cause found via code reading (still valid, not invalidated by what follows):** `bondviewProcessInput(s8 stick_x, s8 stick_y, ...)` in `src/game/bondview2.c` takes a **signed 8-bit stick** — the smallest representable nonzero aim-turn value is a hard jump to 10% speed (stick=61; `(stick-60)/10` is exactly 0 at stick<=60). No threshold/curve tuning on the port's synthesis side can produce a smooth ramp through an integer that can only be 60 or >=61. Confirmed via `pd_port` (`<repos>\pd_port`) reference: PD's own mouse-look (`src/game/player.c:3669`, `src/game/bondeyespy.c:945`) never synthesizes an N64 stick at all -- it's `theta += mdx * scale`, a continuous float angle accumulator, no floor, no int8 quantization anywhere.
|
||||
- **User also reported a second, more specific symptom mid-investigation: aim resets to center the instant mouse movement pauses (even while still holding RMB), breaking precision tasks (shoot-the-lock, watch-laser-cuts-metal-in-train puzzles).** Traced `bondviewCurrentPlayerUpdateSpeedTheta`/`speedVertaUp`/`Down` (bondview2.c) in detail: confirmed this is a smoothed rate-based decel model (`g_CurrentPlayer->speedtheta` eases toward 0 over several ticks when input stops, does NOT hard-reset) -- so a literal snap-to-center was not found in that specific mechanism. Root cause of the reset symptom specifically was **not conclusively identified** before moving to the rewrite.
|
||||
- **Attempt 2 (bigger, PD-style, approved by user before starting): bypassed the s8-stick synthesis entirely for aim-mode.** `port/src/input.c` computed a continuous -1..1 turn/vert speed (`inputGetContinuousAimSpeed()`, new function + header decl) instead of synthesizing `sx`/`sy`; `src/game/bondview2.c`'s aim-mode block (`#ifdef PORT`) read it directly, bypassing the `(stick-60)/10` conversion but leaving all downstream `speedtheta`/`speedverta` easing untouched. Removed the now-dead `Input.AimBand`/`Input.MouseAimCurve` knobs. **Compiled clean (verified both PORT and N64 `#ifdef` brace balance carefully), crash-free in a headless sanity check -- but broke live: "somethings broken... can't aim at all... it locks my input completely with the mouse."** Root cause of THAT breakage was not identified (no repro available headlessly; ran out of session before a careful live-debug pass). **Fully reverted** (`git checkout -- src/game/bondview2.c port/src/input.c port/include/input.h` back to the `db6eba2b` merge commit) — repo confirmed clean, PR #62's mouse work is back to its pre-session (working, if imperfectly-tuned) state. Live ini's `MouseAimSpeed` also manually restored 14->16 to match the reverted code default.
|
||||
|
||||
@@ -1893,7 +1898,7 @@ current testing, folded in:
|
||||
player's already-fixed 1P viewmodel isn't implicated. Narrows the
|
||||
search surface.
|
||||
3. **D194 mouse feel — external corroboration, not a new mechanism.**
|
||||
Investigated `C:\Users\james\Games\Emulators\Nintendo 64\1964_GEPD_Edition`
|
||||
Investigated `<games>\Emulators\Nintendo 64\1964_GEPD_Edition`
|
||||
(the user's reference point for "feels better") — the 1964 emulator's
|
||||
bundled `Mouse_Injector.dll` (closed-source, no source available; the
|
||||
emulator's own `source.tar.xz` is just the stock 1964 core). Its exports
|
||||
@@ -2839,7 +2844,7 @@ except `bg.c`'s `GE_D63` lines which are not `#ifdef PORT`-guarded).
|
||||
|
||||
## Playtest bug reports (M-49 cont., 2026-09-04) — logged for future triage, NOT v0.1.0 blockers
|
||||
|
||||
User playtested the **v0.1.0 win64 bundle** (`C:\Users\james\Games\goldeneye-pc-port-0.1.0-win64`,
|
||||
User playtested the **v0.1.0 win64 bundle** (`<games>\goldeneye-pc-port-0.1.0-win64`,
|
||||
fresh save). Bugs filed in findings §F (D191–D197), all alpha-acceptable.
|
||||
NB: Cradle does **not** crash — it's the D193 scripted-sequence stall (an
|
||||
earlier note here wrongly said "Cradle also crashes").
|
||||
@@ -3303,7 +3308,7 @@ collision geometry. Full ranked next-steps in findings.md D205.
|
||||
6. Build + smoke after probe removal: `./build-pc.sh ntsc-final`, then
|
||||
`-level_09` 60 s crash-free with `GE_AUDIOTRACE=1`.
|
||||
### Environment (unchanged except noted):
|
||||
- Build: `/c/msys64/usr/bin/bash.exe -lc 'cd /c/Users/james/Source/Repos/gh-fullhist && ./build-pc.sh ntsc-final'` (login shell for MINGW64 PATH; SDL2.dll at `/c/msys64/mingw64/bin`).
|
||||
- Build: `/c/msys64/usr/bin/bash.exe -lc 'cd <repo> && ./build-pc.sh ntsc-final'` (login shell for MINGW64 PATH; SDL2.dll at `/c/msys64/mingw64/bin`).
|
||||
- Capture run: `GE_AUDIOTRACE=1 GE_INPUTSCRIPT="$(cat ../scratchpad/exact_run3_script.txt)" ./ge007.x86_64.exe -level_09` from `build-pc/`; kill with `taskkill //F //PID <pid>` (msys `kill` does not work).
|
||||
- `mupen64/` (N64 emulator, user's A/B reference) at repo root — added to .gitignore this session.
|
||||
- `scratchpad/` is gitignored: banktest/, exact_match.py, fire scripts, match outputs are all local-only. To re-verify the bank exoneration: `scratchpad/banktest/harness.exe` (rebuild from harness.c against port/src/romdata.c if stale) then `python scratchpad/banktest/diff_bank.py`.
|
||||
@@ -3391,7 +3396,7 @@ archived user capture: `scratchpad/d202-m66/` (`check_dump.py`,
|
||||
The `[EXPIRE]` line and the guard/expire code STAY (permanent, documented).
|
||||
Build note for this shell: toolchain at `/c/msys64/mingw64/bin`, and
|
||||
`cmake --build -j` hit "Cannot create temporary file in C:\\Windows\\" —
|
||||
`ninja -j1` with `TMP/TEMP=C:/Users/james/AppData/Local/Temp` works.
|
||||
`ninja -j1` with a writable native `TMP/TEMP` works.
|
||||
|
||||
## Done this session (M-66) — D202 ROOT CAUSE ESTABLISHED: the audible stuck door loop is sound 203 behaving exactly as ROM + ground-truth code specify — faithful N64 behaviour (original quirk), not a port bug. Disposition A/B/C pending user decision.
|
||||
|
||||
@@ -4765,7 +4770,7 @@ does not.
|
||||
Build locally: `cmake -S . -B build-linux -G Ninja -DROMID=ntsc-final
|
||||
-DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14` then `ninja -C
|
||||
build-linux` (~20s on drvfs). WSL `Ubuntu` distro provisioned (toolchain +
|
||||
SDL2/zlib/GL dev); repo at `/mnt/c/Users/james/Source/Repos/gh-fullhist`
|
||||
SDL2/zlib/GL dev); repo at `<repo>`
|
||||
(fixed the malformed `/etc/wsl.conf` `[automount]` + `wsl --shutdown`).
|
||||
`data/` has the ROM + sidecars already.
|
||||
|
||||
@@ -5074,7 +5079,7 @@ playtest handoff: `docs/dev/M-35-PLAYTEST-CHECKLIST.md`; WI-3 design:
|
||||
(`d43_emit.py` / `d69_emit.py` / `d88_emit.py --regen`, all pass clean) → `./build-pc.sh
|
||||
ntsc-final` links 242/242, `-level_09` runs crash-free past frame 1200. **No `assets/*.bin`
|
||||
extraction needed** — the committed `assets/` is self-sufficient; the ROM is runtime-only.
|
||||
The old repo at `C:/Users/james/Source/Repos/007` has the ROM + a prior build.
|
||||
The old repo at `<repos>/007` has the ROM + a prior build.
|
||||
|
||||
- **D168 — VERIFIED.** Rebuilt with the flip fix, captured `-level_09` frame 320:
|
||||
the exit arrow points up, ammo "7|93" reads normally bottom-right — matches
|
||||
|
||||
+112
-76
@@ -50,7 +50,7 @@ and forth** through shared written artifacts, directed by one human.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Local agent | `unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL` on a single **NVIDIA RTX 5090**, driven mainly through the **[pi](https://pi.dev/)** coding agent. Unsloth Desktop (Unsloth's local model runtime, which can drive agents such as Claude Code) was also trialed but not used significantly. |
|
||||
| Local agent | `unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL` on a single **NVIDIA RTX 5090**, driven mainly through the **[pi](https://github.com/earendil-works/pi)** coding agent. Unsloth Desktop (Unsloth's local model runtime, which can drive agents such as Claude Code) was also trialed but not used significantly. |
|
||||
| Hosted agent | **Claude**, via **Claude Code**, on a Claude Pro subscription; mostly **Sonnet 5**, with **Opus 5** used as an escalation tier for the hardest problems and whenever there was subscription budget to spend on it |
|
||||
| Human | one person: direction, work partitioning, integration, and every build / playtest / frame-capture the agents could not run |
|
||||
| Base | fork of the [GoldenEye 007 decompilation](https://github.com/n64decomp/007) (years of prior work by Larry Ficken ("kholdfuzion") and contributors) |
|
||||
@@ -59,58 +59,32 @@ and forth** through shared written artifacts, directed by one human.
|
||||
The port is the GoldenEye-specific porting work **on top of** those two
|
||||
existing bodies of work; it is not a from-scratch reimplementation of either.
|
||||
|
||||
In practice the models formed a **three-tier escalation**: the local model
|
||||
handled well-scoped work, Sonnet 5 took what it stalled on, and Opus 5 was
|
||||
reserved for the bugs that needed the most reasoning held at once; the same
|
||||
"escalate when stuck" move applied at every level.
|
||||
In practice the models formed a **three-tier escalation** — the local model
|
||||
handled well-scoped work, Sonnet 5 took what it stalled on, and Opus 5 the
|
||||
rest; the same "escalate when stuck" move applied at every level.
|
||||
|
||||
## Timeline
|
||||
|
||||
All dates from this repository's own commit history (August–September 2026).
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
dateFormat YYYY-MM-DD
|
||||
axisFormat %b %d
|
||||
title GoldenEye 007 PC port; from fork to v0.3.0
|
||||
section Local model - Qwen 3.8 via pi
|
||||
Fork + PC-port scaffolding :m1, 2026-08-16, 1d
|
||||
Full compile + link (~230 TUs) :m2, 2026-08-20, 1d
|
||||
Boot to window (ROM map + SDL2) :m3, 2026-08-20, 1d
|
||||
OS shims, threads, fast3d integration :2026-08-21, 2d
|
||||
First rendered frames :m4, 2026-08-22, 1d
|
||||
Offline asset-conversion pipeline :2026-08-22, 2d
|
||||
Entire intro renders (logos to cast) :m5, 2026-08-24, 1d
|
||||
section Both agents - handoff workflow
|
||||
Claude joins :milestone, 2026-08-27, 0d
|
||||
Stage load; Bunker 1 renders + firefight :2026-08-27, 2d
|
||||
21 solo levels load + render + no-crash :m6, 2026-08-29, 1d
|
||||
SDL input layer (kbd/mouse/gamepad) :2026-08-29, 1d
|
||||
Front-end flow (menu to briefing to start) :m7, 2026-08-30, 1d
|
||||
File-backed EEPROM saves :2026-08-31, 1d
|
||||
section Month one - front end to v0.3.0
|
||||
Audio mixer (music + SFX) :2026-09-02, 7d
|
||||
Steam Deck hardening + F10 overlay QoL :2026-09-14, 3d
|
||||
Final fix sweep (D309-D321) + release review :2026-09-18, 3d
|
||||
v0.3.0 released (full campaign playtested) :milestone, 2026-09-20, 0d
|
||||
```text
|
||||
# phase timeline (from the port's own commit dates)
|
||||
Aug 16 day 0 fork + PC-port scaffolding
|
||||
Aug 20 day 4 full compile + link (~230 TUs); boot to window
|
||||
Aug 22 day 6 first rendered frames; offline asset-conversion pipeline
|
||||
Aug 24 day 8 entire intro renders (logos -> gun-barrel -> cast)
|
||||
Aug 27 day 11 Claude joins (handoff workflow begins)
|
||||
Aug 29 day 13 21 solo levels load + render + unattended no-crash; SDL input layer
|
||||
Aug 30 day 14 front-end flow (menu -> briefing -> start)
|
||||
Aug 31 day 14 file-backed EEPROM saves
|
||||
Sep 02 audio mixer (music + SFX)
|
||||
Sep 14 Steam Deck hardening + F10 overlay QoL
|
||||
Sep 18 final fix sweep (D309-D321) + release review
|
||||
Sep 20 day 35 v0.3.0 released: full campaign at Agent difficulty, audio
|
||||
complete, bundles for Windows, Linux and Steam Deck
|
||||
```
|
||||
|
||||
- **Day 0** (16 Aug): repository forked, PC-port scaffolding added.
|
||||
- **Day 4** (20 Aug): the entire ~230-TU game + libultra set compiles and
|
||||
links as a host binary.
|
||||
- **Day 6** (22 Aug): first real frames render.
|
||||
- **Day 8** (24 Aug): the whole intro sequence renders; logos, gun-barrel,
|
||||
cast roll.
|
||||
- **Day 11** (27 Aug): second agent joins.
|
||||
- **Day 13** (29 Aug): **all 21 solo missions load, render, and survive an
|
||||
unattended play window without crashing.**
|
||||
- **Day 14** (30–31 Aug): front end playable end to end (menu → mission
|
||||
select → difficulty → briefing → start); file-backed saves.
|
||||
- **Day 35** (20 Sep): **v0.3.0 released** — the full campaign playtested
|
||||
end to end at Agent difficulty, audio complete, bundles for Windows,
|
||||
Linux and Steam Deck.
|
||||
|
||||
So roughly **two weeks**, one person part-time, to take a decompilation from
|
||||
Roughly **two weeks**, one person part-time, took the decompilation from
|
||||
"builds an N64 ROM" to "boots on desktop, renders every solo level, playable
|
||||
through the front end into the early game". The rest of month one (29 Aug –
|
||||
20 Sep) took it from there to a public release: the 21-level sweep to
|
||||
@@ -134,12 +108,15 @@ issues documented rather than outstanding.
|
||||
|
||||
### Commit velocity
|
||||
|
||||
```mermaid
|
||||
xychart-beta
|
||||
title "Commits per week (week start)"
|
||||
x-axis ["8/16", "8/23", "8/30", "9/6", "9/13", "9/20"]
|
||||
y-axis "commits" 0 --> 250
|
||||
bar [20, 109, 203, 141, 220, 6]
|
||||
```text
|
||||
# commits per week (week start)
|
||||
8/16 ## 20
|
||||
8/23 ########### 109
|
||||
8/30 #################### 203
|
||||
9/6 ############## 141
|
||||
9/13 ###################### 220
|
||||
9/20 # 6 (release day only)
|
||||
(each # ~ 10 commits)
|
||||
```
|
||||
|
||||
Weekly totals (the final week is release day only). The step up from the
|
||||
@@ -150,10 +127,11 @@ at once.
|
||||
|
||||
### Who did what
|
||||
|
||||
```mermaid
|
||||
pie showData title "Commits by agent (raw count, snapshot through early September)"
|
||||
"Claude" : 161
|
||||
"Local model (Qwen 3.8 / pi)" : 62
|
||||
```text
|
||||
# commits by agent (raw count, snapshot through early September)
|
||||
Claude ################ 161 (72%)
|
||||
Local model (Qwen 3.8/pi) ###### 62 (28%)
|
||||
(each # ~ 10 commits)
|
||||
```
|
||||
|
||||
(Phase A, the first 26 commits, to 24 Aug, was entirely the local model,
|
||||
@@ -184,10 +162,11 @@ chain in relatively few, large commits, and the local model kept contributing
|
||||
raw commits; the foundation is a heavier third of the project than its commit
|
||||
share suggests; the developer's estimate is roughly:
|
||||
|
||||
```mermaid
|
||||
pie showData title "Agent effort, milestone-weighted"
|
||||
"Claude" : 60
|
||||
"Local model (Qwen 3.8 / pi)" : 40
|
||||
```text
|
||||
# agent effort, milestone-weighted
|
||||
Claude ############ 60%
|
||||
Local model (Qwen 3.8/pi) ######## 40%
|
||||
(each # ~ 5%)
|
||||
```
|
||||
|
||||
The local model's ~40% is front-loaded and foundational (the build, the boot
|
||||
@@ -201,21 +180,19 @@ result worth taking away.
|
||||
|
||||
This is the part worth paying attention to.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
H["Human: direction, integration,<br/>build + playtest verification"]
|
||||
C["Claude / Claude Code<br/>frontier, hosted"]
|
||||
Q["Qwen 3.8 via pi<br/>open-weight, local RTX 5090"]
|
||||
D[(Shared artifacts:<br/>HANDOFF.md · findings.md · porting-notes.md)]
|
||||
```text
|
||||
# the handoff workflow
|
||||
|
||||
H -->|scopes task, budget, files| C
|
||||
H -->|scopes task, budget, files| Q
|
||||
C <-->|reads / appends| D
|
||||
Q <-->|reads / appends| D
|
||||
C -.->|usage limit reached| Q
|
||||
Q -.->|hard structural bug| C
|
||||
C -->|patch + write-up| H
|
||||
Q -->|patch + write-up| H
|
||||
HUMAN
|
||||
direction, integration, build + playtest verification
|
||||
| scopes task, budget, files | scopes task, budget, files
|
||||
v v
|
||||
CLAUDE (hosted) QWEN 3.8 / pi (local, RTX 5090)
|
||||
| patch + write-up | patch + write-up
|
||||
+--------------+ +--------------+
|
||||
v v
|
||||
SHARED ARTIFACTS (both agents read + append)
|
||||
HANDOFF.md . findings.md . porting-notes.md
|
||||
```
|
||||
|
||||
Both agents worked against the **same three written artifacts**, which is what
|
||||
@@ -255,8 +232,7 @@ Honest notes, for anyone weighing whether this transfers.
|
||||
|
||||
- The **local model carried the groundwork phase**; build system, boot
|
||||
chain, OS shims, and the offline-converter architecture. None of it was
|
||||
rewritten later. A 27B open model on one consumer GPU was genuinely productive
|
||||
on this.
|
||||
rewritten later.
|
||||
- **The written-artifact discipline made agent output compound.** An agent
|
||||
starting cold late in the project was more effective than one early on,
|
||||
because the accumulated notes were good. This is also what made the two
|
||||
@@ -286,3 +262,63 @@ Honest notes, for anyone weighing whether this transfers.
|
||||
**Still outstanding:** see
|
||||
[`docs/ROADMAP.md`](https://github.com/jkdansereau/goldeneye-pc-port/blob/main/docs/ROADMAP.md),
|
||||
the single tracker for open work.
|
||||
|
||||
## Since the two-agent phase
|
||||
|
||||
The two-agent setup above is the **initial phase**, snapshotted at v0.3.0
|
||||
(the project has since shipped v0.4.x and is heading to v0.5.0; the model
|
||||
and harness record below is current through that point).
|
||||
|
||||
Since then the emphasis has shifted from "the two models that built it" to
|
||||
**testing a lot of new models and harnesses**, to find what's fastest and
|
||||
cheapest per task. The long-time local workhorse stayed **Unsloth's Qwen 3.8 27B**;
|
||||
in the final week that broadened into a menu, and the **current standard is
|
||||
NInfer + Strata**. On the hosted side, the Claude orchestrator stepped up from
|
||||
**Sonnet 5 / Opus 5** to the **5.5 tier** (Sonnet 5.5 / Opus 5.5, out in the
|
||||
last few weeks), which has driven the most recent work. The local menu:
|
||||
|
||||
- **Qwen 3.8 27B** ([Unsloth](https://huggingface.co/unsloth/Qwen3.8-27B-GGUF),
|
||||
`UD-Q4_K_XL`) — the primary local workhorse for most of the port's life, doing
|
||||
nearly all of the local groundwork on its own. A larger-context
|
||||
[`ISTA-DASLab/Qwen3.8-27B-GSQ-RCO-GGUF`](https://huggingface.co/ISTA-DASLab/Qwen3.8-27B-GSQ-RCO-GGUF)
|
||||
(`IQ3_S`) was also briefly trialed for bigger-context workloads, then shelved
|
||||
(little use since v0.2.0).
|
||||
- **NInfer (Windows)**
|
||||
([natpate/ninfer-windows](https://github.com/natpate/ninfer-windows), v0.9.0,
|
||||
CUDA 13.1 — a standalone Windows port of the NInfer engine, with MTP /
|
||||
DFlash2 speculative decoding) — ran **Qwen 3.8 27B** in base, NVFP4 and
|
||||
NVFP4-full artifacts; trialed in the final week, now half of the standard
|
||||
and the fast day-to-day local driver.
|
||||
- **Qwen 3.8 Flash-Next** via
|
||||
[Strata](https://github.com/Niko1221/Strata) (Niko1221's MIT-licensed
|
||||
C++/CUDA/HIP engine) — a 125B mixture-of-experts model that normally needs a
|
||||
server, run **locally on a single gaming GPU** (IQ1_M, 1-bit) for the
|
||||
biggest-context coding passes. The other half of the standard.
|
||||
- **[claude-code-delegate-local](https://github.com/fegone/claude-code-delegate-local)**
|
||||
— an MCP server that let the Claude Code orchestrator and the local models
|
||||
talk, delegating Claude's subagents to the local engines. A nice tool, but
|
||||
**mostly deprecated now**: hand-offs between agents are done by hand for now,
|
||||
pending a better parallel-agent handoff system that drops the MCP overhead.
|
||||
- **GPT-6 (Sol)** via [OpenRouter](https://openrouter.ai) — a frontier hosted
|
||||
model, **trialed** to see how it held up (not the hardest-work tool). Its
|
||||
code output is still owed a code-quality audit in this doc.
|
||||
|
||||
The practical effect: the project stopped depending on any one model or its
|
||||
usage limits. The local GPU is now the default path for high-volume work, with
|
||||
hosted frontier models reserved for the problems the local models can't close.
|
||||
|
||||
**Measurement owed.** Which of these was best on a given task — and each
|
||||
model's rough cost-to-performance ratio — has not yet been measured properly;
|
||||
attributing individual commits to the model that produced them is still a
|
||||
manual pass. That includes a **code-quality audit of the GPT-6 (Sol) trial**.
|
||||
All of it is pending and will be added here when it lands.
|
||||
|
||||
A concrete reason the commit-date route is unreliable: the `D350` commit
|
||||
(`1303c0eb`, "expose watch-backed Bond settings in PC options and F10")
|
||||
carries a **27 Sep** timestamp on both its author and committer dates, but
|
||||
the session notes place that work on **4 Oct**. Because the two git dates
|
||||
agree, this is **not** a rebase artifact (a rebase would have moved the
|
||||
committer date while preserving the author date); it is a genuine divergence
|
||||
between the recorded commit time and the working session, and resolving it
|
||||
takes the session log, not the commit date. This is the class of edge case
|
||||
the attribution pass has to walk by hand.
|
||||
@@ -380,4 +380,16 @@ D517,FIXED,Holding left/right on a Bond settings row dropped the fps:,FIXED (liv
|
||||
D518,FIXED,Pad layout preset was one global value:,FIXED (live pass 2026-10-04 incl.
|
||||
D519,FIXED,"One PC options UI: the file-select ""PC Options"" entry opens the F10 overlay; the MENU_PC_OPTIONS screen is deleted —",FIXED (headless-verified 2026-10-04; by-eye pass owed)
|
||||
D520,FIXED,"F10 overlay slider wedge, slider marker and dropdown arrow antialiased (they stepped in whole canvas pixels that grow with the window) —",FIXED (headless before/after capture; by-eye owed)
|
||||
D521,PARTIAL,A fixed-frame golden window that overlaps the intro flyby is platform-nondeterministic (cross-platform goldens); verify.sh's linux pixel-gate skip is driver-co…,PARTIAL (rule recorded 2026-10-04; the two residual bands CLOSED 2026-10-05 by D525's box re-round —
|
||||
D522,FIXED,The golden window's frame-900 stem is not settled gameplay on several levels —,FIXED 2026-10-05 (recipe-side re-base:
|
||||
D523,CLOSED,The golden recipe does not pin save state:,SUPERSEDED by D529 (2026-10-07) —
|
||||
D524,FIXED,The golden tooling was destructive and drift-prone:,FIXED 2026-10-05 (both pins idempotent —
|
||||
D525,FIXED,"The whole <level>/linux/ golden set was stale, not just on the six re-based levels —","FIXED 2026-10-05 (21-level box re-round, 63 frames, save pinned present; structural parity 21/21, Archives/Streets bands attributed to save state, not a renderer)"
|
||||
D526,CLOSED,P13 Dam-ending grate / edge-railing transparency is faithful N64 behaviour (port == 1964/GEPD); the per-triangle census probe is retained as a generic draw-sta…,"CLOSED — faithful, confirmed on 1964/GEPD (2026-10-07):"
|
||||
D527,OPEN,GE_PCDUMP written first:last (a colon where the dash belongs) silently dumps EVERY frame —,OPEN (harness documentation; a log-or-fail-closed fix is owed in the port layer)
|
||||
D528,OPEN,"GE_STARTMENU skips the EEPROM read, so front-end-only sessions never import the emulator save —",OPEN (harness documentation; the D514 imported-save test must run from a normal boot; a log-or-import fix is owed in the port layer)
|
||||
D529,FIXED,The golden gate depends on the save file's CONTENT —,FIXED 2026-10-07 (canonical save in-tree at tools_pc/golden/ge007.eep; verify.sh installs it like the ini pin; all 21 win sets re-captured under it —
|
||||
D530,?,The box (X220) linux golden re-round landed —,AMENDED BY D531 (2026-10-07) —
|
||||
D531,FIXED,capture_p7.sh's D529 adaptation was incomplete —,"FIXED 2026-10-07 (loop re-pins the canonical save per level + cd ""$ROOT""; fresh 21/21 box re-capture committed —"
|
||||
D532,FIXED,The three P12 U5 should-fixes applied —,FIXED 2026-10-07 (tooling-only:
|
||||
D450,FIXED,"Unplugging and replugging a controller was not picked up (user, GameSir-G7 Pro; 2026-09-29).","FIXED — port-only: the render thread's gfx_sdl_handle_events drains the same SDL queue as video.c's host pump but had no case for SDL_CONTROLLERDEVICEADDED/REMOVED, so it usually swallowed them and i…"
|
||||
|
+181
-4
@@ -788,6 +788,18 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121).
|
||||
| D518 | **Pad layout preset was one global value: setting another player's preset changed the main player's mapping too** — Port-only; D498 follow-up, maintainer report; full `## D518` entry at file tail | FIXED (live pass 2026-10-04 incl. split-screen 2P) |
|
||||
| D519 | **One PC options UI: the file-select "PC Options" entry opens the F10 overlay; the MENU_PC_OPTIONS screen is deleted** — Port-only (the one front.c entry call is kept); Bond-file rows + watch chooser re-keyed to file select; 4 probes retired, `GE_FILESELECT_OVERLAY` added; full `## D519` entry at the end of this file. | FIXED (headless-verified 2026-10-04; by-eye pass owed) |
|
||||
| D520 | **F10 overlay slider wedge, slider marker and dropdown arrow antialiased (they stepped in whole canvas pixels that grow with the window)** — Port-only; D504 follow-up, P4k investigation; full `## D520` entry at file tail | FIXED (headless before/after capture; by-eye owed) |
|
||||
| D521 | **A fixed-frame golden window that overlaps the intro flyby is platform-nondeterministic (cross-platform goldens); verify.sh's linux pixel-gate skip is driver-conditional** — Port-only (docs + verify.sh probe); D117 class, P7; full `## D521` entry at the end of this file | PARTIAL (rule recorded 2026-10-04; the two residual bands CLOSED 2026-10-05 by D525's box re-round — save state, not a renderer; cross-platform parity stays informational, the gate is per platform) |
|
||||
| D522 | **The golden window's frame-900 stem is not settled gameplay on several levels — the win golden gate is not green (5/21 REGRESSION honest sequential, 7/21 concurrent)** — Golden gate; D117 follow-up; full `## D522` entry at file tail | FIXED 2026-10-05 (recipe-side re-base: per-level windows settled on every level; win gate 21/21 PASS honest sequential; no tol limit raised) |
|
||||
| D523 | **The golden recipe does not pin save state: `verify.sh` pins the ini but never touches `data/ge007.eep`, and the goldens were captured with a save present** — Golden gate; D514/D522 follow-up; full `## D523` entry at file tail | SUPERSEDED by D529 (2026-10-07) — the frame depends on the save's *content*, not its presence (the presence claim was only ever measured on Archives); the gate now installs the canonical in-tree save `tools_pc/golden/ge007.eep` |
|
||||
| D524 | **The golden tooling was destructive and drift-prone: `verify.sh`'s per-level ini/save pin snapshotted the previous level's game-written file (a sweep overwrites the user's own `data/ge007.ini`), and `capture_p7.sh` hardcoded the pre-D522 windows while deleting the save it captures with** — Golden tooling (U5 review of `tools_pc/**`); D522/D523 follow-up; full `## D524` entry at file tail | FIXED 2026-10-05 (both pins idempotent — first call snapshots the user's files, every level re-pins from that snapshot; `capture_p7.sh` reads the recipe out of `verify.sh` and requires the save present) |
|
||||
| D525 | **The whole `<level>/linux/` golden set was stale, not just on the six re-based levels — re-rounding it closes D521's two residual render bands** — Golden gate (P7b, box); D521/D522/D523 follow-up; full `## D525` entry at file tail | FIXED 2026-10-05 (21-level box re-round, 63 frames, save pinned present; structural parity 21/21, Archives/Streets bands attributed to save state, not a renderer) |
|
||||
| D526 | **P13 Dam-ending grate / edge-railing transparency is faithful N64 behaviour (port == 1964/GEPD); the per-triangle census probe is retained as a generic draw-state diagnostic** — P13 Dam ending (B1 lead); full `## D526` entry at file tail | CLOSED — faithful, confirmed on 1964/GEPD (2026-10-07): the show-through is in both (port == N64), so no port bug, no fix (D306/D291 class); the per-triangle census probe (GE_D526/GE_D526BOX/GE_D526MAX) is retained as a generic diagnostic |
|
||||
| D527 | **`GE_PCDUMP` written `first:last` (a colon where the dash belongs) silently dumps EVERY frame** — harness trap (`port/src/video.c`); full `## D527` entry at file tail | OPEN (harness documentation; a log-or-fail-closed fix is owed in the port layer) |
|
||||
| D528 | **`GE_STARTMENU` skips the EEPROM read, so front-end-only sessions never import the emulator save** — harness trap; D514 follow-up; full `## D528` entry at file tail | OPEN (harness documentation; the D514 imported-save test must run from a normal boot; a log-or-import fix is owed in the port layer) |
|
||||
| D529 | **The golden gate depends on the save file's CONTENT — the D523 "presence, not which save" claim is refuted; the gate must pin a canonical save** — Golden gate; D523 follow-up (D525/D524); full `## D529` entry at file tail | FIXED 2026-10-07 (canonical save in-tree at `tools_pc/golden/ge007.eep`; `verify.sh` installs it like the ini pin; all 21 win sets re-captured under it — three consecutive clean 21/21 sweeps are the valid green record; the no-arg `verify.sh` path now exits 1; the box linux re-round under it landed as D530) |
|
||||
| D530 | **The box (X220) linux golden re-round landed — first cross-machine test of the four D117 flaky levels** — Golden gate (P7, box); D529 never-do 3/6 follow-up; full `## D530` entry at file tail | AMENDED BY D531 (2026-10-07) — the "canonical eep" provenance claim was wrong: the re-round ran under the box-LOCAL save (the `capture_p7.sh` per-level re-pin bug); the D531 re-capture under the true canonical eep supersedes this set |
|
||||
| D531 | **`capture_p7.sh`'s D529 adaptation was incomplete — the per-level re-pin restored the local save, so the 2026-10-05 box re-round ran under the box-local save; fixed + re-captured under the canonical eep** — Golden gate (P7, box); D529/D530 follow-up, P12 U5 review finding; full `## D531` entry at file tail | FIXED 2026-10-07 (loop re-pins the canonical save per level + `cd "$ROOT"`; fresh 21/21 box re-capture committed — 47/63 frames differ from the box-local-save set; pixel-gated box verify owed for a window with the box's WSLg GPU display active — today's session is on the software fallback, black read-backs) |
|
||||
| D532 | **The three P12 U5 should-fixes applied — the gate's ini pin now fails closed, the seed is hard-pinned (stray `GE_RSEED` warns), and `audiodebug.ps1`'s dead A/B switches are gone** — golden gate + tooling; D531/U5 follow-up; full `## D532` entry at file tail | FIXED 2026-10-07 (tooling-only: `pin_ini_640x480` fails closed like `pin_eep`; `GOLDEN_SEED` literal + warning, capture `eval` unaffected; `-AB`/`-Old`/`-OldMode` removed with a note) |
|
||||
| D407 | **Tanks cannot be boarded/exited on PC — the v0.4.0 use/reload split (D378/D393) removed the B-button tap the engine's tank handlers in `bondview2.c` consume (user report 2026-09-28, Runway/Streets)** — full `## D407` entry at file tail | PARTIAL (fix landed in v0.4.0, port-only): present `GE_CONT_B` on the use (E / pad A) rising edge only while `g_PlayerIsInTank == 1` or `g_BondCanEnterTank != 0`; E keeps its D378 no-reload-fallback semantics elsewhere, N64 layout unaffected. D407(b) same cycle: front PC Options page-edge highlight clamp + mouse-wheel / W-S paging (wheel queue consumed on the menu, D223); its wheel mapping shipped inverted and was fixed to match W/S (wheel up = step up). D407(c): board-animation lockout, menu-accept B gate in tank states, in-tank aim routed through the legacy velocity stick + `Input.TankAimScale` knob. RESOLVED 2026-09-28: all port-only (src/game zero-diff), 10 TANKDBG probes stripped, release binary verified clean, user live tank drive signed off (board + exit OK, aim feel good). |
|
||||
| D408 | **`Game.SkipIntro` skips the post-mission failure dossier: with it on, entering a level then aborting (watch Z+A) or dying (KIA) returns straight to the menus — no REPORT / "Mission status: KILLED IN ACTION / ABORTED" screen** (user report 2026-09-28; save/AllUnlocked ruled out) — full `## D408` entry at file tail | OPEN (cosmetic, not root-caused past the handoff site). v0.4.0 decision: SkipIntro stays EXPERIMENTAL / not recommended for regular users — F10 row relabelled "Skip intro (EXPERIMENTAL)". |
|
||||
| D450 | **Unplugging and replugging a controller was not picked up (user, GameSir-G7 Pro; 2026-09-29).** — full `## D450` entry at file tail | FIXED — port-only: the render thread's `gfx_sdl_handle_events` drains the same SDL queue as video.c's host pump but had no case for `SDL_CONTROLLERDEVICEADDED/REMOVED`, so it usually swallowed them and `inputRescanPads` never ran. Both pumps now post a request; the rescan runs at the top of `inputUpdate`, on the thread that reads the pads. |
|
||||
@@ -5998,7 +6010,7 @@ probe scripts left.
|
||||
prints `ALL CHECKS PASSED`, and `-level_09` / `-level_20` then segfault before
|
||||
frame 1 (`EXCEPTION: 0xc0000005`, faulting return address is an ASCII
|
||||
model-name string). The pre-migration working sidecar
|
||||
(`C:/Users/james/Source/Repos/007/data/pccg-ntsc-final/pccg.bin`, 3604378 B,
|
||||
(`<repos>/007/data/pccg-ntsc-final/pccg.bin`, 3604378 B,
|
||||
2421-B manifest) drops into this tree and `-level_09` runs crash-free.
|
||||
|
||||
**Isolation done (M-38).**
|
||||
@@ -12871,7 +12883,7 @@ Verified: build clean (`build-pc`, MSYS2 MINGW64/ninja); `tools_pc/verify.sh bun
|
||||
|
||||
## D317 — Crash when toggling Game.AllUnlocked back and forth in-game (user report, v0.3.0 playtest build, 2026-09-18) — no dump left behind.
|
||||
|
||||
**Reported:** "Toggling unlock all back and forth in game causes a crash." Reproduced by the user on the current-tip playtest exe (the one at `C:\Users\james\Desktop\ge007-v0.3.0-playtest`, includes D310/D311 fixes). **Repro detail (user, 2026-09-18):** level = **Runway**. **No crash dump or log was left in that folder** — hard exit, so Windows Event Viewer is the only system-side artifact to check.
|
||||
**Reported:** "Toggling unlock all back and forth in game causes a crash." Reproduced by the user on the current-tip playtest exe (the Desktop `ge007-v0.3.0-playtest` folder, includes D310/D311 fixes). **Repro detail (user, 2026-09-18):** level = **Runway**. **No crash dump or log was left in that folder** — hard exit, so Windows Event Viewer is the only system-side artifact to check.
|
||||
|
||||
**Closed as a symptom of D316, not a real crash.** Evidence:
|
||||
- No WER report exists for the playtest exe; every `ge007` AppCrash in Windows Error Reporting traces to this repo's own `build-pc` dev runs, none after 12:00 that day, while the playtest session was ~13:15 — a real crash would have logged one.
|
||||
@@ -15453,7 +15465,7 @@ I logged all of this as **D397** (`docs/dev/findings.md`, index CSV, and the D18
|
||||
|
||||
**Status (2026-09-28, per `scratch/d397_fs/HANDOFF-D397.md`) — OPEN, re-scoped; no fix landed.** An in-tree CI→I import-routing block in `gfx_pc.cpp` `import_texture` was tried and is **ineffective** (the D116 stale-tile-metadata hypothesis is REFUTED: D161 already routes `fmt==CI && palette==G_TT_NONE` to `import_texture_i8`; the GE_TEXI logs show `palfmt=0` on all 299 rows) — the block was removed 2026-09-28. Established: the data path is 100% clean (299 row strips upload byte-exact vs `scratch/d397_fs/gunbarrel.pgm`); the artifact is static; MSAA, mips, RAND_NOISE, 5-bit quant and texture-cache aliasing are ruled out. Leading hypotheses: **H1** — the file-select custom-CC LERP (`gDPSetCombineLERP(TEXEL0, PRIMITIVE, ENV_ALPHA, ...)`) uses ENV_ALPHA 0x14 as the mix factor; the port feeds it as `20/255 ≈ 0.078` (`G_CCMUX_ENV_ALPHA` input, `gfx_pc.cpp`), so a black texel renders ≈0.92×prim ≈ the measured 27/28/17 black-region census — the N64 RDP 5-bit coefficient scaling (check `rsp/graphics/gmain.s` and the PD port's CC engine for the same combine id) is the root-cause question; **H2** — the 6-of-9-row comb is a second, separate row-strip-geometry defect (non-integer quad y + NEAREST, or the 256-tri vertex-ring wrap between the two tris of a row); **H3** — part of the darkened look is authentic N64 (G_TC_FILT 4-bit intensity dither, unimplemented here). A `GE_D397SH` env-gated shader-formula probe (in `gfx_opengl.cpp`, ~30 lines) stays in-tree until the root cause lands, then is removed. Next steps per the handoff: Q1 correlate which of the 20 compiled shaders is the gun-barrel row-strip one, Q4 settle the LERP-factor scaling against gmain.s/PD, Q5 native 640×480 FBO capture to re-measure the comb period.
|
||||
|
||||
**Status (2026-09-27b, static read against the local `pd_port` checkout) — H1 REFUTED, H2 promoted to leading cause.** Cross-checked `G_CCMUX_ENV_ALPHA` handling against `C:\Users\james\Source\Repos\pd_port\port\fast3d\gfx_pc.cpp`: byte-identical formula (`tmp.r=tmp.g=tmp.b=rdp.env_color.a`, then `/255.0f` at the vertex-color pack site) — no special-cased coarser scaling in either port. There is no "5-bit RDP coefficient" quirk in the real color combiner; PRIM/ENV alpha are genuine 8-bit `gDPSetEnvColor` fields and the combiner's A/B/C/D math is full 8-bit on real hardware (the 5-bit-precision idea conflated the CC with an unrelated hardware unit). **H1 is very likely not the (or not the only) cause; the uniform darkening it predicts may simply be faithful/authored** — do not correct it without an N64/1964-GEPD reference frame.
|
||||
**Status (2026-09-27b, static read against the local `pd_port` checkout) — H1 REFUTED, H2 promoted to leading cause.** Cross-checked `G_CCMUX_ENV_ALPHA` handling against `<repos>\pd_port\port\fast3d\gfx_pc.cpp`: byte-identical formula (`tmp.r=tmp.g=tmp.b=rdp.env_color.a`, then `/255.0f` at the vertex-color pack site) — no special-cased coarser scaling in either port. There is no "5-bit RDP coefficient" quirk in the real color combiner; PRIM/ENV alpha are genuine 8-bit `gDPSetEnvColor` fields and the combiner's A/B/C/D math is full 8-bit on real hardware (the 5-bit-precision idea conflated the CC with an unrelated hardware unit). **H1 is very likely not the (or not the only) cause; the uniform darkening it predicts may simply be faithful/authored** — do not correct it without an N64/1964-GEPD reference frame.
|
||||
|
||||
Found a concrete geometric mechanism for **H2**, promoted to leading cause: `titleRenderFolderMenuBackgroundLines` (`src/game/title2.c:24`) emits `lry - uly == 3` (U10.2 units) per row — a **0.75-native-pixel-tall** rect, not 1.0 — via the universal N64 `((y+1)<<2)-1` idiom. That idiom is only exact on real hardware because the RDP's scan converter *floors* the fixed-point Y to an integer scanline before testing coverage. `gfx_draw_rectangle` (`gfx_pc.cpp:3443`) does not replicate that: it maps the U10.2 corners straight to continuous NDC floats and rasterizes with the GPU's ordinary continuous coverage rules. A sub-1-native-pixel-tall rect stacked 299 times (each offset exactly 1.0 native px from the last) does not reliably rasterize as "the one scanline the idiom intended" under continuous rasterization — which of the two neighbouring device rows a given source row's fractional edges land in drifts as the stack accumulates, worsened by any non-integer native→window scale (`gfx_adjust_viewport_or_scissor`'s `ratioY`). This is a rasterization property of the geometry, not stale state, so it naturally explains the first-render (non-re-entry) trigger that refuted D182's hypothesis for this instance. Full mechanism + tell for future occurrences: `docs/porting-notes.md` §D15. **Not yet done: a live capture to confirm the comb period tracks `ratioY`** (predicted: comb period should change if the window/render resolution changes, at fixed native resolution) — this is the concrete falsifiable test before attempting a fix. No code changed this pass (diagnosis only).
|
||||
|
||||
@@ -16524,7 +16536,7 @@ Whichever loop runs `SDL_PollEvent` first gets the event, and the render loop us
|
||||
|
||||
**Maintainer live-pad checklist.** (a) Fresh ini, no edits: Jinx 1.1 plays exactly as before (RT fire, LT/LB aim, A use, X reload, B gadget, Y next weapon, stick clicks crouch, Start pause; menus A/X accept, B/Y cancel). (b) F10 (Back) -> Input -> Controller...: Layout preset right -> Custom; seat/action rows appear. (c) Select Fire, press A: "Press button..." (the A press does not bind itself); press LB -> Primary: LB; fire with LB in a level, RT no longer fires. (d) Capture then tap B: cancelled, row unchanged, page does not close. Capture then hold B ~1 s: binds B. (e) Capture then tap Back: cancel; hold Back ~1 s: slot cleared. Esc and Delete work too. (f) Y on a row clears the slot without a modal. Start unbound -> still pauses (guard). (g) Reset to defaults restores Jinx 1.1 strings on all seats. (h) Controller-only: do (b)-(f) without touching the keyboard; never trapped. (i) 2P split-screen with two pads: set seat Pad 2 to a different Fire; confirm P1 and P2 differ; Pad 2 Y/B in menus still accept/cancel. With keyboard/mouse as P1 (one pad, MPMode Auto) the single pad uses the seat 0 table. (j) Unplug/replug a pad mid-match: bindings stay with the seat. (k) PrevWeapon (unbound by default): bind it and confirm it steps weapons backwards (untested live; reuses the wheel-back A+Z idiom). (l) Front-end PC Options -> Input -> Controller: same page; A starts capture, hold Back clears. (m) Quit and relaunch: the ini keeps `PadPreset` and the `Input.Pad*.` strings.
|
||||
|
||||
**Credit.** The two-names-per-action SDL string format, the menu lockout guard idea and release-before-capture arming follow outside PR #109 (italoarruda); the commits carry `Co-authored-by: italoarruda`.
|
||||
**Credit.** The two-names-per-action SDL string format, the menu lockout guard idea and release-before-capture arming follow outside PR #109 (italoarruda); the commits carry a `Co-authored-by: italoarruda` trailer.
|
||||
|
||||
**Confidence.** High: preset 0 byte-equivalence (exhaustive over the mapping function), build, boot/level/overlay smoke, page render. Medium: pad-driven capture timing and the front-end page behaviour (no physical pad here). Low: PrevWeapon feel.
|
||||
|
||||
@@ -17114,3 +17126,168 @@ keep: the next `./build-pc.sh` run reconfigures in place and picks up x86_64.
|
||||
**Fix (`port/src/optionsoverlay.c`).** `drawWedge`: the solid body as runs of equal whole height plus one coverage-alpha top pixel per 1-px column; the marker and the dropdown arrow via `drawTriDownAA` (per-pixel area coverage from 4 sub-rows). Render state is set once per shape (`aaBegin`) and each piece is 2 commands (`aaPiece`, pieces under alpha 6 skipped), so the display-list size stays about where it was (D516 overflow history; `OV_BUF_CMDS` 16384). Applies in every Display mode (maintainer: the overlay is port UI, not part of the N64 picture).
|
||||
|
||||
**Verified.** Build rc=0, no warnings; `GE_OPTIONSOVERLAY=1 GE_OPTIONSOVERLAY_SECTION=__HdrAudio GE_PCDUMP=300-300` before/after: the ramps go from ~7 visible steps to a smooth ramp, markers/arrows softened; no DL overflow logged. **Owed:** maintainer by-eye at their window size.
|
||||
|
||||
|
||||
## D521: A fixed-frame golden window that overlaps the intro flyby is platform-nondeterministic (P7, cross-platform goldens)
|
||||
|
||||
**Problem (P7, 2026-10-04, Linux golden baselines).** The golden recipe was run verbatim on a real-GL Linux box (Mesa 23.0.3 / Intel HD 3000, X, 640x480 ini pin, `GE_INPUTSCRIPT="20:START"`, `GE_PCDUMP="900-1500:300"`, `GE_QUITFRAME=1502`) for all 21 levels and compared against `tools_pc/golden/<level>/win/`. At the settled stems (1200/1500; Cuba 600/900) the cross-platform delta is 1.142-6.958% of pixels over tol 2 -- worst non-outlier dam 1500 6.958%, worst grid-cell dmean 14.315 (surface1 1200), phash <= 3 -- but Dam's frame 900 measures 92.863% over tol 2 with phash 83, a completely different scene. The same-machine spread is what makes that number meaningful: repeat Linux runs of the same recipe differ by 0.115% (1200) and 0.219% (1500) at those stems (cap_1 vs cap_3, exact tol 2) but by 72.460% at 900, i.e. the 900 disagreement is the flyby still moving, not a renderer.
|
||||
|
||||
**Cause (D117 class, no new nondeterminism).** The intro flyby is wall-clock paced, and the capture harness steps *sim* frames, not wall-clock frames: `GE_PCDUMP` and `GE_QUITFRAME` both key off `frames` (`port/src/video.c:1406`, `++frames` in `videoEndFrame()`), which advances once per `portRenderGfxTask()` (`port/src/libultra.c:1256`), i.e. once per retrace actually consumed by `__scMain`. Retrace messages are dropped at the posting site when the game's queue is nearly full (`port/src/libultra.c:753`), so a box that cannot hold 60 fps stretches wall time *without* advancing `frames` (per-frame render times in cap_dam.log: frame 900 13009 us, 1200 15121 us, 1500 11808 us). On this box the flyby was still running at frame 900 -- it settles between frame ~830 and ~1130 run to run -- while the Windows golden run had it settled before 900. The scripted START press is not the difference: the pulse's six `GE_INPUTLOG` lines precede "frame 5 rendered" on both platforms, and `GE_INPUTSCRIPT_MS=1` variants (150/300/600 ms) change nothing.
|
||||
|
||||
**Rule (this is a documentation finding, not a code fix).** A cross-platform golden comparison is only meaningful at stems that are settled gameplay on *every* platform in the set. Either move the window past the slowest platform's flyby settle point, or report in-flyby stems as a scene offset and never gate on them. `GE_DETERM=1` is the right tool for Linux-vs-Linux regression runs only: it makes retrace generation call-sequenced (det_a vs det_b, exact tol 2: 4.654/5.562/5.331% at 900/1200/1500) but changes the frame -> sim mapping, so its 14.6-16.2% against the win/ goldens (det_a vs dam/win: 15.788/14.594/16.171%) is expected and must never be used for cross-platform comparison.
|
||||
|
||||
**Port-layer change (same sweep).** `tools_pc/verify.sh`'s linux pixcount/framediff skip (N6 / M-48, "GE_PCDUMP reads black") is a property of the GL *driver*, not of the platform. It is now driver-conditional: a `glxinfo -B` renderer probe sets `LINUX_SOFTWARE_GL`, and only llvmpipe/softpipe/swrast/dynrecomp skip the pixel gate; a real driver (Mesa iGPU/dGPU, NVIDIA) runs the same gate as Windows. `glxinfo` missing or unrecognised keeps the old conservative skip, so an unknown box behaves exactly as before. **Known limitation:** the probe whitelists by *blacklist* (`llvmpipe|softpipe|swrast|dynrecomp`), so a future software driver outside that list would enable the pixel gate and false-FAIL; the probe is not rewritten here.
|
||||
|
||||
**Verified (P7 sweep, 21 levels, one pass).** Structural framediff (cell means / coverage / phash) linux-vs-win: rc=0 on 19/21 levels; rc=1 on Dam (frame 900, the flyby) and Streets (frame 1200). Exact `--tol 2` over-tol2 %: 1.142-6.618% on the 17 levels with no outlier stem (bunker2 1.142-1.144%, facility 1.396-1.842%, surface1 1.494-2.779%, bunker1 1.710-2.341%, train 1.573-2.160%, control 2.125-2.688%; highest non-outlier surface2 5.592-6.170%, jungle 5.858-6.618%). Outliers, each classified: **Archives** 19.956-24.554% at all three stems, but the 16x12 grid map is confined to grid rows 0-2 (cell means up to 50.8; row 3 is 2.5-4.6, rows 4-11 <= 3.1) and the per-pixel histogram is a constant ~18-22 delta (counts at d=18,19,20,21,22) -- systematic, a candidate real rendering difference (sky/fog band), needs a same-sim-state capture pair before it is called a renderer bug. **Cuba** 10.705-26.350% with 16x12 cell means <= 11.1 and per-pixel deltas clustered at d 3-6 across the whole frame -- the dither/quantization noise floor, structural-clean. **Jungle** 5.858-6.618% (worst cell dmean 14.8-26.7). **Streets** 1200: 9.564% with a diagonal band of 16x12 cell means 16.0-148.4 across rows 0-4, cols 0-6 (a region delta, not noise); Streets 900/1500 are clean (4.738/5.040%) and show a separate residue in the lower-right cells (row 9 col 10: 20.9 at 900, 33.0 at 1500). **Dam** 900: 92.863% over tol 2, phash 83 -- the flyby offset.
|
||||
|
||||
**Open (docs/ROADMAP.md §4).** The Archives top-band and the Streets-1200 band, as the two candidates for a genuine cross-platform rendering difference; both need a same-sim-state capture pair (identical scripted input and a settled camera on both boxes) before either can be called a renderer bug.
|
||||
## D522: The golden window's frame-900 stem is not settled gameplay on several levels — the win golden gate is not green (golden gate; D117 follow-up)
|
||||
|
||||
**FIXED 2026-10-05 — recipe-side re-base only (no game-code change, no tol limit raised).** The measurements below are kept as the record of why. `tools_pc/verify.sh`'s `golden_dump_for` now carries per-level windows: `900-1500:300` on the 14 levels where 900 is settled, `1000-1400:200` on Surface 2 / Streets / Depot / Cradle / Frigate, `1500-1700:100` on Dam. Chosen by measuring run-to-run agreement: at 900 those levels fail the per-pixel limit and Dam's 900 is still flyby; at the new stems three independent runs agree within tol 2 (frigate + the four: 1000/1200/1400 all 0.000% max-pair; Dam's 1200 agreed on two runs then diverged 5.761% on a third, so it moved to 1500-1700 — 1500/1700 0.000%, 1600 keeps ~40 moving pixels at 0.013%, inside the 1% limit). Full 21-level sweep after the re-base: **21/21 PASS** (`scratch/verify-rebase2.log`).
|
||||
|
||||
**Problem (2026-10-05 golden-gate pass, this tree).** A full 21-level sweep run with the recipe exactly as `tools_pc/golden/README.md` states it does not pass against the tracked `tools_pc/golden/<level>/win/` set. Honest sequential pass (one run at a time, `scratch/sweep-par.sh 1`, live `data/ge007.eep` present): **5/21 REGRESSION** — dam 6.542 % @900 (worst_cell 12.11), surface2 3.752 % @900 (limit 3.0), streets 1.001 % @1200, depot 1.267 % @900, cradle 1.754 % @900, all against a 1.0 % per-pixel limit; 16/21 PASS. The concurrent pass (`JOBS=7`, 21 levels in 1:56 wall) failed **7/21**: the same five plus runway 1.668 % @900 and frigate 4.484 % @900, both of which pass cleanly when run alone (worst_cell 0.616 / 0.109). Both numbers are recorded, not averaged; the difference is pacing (see below).
|
||||
|
||||
**Cause (D117 wall-clock pacing, not a render bug).** `GE_INPUTSCRIPT="20:START"` skips the intro flyby, but the flyby's own length is wall-clock paced: the scripted pad advances in real time, so which camera beat frame 900 lands on moves with the run's pacing. dam's 900 stem measured 1.598 / 2.689 / 3.424 / 6.542 / 7.240 % across five runs of the same recipe — the spread is the flyby beat, not noise. The unstable stem itself moves between passes: streets failed at 1500 in the concurrent pass and at 1200 in the sequential one. `tools_pc/golden/README.md`'s claim that "frames 900/1200/1500 are settled gameplay on every level" is contradicted.
|
||||
|
||||
**Also measured (D117 follow-up not closed).** `GE_DETERM=1` does not make the window reproducible: repeats differ 4.654 / 5.562 / 5.331 % with `GE_DETERM=1` against 0.115 / 0.219 % plain at the same stems — the switch makes the spread worse, not deterministic.
|
||||
|
||||
**Never do:** raise the tol limits to fit. That hides exactly the D117 class this gate exists to catch.
|
||||
|
||||
**Fix owed (recipe-side only; no game-code change):** either (a) move the capture window to stems settled on every level (1200–1800:300 is the measured candidate) and re-capture the 63 `win/` PNGs plus the box's linux set, or (b) keep the set and state the gate honestly (structural green + per-pixel marginal at 900) in `golden/README.md`, the ROADMAP row and the known-issues table. Driver: `scratch/sweep-par.sh` (gitignored; mirrors `verify.sh`'s ini pin, `GE_*` recipe, framediff flags and per-level limits, one cwd per level so runs can overlap — parallel verdicts are diagnosis only, the honest numbers come from the `JOBS=1` pass).
|
||||
|
||||
## D523: The golden recipe does not pin save state — `verify.sh` pins the ini but never touches `data/ge007.eep` (golden gate; D514/D522 follow-up) — **SUPERSEDED by D529 (2026-10-07): the frame depends on the save's CONTENT, not its presence; the gate now installs the canonical in-tree save**
|
||||
|
||||
**FIXED 2026-10-05 — `verify.sh` now pins the save file** (back up + require `data/ge007.eep`, mirroring the ini pin; it exits 2 with a message when a clone has none, rather than silently measuring a different scene), and `tools_pc/golden/README.md` states the pin. The measurements below are the record of why the gap mattered.
|
||||
|
||||
**Problem.** The goldens were captured with a save file present, and nothing in the recipe records that. `tools_pc/verify.sh` backs up and pins `data/ge007.ini` (`pin_ini_640x480` / `restore_ini` / the EXIT trap) but has no analogue for `data/ge007.eep`, and `tools_pc/golden/README.md`'s recipe list never mentions it. The game's save file changes the rendered scene, so the recipe reproduces the goldens only on a machine that happens to hold a matching save — and a fresh clone of this repo ships no `.eep` at all.
|
||||
|
||||
**Measured on this tree (2026-10-05, two honest sequential 21-level passes, same build, same ini pin).** With the live `data/ge007.eep` present: 5/21 REGRESSION. With no `.eep` at all: **19/21 REGRESSION** — Archives 21.557 % @900 (worst_cell 31.64), Silo 40.9 and Dam 116.6 worst_cell (framediff-level misses, not even per-pixel-comparable), and every remaining level 1.2–5.5 % against a 1.0 % limit. Only Bunker 2 (0.001) and Cuba (structural tier only) survive. So the save state, not the renderer, is what separates a passing gate run from a failing one.
|
||||
|
||||
**Box-side corroboration (P7, D521).** Archives cell means 0.0 → 27–31 from `.eep` presence alone, and dam's 900 phash 3 → 83: same cause, opposite direction, because the box's save differs from the win capture's. The box changed no golden and no `verify.sh` for it — correct, since the fix belongs to the recipe, not to either artifact.
|
||||
|
||||
**Fix owed (port tooling + docs only).** Pin the save file the way the ini is pinned: back up `data/ge007.eep`, install the capture-time save (or explicitly none) for golden runs, restore on exit, and state in `golden/README.md` which save state the set carries. `data/` already holds candidate capture-time saves (`ge007 - Copy.eep`, `ge007 copy.eep`, `d295_repo_eep_prior.bak`), all with different sha256 from the live one; which one the set was captured with is not recorded and has to be identified before pinning.
|
||||
|
||||
**Measured refinement (2026-10-05, same build, Archives as the discriminating level).** The variable that matters is **save-file presence, not which save**: Archives measures 0.175625 worst_cell with the live `ge007.eep`, with `ge007 - Copy.eep`, with `ge007 copy.eep`, and with `d295_repo_eep_prior.bak` (four different sha256s, all identical verdicts), and 21.557 % / worst_cell 31.64 with no `.eep` at all. So pinning "a save present" reproduces the set on Archives from any of these; pinning nothing does not. Dam cannot discriminate — its 900 stem spread (D522) dominates the save delta (measured 3.03 / 12.11 / 17.37 / 116.6 / 132.96 worst_cell across runs of the same recipe). Until that is done, no sweep verdict from a fresh clone is comparable to the committed goldens.
|
||||
|
||||
## D524: The golden tooling was destructive and drift-prone — `verify.sh`'s per-level ini/save pin snapshotted the previous level's game-written file, and `capture_p7.sh` hardcoded the pre-D522 windows while deleting the save it captures with (golden tooling; D522/D523 follow-up)
|
||||
|
||||
**FIXED 2026-10-05 — tooling only (no game-code change, no golden touched by this finding).** Two sites, both found in the U5 code review of `tools_pc/**` (paths / quoting / subprocess / destructive behaviour) that the v0.4.1 release audit owed.
|
||||
|
||||
**(1) `verify.sh` sweep overwrote the maintainer's own settings.** `pin_ini_640x480` and `pin_eep` are called once per level inside the sweep loop, and the game rewrites `data/ge007.ini` (and writes `data/ge007.eep`) after every run. So from level 2 onward the "backup" is the *previous level's game-written* ini, and the EXIT trap restores that: after one 21-level sweep the user's personal settings (`FovScale`, `DrawDistance`, MSAA, sound…) are replaced on disk by compiled-in defaults, with no way back, and the save restore hands back the second-to-last level's written save rather than the pre-sweep one. It also leaked one `mktemp -d` directory per level. Fix: both pins are idempotent — the FIRST call snapshots the user's ini/save, later calls only re-pin — and `pin_eep` re-installs that snapshot before every level, so each run starts from the same save state (D523 says presence, not which save, is what the frame depends on; the runs write the save, so re-installing is what makes the sweep reproducible).
|
||||
|
||||
**(2) `tools_pc/capture_p7.sh` carried the pre-D522 recipe and cleared the save.** It hardcoded `GE_PCDUMP="900-1500:300"` / `GE_QUITFRAME=1502` (stale on the six levels D522 re-based) and ran `rm -f data/ge007.eep` before every run — the D523 gap, and the reason the 2026-10-04 linux set had to be re-captured at all. It now reads the windows, scripts and seed out of `tools_pc/verify.sh` (`golden_dump_for` / `golden_script_for` / `GOLDEN_SEED`) so the capture tool and the gate cannot drift, computes `GE_QUITFRAME = last requested frame + 2`, and refuses to run without `data/ge007.eep` present.
|
||||
|
||||
**Never do:** keep the per-level backup semantics. A sweep that leaves the user's ini rewritten is a silent data-loss bug in a tool the maintainer runs against their own `data/` directory; "restore what the last run left" is never the intent.
|
||||
|
||||
## D525: The whole `<level>/linux/` golden set was stale, not only on the six re-based levels — re-rounding it closes D521's two residual render bands (golden gate; D521/D522/D523 follow-up)
|
||||
|
||||
**FIXED 2026-10-05 — recipe/asset side only (box re-round + merge; no game-code change, no tol limit raised).** The 13-frame order owed to the box was the wrong size. D523's evidence says save-file *presence* moves ~every level (Archives 21.557 % with no `.eep`, 0.175625 worst_cell with any of four saves), and P7's 2026-10-04 round ran with `data/ge007.eep` cleared while the win set carries a save present — so the entire 21-level linux set was stale, not just the six levels D522 moved. The box re-captured all 21 levels (63 frames, 21/21 rc=0, frames=3, 25-29 s each, ~10 min wall) at the windows `verify.sh` now carries, with the save pinned present, on the same real-GL box (Mesa 23.0.3 / Intel HD 3000, X on vt2, `DISPLAY=:0`, 640x480 ini pin, `GE_RSEED` pinned, per-level `GE_INPUTSCRIPT`). The base branch already carried 50 linux PNGs (the five re-based levels kept only their 1200 stem, Dam had none); after the re-round the set is 63, one frame per recipe stem on every level.
|
||||
|
||||
**Cross-platform measurement after the re-round (framediff linux-vs-win at the recipe stems, tol 2).** Structural tier: **21/21 PASS** — worst 16x12 cell mean 4.43 (streets), phash <= 6 on 20 levels, the one structural signal at the limit being **cradle phash 40** (threshold 40; cell means 1.17, so it is a perceptual-hash tie, not a region delta). Exact tier, % of pixels over tol 2: **0.348-3.983 %** on the 20 non-Cuba levels (facility 0.348-0.477, surface2 0.408-0.488, surface1 0.835-0.931, train 0.782-0.825, bunker1 0.951-1.063, statue 0.605-1.105, bunker2 1.142-1.143, depot 1.098-1.155, control 1.298-1.332, runway 1.340-1.396, caverns 1.462-1.473, silo 2.352-2.363, egypt 2.874-2.951, dam 2.964-3.443, frigate 1.282-3.181, cradle 3.063-3.337, jungle 3.127-3.851, aztec 3.704-3.830, archives 3.590-3.859, streets 3.616-3.983); Cuba 23.657-36.338 % is the recipe's structural-tier-only level (cutscene animation timing, `golden_tolpct_for cuba` = empty). The same spread measured 1.142-6.958 % on the stale set, so the re-round roughly halves the worst cross-platform deviation.
|
||||
|
||||
**D521's two open items are closed by this measurement, and neither is a renderer bug.** **Archives** measured 19.956-24.554 % with cell means up to 50.8 confined to grid rows 0-2 on the stale pair; it now measures 3.590-3.859 % with worst cell mean 2.31 and phash 1 — the band was the save-state difference D523 names, not a sky/fog rendering difference. **Streets** frame 1200 measured 9.564 % with a diagonal band of cell means 16.0-148.4; it now measures 3.616-3.983 % with worst cell mean 4.43 and phash 0. **Dam** frame 900's 92.863 % / phash 83 is the flyby offset (D521/D522) and is not in the set any more: Dam sits at 1500-1700, where the cross-platform delta is 2.964-3.443 %.
|
||||
|
||||
**Box-side caveat (this is why the box's own sweep is not a pixel gate).** `verify.sh`'s D521 renderer probe fails closed on this box: `glxinfo -B` exits 255 with "Error: unable to open display :0" from a non-login ssh shell even though the game's SDL GL context and `glReadPixels` readback work (the captured PNGs are 128-355 KB, not black). `LINUX_SOFTWARE_GL` therefore stays 1 and the box's sweep reports "pixcount/framediff skipped, crash-detect only". The cross-platform numbers above are computed on Windows against the merged linux PNGs, which is the only honest place to compute them from this box. **Never claim the linux pixel gate ran on this box** — the claim that holds is that the linux captures are structurally clean against the win set and that the linux *crash* gate ran on the box.
|
||||
|
||||
**Never do:** call the cross-platform spread a parity gate. The per-pixel limit (1 % / 3 % on jungle+surface2) is calibrated per platform against that platform's own run-to-run noise; 0.348-3.983 % across platforms is informational, and the gate each platform ships is its own captures against its own goldens.
|
||||
|
||||
## D526: P13 Dam-ending grate / edge-railing transparency is faithful N64 behaviour (port == 1964/GEPD); the per-triangle census probe is retained as a generic draw-state diagnostic
|
||||
|
||||
**CLOSED as faithful 2026-10-07 (no port bug; no fix).** The P13 "Dam-ending grate show-through" (2nd POSENDS camera: the area under the grate Bond stands on shows through — the 2D edge-railing/grate texture's between-anchors region) was triaged as a suspected B1 port bug (the grate quad's texture stage taking an alpha/blend path it shouldn't — D195/D268 class). To bucket it, a per-triangle draw-state census probe was built (this D526) and smoke-tested. The 1964/GEPD reference of the same 2nd-POSENDS shot then showed **the port and the N64 look the same** — the show-through is in *both*. So it is the original game's 2D grate/railing texture rendering, reproduced faithfully: a known issue that **closes in the D306/D291 class** (a "bug" that 1964 shows is intended behaviour). There is nothing to fix in `port/fast3d/`.
|
||||
|
||||
**Probe (retained as a generic tool):** `d526_note_emit()` in `port/fast3d/gfx_pc.cpp`, folded into the D474 `tri_dbg()` gate (zero player cost when off). Env: `GE_D526="lo-hi"` (sim-frame window), `GE_D526BOX="x0 y0 x1 y1"` (NDC region, y-up; default whole screen), `GE_D526MAX=N` (cumulative per-triangle line cap, 400; the per-frame `D526F:` signature aggregate is uncapped). Emits to stderr: per-triangle NDC bbox, z/w, `gm`, `oml`, `omh`, combine mode, first-tile tmem/fmt/siz, prim + vertex alpha, use_alpha/modulate/invisible/2-cycle, plus a per-frame `D526F:` signature map. It is the only per-triangle *draw-state* census (D474/D75D/ZF/D303 are specialized) and is the right tool for the alpha/texture bug class (D195/D266/D268/D273).
|
||||
|
||||
**Static audit (no code change):** `palette_to_rgba32` (`gfx_pc.cpp:1044`) matches the game's ground truth — `texChannelsToPixels` (`src/game/image.c:1836`) packs RGBA5551 as `R<<11|G<<6|B<<1|A` (alpha = bit 0) and IA16 as intensity-hi/alpha-lo (the D228-fixed decode), so a global palette bit-flip is ruled out; blend state is stock and D268-verified. Consistent with the faithful result (the port's alpha/texture path is correct).
|
||||
|
||||
**Never do:** ship a `port/fast3d/` "fix" for the Dam-ending grate show-through — 1964/GEPD confirms it is faithful N64 behaviour (D306/D291 class). Do not drop the census probe without a finding that uses it; it is a maintained diagnostic.
|
||||
|
||||
## D527: `GE_PCDUMP` written `first:last` (a colon where the dash belongs) silently dumps EVERY frame (harness trap)
|
||||
|
||||
**OPEN (harness documentation; no code change yet).** `port/src/video.c:1357` parses `GE_PCDUMP` with `sscanf("%d-%d:%d")`. If the lo/hi pair is written `first:last` (a colon where the dash belongs), the `%d-%d` part fails to match, the fallback sets `hi=0x7fffffff` and `step=1`, and the dump writes **every** frame from `first` onward at ~921 KB each — a first launch in the 2026-10-05 session ate ~1.5 GB before it was noticed (the run went to ~1500 fps until the window was closed). The failure mode is silent: no error line, the dump just runs.
|
||||
|
||||
Fix owed (port-layer only): log a NOTE when the `sscanf` does not consume all three fields (e.g. "GE_PCDUMP 'x:y' is not 'first-last:step' — dumping every frame"), or fail closed (ignore the value) — either way the operator must see which window is active.
|
||||
|
||||
**Never do:** write `GE_PCDUMP` as `lo:hi` — use `first-last:step` (a dash between lo and hi, a colon before the step).
|
||||
|
||||
## D528: `GE_STARTMENU` skips the EEPROM read, so front-end-only sessions never import the emulator save (harness trap)
|
||||
|
||||
**OPEN (harness documentation).** A `GE_STARTMENU` session (front end up with no level load) never reaches the EEPROM read — no `eeprom:` log line; the front end reports `watchsettings: no valid Bond save in any folder` even with `data/ge007.eep` present. Consequence: the D514 imported-save test **cannot** be driven from a `GE_STARTMENU` boot; it must run from a **normal boot**. There it reproduces exactly: `eep: imported emulator save (6 regions converted, backup data\\ge007.eep.emulator.bak)` and `data/ge007.eep` md5 `3ca7cf84…` = the in-game-proven converted save (2026-10-05 session).
|
||||
|
||||
Decision owed: document it (a NOTE log line when `GE_STARTMENU` is active: "EEPROM import skipped") or make the front end perform the import — port-layer only; the N64 front end has no EEPROM at all, so this is pure port scaffolding.
|
||||
|
||||
**Never do:** drive the D514 imported-save test from a `GE_STARTMENU` boot — it must run from a normal boot, or the EEPROM import is skipped and the test cannot see the converted save.
|
||||
|
||||
---
|
||||
|
||||
## D529: The golden gate depends on the save file's CONTENT — the D523 "presence, not which save" claim is refuted; the gate must pin a canonical save (golden gate; refines D523; follow-up to D525/D524)
|
||||
|
||||
**2026-10-07 (pre-push session).** The D523 pin installed *whichever* local save existed ("presence, not which save — Archives measures worst_cell 0.175625 on each of the four candidate saves and 21.557% with none"). That claim had only ever been measured **on Archives**. The 2026-10-07 sweep refutes it: the local `data/ge007.eep` had been rewritten by the live Dam-ending playtest sessions (md5 `a41d7ab…`, mtime 2026-10-05 07:27), and the honest sequential sweep under it produced **6/21 REGRESSION** on a *byte-identical binary* (the 2026-10-04 run had been 21/21).
|
||||
|
||||
**The A/B (facility, window 900-1500:300):**
|
||||
|
||||
| save (2 KB each) | facility worst_cell |
|
||||
|---|---|
|
||||
| `ge007 copy.eep` (2026-09-02, the pre-live-sessions save) | **0.0–0.25 — PASS** |
|
||||
| `ge007 - Copy.eep` (2026-09-16) | 0.0–0.25 — PASS |
|
||||
| `build-pc/ge007.eep` (2026-09-28) | 0.25 (f2) / 0.25 (f3) — PASS |
|
||||
| `../007/data/ge007.eep` (2026-09-15) | 0.25–0.5 — PASS |
|
||||
| `gamefaqs_dexdrive_2001.eep` (external) | **177.47 (f2) / 177.22 (f3) — REGRESSION** |
|
||||
| `data/ge007.eep` local (a41d7ab, the 2026-10-05 sessions) | **177.47 (f2) / 177.22 (f3) — REGRESSION** |
|
||||
|
||||
Two distinct classes in the 6-failure sweep, proven apart by the A/B:
|
||||
1. **Save-content dependent (facility, streets, jungle, cradle):** same failure signature (177.2–177.5 at the 1200/1500 stems — a *different scene* in-window, not a jitter class) only on the two saves with that content (the 2001 dexdrive save and the 10-05 local save share it; 2001-vintage saves apparently hold state that routes facility's intro differently). The other four candidates pass. **This is what D529 fixes: the gate installs ONE canonical save, so "which save" can never vary.**
|
||||
2. **D117 wall-clock flyby (dam@1500 4.9%, frigate@1000 3.2–8.3%, streets@1000 2.5–25.7%):** fails *identically on every save* — the window's first stem is inside the real-time-paced intro flyby, so the content at a given sim frame varies with machine load (D117, long-known, previously masked because the Oct-4 goldens happened to be captured the same way).
|
||||
|
||||
**Resolution (FIXED 2026-10-07, same session):**
|
||||
- **Canonical save in-tree: `tools_pc/golden/ge007.eep`** (2 KB, = `ge007 copy.eep`, the stable pre-live-sessions save the Oct-4 gate was green on). In-tree = a fresh clone or CI can run the gate with zero external state, and the D523 "fresh clone has no save → exit 2" failure branch is gone for good.
|
||||
- **`verify.sh` installs it like the ini pin** (snapshot the local `data/ge007.eep` if any → install the canonical → restore-or-remove on exit). The local playtest save is never the gate's input.
|
||||
- **All 21 win golden sets re-captured under the canonical save** (`scratch/golden-recapture-win-v050.sh`; 21/21 rc=0). The first four flaky levels (dam/frigate/streets/jungle — the D117 flyby stems) were re-captured again **clean** (no concurrent processes) after the first interleaved capture.
|
||||
- **Green protocol held (final, clean):** the first "double-green" pair ran `verify.sh` **with no arguments — which at the time only printed the usage and exited 0** (a no-op, not a sweep — that pair does not count) and was also interleaved with the in-flight re-capture. The valid record is **three consecutive clean full sweeps (`verify.sh sweep`) all 21/21 PASS** after the clean 4-level re-capture (`scratch/verify-v050-flaky3-run{1,2,3}.log`). **`verify.sh` with no arguments must never be cited as a green run.** CODE-PATCHED the same day (independent-reviewer follow-up): the no-arg path now prints the usage and **exits 1** with an explicit "never cite a no-arg run as a gate result" error — the failure class is closed in code, not just doc.
|
||||
- **Linux side:** the box set was re-rounded 2026-10-05 under a *cleared* eep (D525) — a cleared eep is a *specific content state* (empty save), not the canonical one. The box re-round under `tools_pc/golden/ge007.eep` is owed in parallel on the release branch (off the critical path; the box pixel probe fails closed there anyway — D244 — so it is a second-surface check, not a gate).
|
||||
|
||||
**Why this is not a renderer drift:** the binary is byte-identical to the 2026-10-04 21/21 run; the only variable that changed is `data/ge007.eep`, and the A/B is save-keyed (same binary, four passing saves, one failing save). No renderer code changed.
|
||||
|
||||
**Never do:** (1) run the golden gate against a local playtest save — it is exactly this class of drift; always the in-tree canonical eep. (2) claim "the frame depends on save *presence*" again — it depends on *content*; the D523 claim survives only as the (superseded) measurement on Archives. (3) treat the linux 63-frame set as valid under the canonical eep before the box re-round lands — it is the D525 cleared-eep round, and **no linux number may be cited (e.g. in the README pass) until that re-round lands**. (4) cite `verify.sh` with **no arguments** as a green run — a sweep is `verify.sh sweep` (the no-arg path now exits 1, closing the trap in code). (5) run a re-capture concurrently with a sweep (contention moves the D117 flyby stems). (6) treat **same-session** sweeps as proof the four D117 flaky levels (dam/frigate/streets/jungle) are stable across wall-clock: the first-stem content is time-dependent and the pin was fixed to "now" — the cross-machine test is the box re-round; **if those four go red there, the fix is to exclude or widen the first-stem cell for those levels, NOT to re-capture again** (an independent reviewer's 2026-10-07 verification flagged this; same-session worst_cell swings were streets 8.38→4.41, jungle 1.42→3.87). (7) trust a `capture_p7.sh` round's provenance claim without checking WHICH save state the loop actually installed — the D524-era per-level re-pin restored the local save and silently overwrote D529's pre-loop canonical install (D531); the linux set is only "canonical" if the loop line says `cp "$CANON_EEP"`.
|
||||
|
||||
## D531: `capture_p7.sh`'s D529 adaptation was incomplete — the per-level re-pin restored the local save, so the 2026-10-05 box re-round ran under the box-local save (not the canonical one); fixed + re-captured (golden gate; D529/D530 follow-up; P12 U5 review finding)
|
||||
|
||||
**Blocker found in the 2026-10-07 P12 U5 review (local session).** `tools_pc/capture_p7.sh`'s per-level loop had `cp "$EEP_ORIG" "$EEP"` (introduced by D524 to make the tool non-destructive): it restored the pre-capture **local** save — or a 0-byte eep when `data/ge007.eep` did not exist — before every level. D529's adaptation (`8fbf8aa0`) installed the canonical save (`cp "$CANON_EEP" "$EEP"`) **once, before the loop** and added the canonical-missing guard, but left the D524-era re-pin line in place — so from level 1 the canonical install was silently overwritten and every capture ran under the local save state. The header comment ("the pinned save, restored before every level") asserted what the code did not do.
|
||||
|
||||
**Impact — D530's provenance claim is wrong:** the 2026-10-05 box re-round (`~/p7-reround.log`, "P7 re-round DONE") ran under the box-local save (`sha256 d9f306…`, 2 KB — distinct from the in-tree canonical `65247b…`), not the canonical eep. D530's / the golden README's / the commit message's "63 PNGs under the canonical eep" did not hold, and D530's first-stem table (measured in that re-round's report against the old D525 goldens — its numbers do check out against the report) is not canonical-save evidence. **The win set is unaffected** — `verify.sh`'s `pin_eep` re-installs the canonical save on every call (that code was right); the bug was capture-side only.
|
||||
|
||||
**Fix (this batch, tooling only):** the loop now runs `cp "$CANON_EEP" "$EEP"` per level (`EEP_ORIG` is kept for the exit-restore only), and the script now `cd "$ROOT"` — the loop's dump/golden paths are root-relative (`ppm/`, `tools_pc/golden/`), contradicting the header's "can be invoked from anywhere" claim.
|
||||
|
||||
**Re-capture (this batch):** a fresh 21-level box re-round under the canonical eep (21/21 rc=0, 63 frames), committed into `tools_pc/golden/<level>/linux/` replacing the D530 box-local-save set: **47/63 frames differ** from it (save content demonstrably moves the frames — D529's drift class), 16 byte-identical (save-independent scenes). **Note on the box's pixel capability:** the 10-05 re-round's p7_report diff table (1–26% over on real content) proves its WSLg GPU display was active then; today the box reads back **black even with `DISPLAY=:0`** (`glxinfo -B` under `:0` reports no usable renderer — the WSLg GPU display is session-state-dependent, and today's session is on the software fallback), so today's `verify.sh` runs (D530's crash-detect sweep and this batch's `~/p7-verify-pixel.log`) are legitimately crash-detect-only. The pixel-gated cross-machine verify is owed for a window in which the box's GPU display is up again.
|
||||
|
||||
**Pixel-gated cross-machine gate (the real D117 datum):** `verify.sh sweep` on the box against the new canonical goldens — **2026-10-07 attempt (log `~/p7-verify-pixel.log`): 21/21 PASS, 0 FAIL, crash-detect only** (the run's renderer probe correctly failed closed on today's software-fallback session, so it adds stability, not, pixel data); the pixel verdict — including the four flaky levels' first stems — is owed for a window in which the box's WSLg GPU display is active. If the four flaky levels (dam/frigate/streets/jungle) go red there, the never-do 6 decision stands: exclude or widen the first-stem cell, do NOT re-capture.
|
||||
|
||||
**U5 review notes from the same pass (non-blockers):** the three should-fixes below were applied 2026-10-07 as D532 (gate hardening: fail-closed ini pin, hard-pinned seed, dead A/B switches removed).
|
||||
|
||||
## D532: the three P12 U5 should-fixes applied — the golden gate's ini pin now fails closed, the seed is hard-pinned (a stray `GE_RSEED` warns instead of re-seeding), and `audiodebug.ps1`'s dead A/B switches are gone (golden gate + tooling; D531/U5 follow-up)
|
||||
|
||||
**2026-10-07 (local session).** Three tooling-only fixes, no game logic:
|
||||
|
||||
1. **`verify.sh` `pin_ini_640x480` failed OPEN** — the three call sites (`single`/`sweep`/`parity`) were `pin_ini_640x480 2>/dev/null || true`, so a failed ini write (missing `data/`, read-only tree, failed snapshot) ran the gate under an **unpinned ini** — the frame depends on a defaults-only 640x480 ini exactly like the save pin (D529), so that was a spurious-verdict source, not a skipped nicety. The pin now fails closed (snapshot and write both `error + exit 2`, matching `pin_eep`'s style) and the call sites are plain.
|
||||
2. **`GOLDEN_SEED` hard-pinned** — it was `"${GE_RSEED:-0x0123456789abcdef}"`, so a stray `GE_RSEED` in the environment silently re-seeded the documented-as-pinned gate (frames shift → spurious verdicts). It is now the literal, with a warning when a differing env var is present (verified: `GE_RSEED=0xdead` warns, the pinned value is silent). `capture_p7.sh`'s `eval grep -m1 '^GOLDEN_SEED='` still picks up the same line, so capture and gate stay consistent.
|
||||
3. **`audiodebug.ps1` dead switches removed** — `-AB`/`-Old` were documented no-ops (`GE_D204_OLD` no longer exists in the game); the switches, the A/B block, and the `-OldMode` plumbing are gone, with a one-line removal note (D532).
|
||||
|
||||
PS parse: 0 errors; `bash -n` clean; the warning path verified. **Owed (unchanged):** the pixel-gated box verify in a WSLg GPU-display window (D531).
|
||||
|
||||
## D530: The box (X220) linux golden re-round landed — first cross-machine test of the four D117 flaky levels (golden gate; D529 never-do 3/6 follow-up) — **AMENDED BY D531 (2026-10-07): the 10-05 re-round ran under the box-LOCAL save, not the canonical one (the capture_p7.sh bug); the true canonical re-capture is D531**
|
||||
|
||||
**2026-10-07 (local session).** The box re-round D529 owed (never-do 3: the linux set was the D525 *cleared*-eep round and no linux number could be cited until it was re-rounded under `tools_pc/golden/ge007.eep`) ran on X220 on 2026-10-05 (tree `442eb2ff`, worktree `~/gh-fullhist-wt-p7`, log `~/p7-reround.log` hit `P7 re-round DONE` 12:53 EDT). **21/21 levels rc=0** (the box self-gate is crash-detect only — the pixel probe fails closed on the box, D244). This session pulled the 63 PNGs (21 levels × 3 frames) and committed them into `tools_pc/golden/<level>/linux/`, replacing the D525 set: 51/63 differ from the D525 round; the 12/63 that are byte-identical are save-independent scenes — including **frigate's first stem (001000)**, a direct D117 stability signal. **AMENDED BY D531: that re-round ran under the box-local save (the `capture_p7.sh` bug), so the "canonical eep" provenance claim — and the first-stem table below, as canonical-save evidence — does not hold; the D531 re-capture supersedes this set.**
|
||||
|
||||
The `fail` rows in the box report are the expected cross-eep diffs against the *old* in-tree set, not regressions: structural tier is all `ok` (phash ≤ 3, cradle@40 the documented exception; Cuba 26.4% inside its documented 23.7–36.3% structural-only range).
|
||||
|
||||
**D117 flaky-four first-stem check (D529 never-do 6 — the first cross-machine test):**
|
||||
|
||||
| level (first stem) | worst_cell | phash |
|
||||
|---|---|---|
|
||||
| dam@1500 | 1.70375 | 0 |
|
||||
| frigate@1000 | — (byte-identical to the D525 round) | 0 |
|
||||
| streets@1000 | 1.775625 | 0 |
|
||||
| jungle@900 | 5.115625 | 3 |
|
||||
|
||||
All four sit in the stable-levels' range (e.g. silo 0.41–0.84% over, worst_cell 0.41–0.42 is the quietest; archives 1.51–2.31 is noisier). **None went red → the never-do 6 decision closes with NO recipe change** (no first-stem cell excluded or widened on the linux side).
|
||||
|
||||
**Unblocked (D529 never-do 3):** the README/index v0.5.0 line "re-based on both platforms (21 levels, 63 frames each)" now stands on a canonical-eep linux set (D531's re-capture; the D530 set it first pointed at was the box-local-save round — see D531). **Fresh box sweep (crash-detect):** with the new goldens staged on the box, `verify.sh sweep` (2026-10-07) is **21/21 PASS** — but that run was crash-detect only (GE_PCDUMP reads black on the box's llvmpipe/WSLg, the D244 note), so it is a stability re-check, not a pixel datum. **AMENDED BY D531:** the "black frames" were **not** simply the no-DISPLAY llvmpipe path — the box's WSLg display is session-state-dependent: its 10-05 session was GPU-backed (the re-round's p7_report pixel table proves real frames), while today's reads back black even with `DISPLAY=:0` (software fallback; `glxinfo -B` reports no usable renderer). D531's pixel-gated attempt (21/21 crash-detect, `~/p7-verify-pixel.log`) is valid as a stability re-check; the pixel datum is owed for a GPU-display window.
|
||||
@@ -31,7 +31,7 @@ passes together fit in ~55 s.
|
||||
|
||||
## Source material
|
||||
|
||||
`C:\Users\james\Videos\NVIDIA\Build-pc\new\` — ShadowPlay recordings
|
||||
`<videos>\NVIDIA\Build-pc\new\` — ShadowPlay recordings
|
||||
(3072x1728 @ 60 fps, h264), no usable audio track (cut with `-an`). The four
|
||||
sessions and their tags are hardcoded in `SESSIONS` at the top of the script;
|
||||
add a new session there (tag, filename suffix, duration) to use it.
|
||||
|
||||
Reference in new issue
Block a user