diff --git a/docs/dev/findings.md b/docs/dev/findings.md index 69a3ad46..dacbe1cb 100644 --- a/docs/dev/findings.md +++ b/docs/dev/findings.md @@ -11067,7 +11067,15 @@ if that's recorded anywhere in the D280 write-up above. **M-152 (2026-09-16, static-only pass, no game execution this session — user was mid-playtest):** read `gfx_sp_tri1` (`port/fast3d/gfx_pc.cpp:1586-1651`) against D233/D106/D271/D234 to see what's already guarded. **D233's trivial-reject fix is ruled out as the direct cause** — it only ever adds triangles GL's own hardware clipper would legitimately draw from well-formed clip-space geometry (`gfx_opengl.cpp:320` hands GL raw `x,y,z,w` and lets GL clip natively), so a well-formed w<0/straddling triangle can't come out screen-filling from that guard alone. **New unguarded site found, not previously catalogued:** the backface-cull test right below it (`gfx_pc.cpp:1618-1629`) divides raw vertex `w` with no epsilon guard when computing the cull cross-product; a vertex at/near `w≈0` during a near-plane crossing can NaN/Inf the cross product, which silently fails both `<=0`/`>=0` cull branches and lets a triangle through that should have been backface-culled. Asset search (`UsetupsiloZ.c`, `bg_silo_all_p.c` — no `SetPrimColor`/`SetEnvColor`/`SetFillColor` at all, so the flat color must be vertex-RGBA or lighting-derived, not a literal stored triple; a byte-triple grep for `0x53,0x3e,0x2c` ±3 fuzzy across all of `assets/` found zero matches) did not identify the source model — GE's binary-included model blobs aren't literal hex in the `.c` sources, so this needs a runtime probe, not more grepping. **Confidence: LOW-MEDIUM, still not root-caused.** Two live candidates: (1) the new backface-cull NaN/Inf leak above, (2) the D106/D271 portal/room-visibility BFS family in `bg.c` (less likely given the smooth 150-frame grow/shrink arc, which doesn't match that family's usual abrupt full-screen-clamp signature, but not traced through the silo intro's specific camera/portal path so not ruled out). A `GE_D288=1` env-gated probe (cached-getenv, D250-safe) is now in tree at `gfx_pc.cpp` right after the D233 guard (~line 1616): logs any triangle whose clip-space NDC bbox covers >15% of the screen or goes non-finite, together with each vertex's `w` and `any_behind_camera`. **Next:** `GE_D288=1 GE_PCDUMP=560-745:5 ./build-pc/ge007.x86_64.exe -level_20 2> scratch/d288_probe.log` (background it, not foreground — see the environment note above), grep around frames 562-741 for `color≈(83,62,44)`. `any_behind=1` with one `w` very close to (not deeply past) 0 → candidate 1; `any_behind=0` with comfortably-positive `w`s but still a large bbox → a genuine asset/transform bug outside fast3d entirely, rules out both candidates above. -**Status (from §F table):** OPEN — visually confirmed and precisely bounded (frames ~562-741 of a bare `-level_20` boot); M-152 narrowed to two live candidates (fast3d backface-cull NaN leak, or the D106/D271 portal-BFS family) via static review, root cause still not identified; a `GE_D288` probe is in tree, needs a live/headless run to disambiguate. Promoted from the long-parked `GRAPHICS-BACKLOG.md` D171 entry with real evidence. +**M-155 (2026-09-16, this session): the M-152 probe run happened, result is inconclusive — the probe itself needs frame-gating before it can disambiguate.** Ran `GE_D288=1 GE_PCDUMP=560-745:5 ./build-pc/ge007.x86_64.exe -level_20 2> scratch/d288_probe.log` (backgrounded, per the environment note above) for a 25s bare boot. **Two problems with the result, not with the underlying bug:** +- The probe fires **116,308 times** in 25s (roughly 1500-2000 frames) — i.e. dozens of times per frame throughout the *entire* run, not bounded to the reported ~562-741 window. `bbox_frac > 0.15` (covering >15% of the screen) turns out to be a common, unremarkable occurrence for ordinary near-camera geometry (walls, floors, large props), not a distinguishing signature of the stray triangle — the threshold alone can't isolate the bug. +- The target signature from M-152's own next-step note, `color≈(83,62,44)`, **never appears** in the log (checked via `color=\([789][0-9],[567][0-9],[34][0-9]\)`, zero matches) — either the boot never actually reached the frame window where the bug fires in this run, or the flat vertex color isn't quantized the way the visual sample suggested. No `GE_PCDUMP` PPM frames were produced either (the `ppm/`-style output dir wasn't created — likely a missing/different output-dir env var beyond just the frame-range spec — so there was no visual cross-check available this pass). +- Of the `any_behind=0` subset (comfortably-positive `w`, ruling out candidate 1 for those specific triangles) with very large bboxes, all sampled instances had ordinary-looking greyscale colors (`(68,68,68)`, `(179,179,179)`, etc.) consistent with normal level geometry, not the flat brown culprit — further evidence the probe is catching routine triangles, not the bug. +- **Confidence: unchanged from M-152 (LOW-MEDIUM), no candidate confirmed or refuted.** This pass is a probe-refinement finding, not a root-cause finding. +- **Next, concrete:** gate the probe to the actual bug window before re-running — extend `GE_D288` with a `num_dls` (frame counter) check bounding it to roughly 560-745 (same pattern `GE_D236RM` already uses for its own frame gating, `gfx_pc.cpp` ~line 1648), and/or tighten the bbox threshold well above the apparent ~0.15 "normal" baseline this run established. Confirm the correct `GE_PCDUMP` output-directory env var (see `docs/dev/GE-ENV-PROBES.md`'s `GE_PCDUMP` row) before relying on visual frame dumps again. +- **Environment note, reinforcing the existing one:** the launched `ge007.x86_64.exe` process does **not** reliably die with `pkill -f ge007.x86_64.exe` from this Bash tool (process shows in `ps aux` as bare `ge007.x86_64`, no `.exe` suffix) — a stray instance ran ~90s longer than intended this session before being caught via `taskkill //F //IM ge007.x86_64.exe`. Use `taskkill //F //IM ge007.x86_64.exe` (not `pkill`) to reliably terminate a backgrounded launch from this shell. + +**Status (from §F table):** OPEN — visually confirmed and precisely bounded (frames ~562-741 of a bare `-level_20` boot); M-152 narrowed to two live candidates (fast3d backface-cull NaN leak, or the D106/D271 portal-BFS family) via static review; M-155's probe run was inconclusive (probe not frame-gated, fires too broadly to isolate the signal) — root cause still not identified. A frame-gated `GE_D288` re-run is the next concrete step. Promoted from the long-parked `GRAPHICS-BACKLOG.md` D171 entry with real evidence. ## D289 — Dam: a crash in the computer room, not reproducible on a second attempt (M-141, Steam Deck user playtest). diff --git a/docs/porting-notes.md b/docs/porting-notes.md index 6c437d08..06fbcdff 100644 --- a/docs/porting-notes.md +++ b/docs/porting-notes.md @@ -1382,6 +1382,16 @@ made mutually acceptable (dual validation / one-time migration). TMP=... TEMP=...` to a real writable per-session directory (the Claude Code scratchpad path works well) before `ninja`/`build-pc.sh`, not just any Windows-looking path string. +- **A backgrounded `ge007.x86_64.exe` launch from this Bash tool does not + reliably die to `pkill -f ge007.x86_64.exe`** (M-155, D288 session): the + process appears in `ps aux` as bare `ge007.x86_64`, no `.exe` suffix, so + the `-f` pattern match on the full name silently fails and the game + window (and its log-writing) keeps running well past the intended + `sleep N` capture window — one session let a stray instance run ~90s + longer than intended before it was caught. Use `taskkill //F //IM + ge007.x86_64.exe` instead to reliably terminate it from this shell, and + `ps aux | grep -i ge007` to confirm before moving on — don't trust a + `kill`/`pkill` exit code alone. - **A crash fault address of `0xffffffffffffffff` on x86-64 usually means a non-canonical #GP from a garbage-high-bits pointer (bits 63:48 not a sign extension of bit 47), not a computed `-1` sentinel** (cross-validated