From 5817102b598d1f1a3bc61d103512606c3dab53b4 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Wed, 8 Jul 2026 23:42:20 -0400 Subject: [PATCH] docs: grey-BG root cause (color-op alpha=tint-strength; slot-0 collision) + --gfx-log tool Co-Authored-By: Claude Opus 4.8 --- docs/engine-re.md | 25 +++++++++++++++++++++++++ docs/tools-reference.md | 1 + 2 files changed, 26 insertions(+) diff --git a/docs/engine-re.md b/docs/engine-re.md index c44f6b3..40c12c9 100644 --- a/docs/engine-re.md +++ b/docs/engine-re.md @@ -618,6 +618,31 @@ annotated in Ghidra, saved. **timed/animated-surface (movie-like) op**; plus the unclassified `0x21c/0x21d/0x224/0x242/0x23d/0x20a/0x20e/0x243` tail (2-arg flags / inline). These stay GAP until a follow-up slice or are safe-noop'd if the opening tolerates it. +### Grey-background root cause — slot collision + tint-strength (2026-07-08, gfx-log) + +Diagnosed with the new `--gfx-log` compositor/op trace (docs/tools-reference.md). The grey background has +**two distinct causes**, both now proven: + +1. **CORRECTION to the blend section above — op `0x202`/`0x203` "alpha" is a TINT STRENGTH, not object + opacity.** Evidence: the primary CG is drawn with `0x203 (alpha=0, color=white)` = `0x00ffffff`. That + means "blend the tint (white) into the texel by strength 0" = **no tint, fully opaque CG** — but slice-A + treated the alpha byte as the object's opacity → the CG rendered fully transparent → grey. Fix (commit + 5e4fdda): `RenderObject.TintStrength` split from `Alpha` (opacity); textured objects stay opaque and the + tint LERPs the RGB by strength (0=keep texel, 1=full tint). Surfaceless fills use the strength as fill + opacity. Verified: the opening event CGs render again (shot-confirmed). + +2. **Effect pages: everything collapses into slot 0.** `set-texture` is dominantly + `set-texture (GLOBAL resId)(GLOBAL slot)(local colorkey)` (543× across the corpus); the **slot is a + global**. In our run every such global resolves to **0**, so the background (`BG030A`), event CGs, and + the effect spritesheet (`AE001H`, an 800×400 4×2 grid of blob frames) **all set-texture into slot 0**. + Objects live-reference their slot, so loading the effect **evicts** the BG → grey; and the effect is + drawn full-screen from slot 0 (its object `src=(0,0 800x600)`) → the whole sheet (blob grid) covers the + screen. ⇒ The layering failure is a **slot-assignment** problem: the slot-selecting globals aren't + populated (unseeded boot/gfx state, or a stubbed op the display subroutine relies on), collapsing the + scene into one slot. **Open (next):** trace an effect-display subroutine to find which global holds the + slot and why it's 0 (`--boot`/INIT2 gap vs a stubbed slot-compute op). Same class as the known + `G[0x624xx]` gfx boot-state gap. NOT a compositor/z-order/blend bug. + --- ## Native walls backlog (targets for this loop) diff --git a/docs/tools-reference.md b/docs/tools-reference.md index 50c43ec..f03af2a 100644 --- a/docs/tools-reference.md +++ b/docs/tools-reference.md @@ -133,6 +133,7 @@ texture ops (no GPU context) — run windowed for real scenes. User args (after - `--shot [--shot-page N]` — capture page N to a PNG then quit (dev screenshot). At scene end it also prints the call-scripts executed as nested frames. - `--shot-sequence [--frames N]` — dump one PNG per rendered frame (`frame_0000.png…`, default N=180 ≈ 3s @60fps) then quit, auto-advancing past input waits. Verifies **time-based (sleep-paced) effects** — e.g. the opening `AE*` burst — as distinct frames, which a single `--shot` cannot. CPU/IO-heavy by design (a PNG every frame); a dev diagnostic, not a normal run. e.g. `godot --path godot -- --boot --shot-sequence out/seq --frames 300`. - `--sleep-scale ` — multiply every `sleep` (op 0xc8) duration by `f` (default 1.0). The authentic opening burst is only ~2 s, too fast to eyeball live; `--sleep-scale 5` stretches it to ~10 s so the paced sequence (arcane `AE*` → character CGs → settled BG) is watchable. Debug-only; leave at 1.0 for real playback. +- `--gfx-log ` — **compositor + op diagnostic** (the tool that root-caused the grey background). Logs, per rendered frame, only the objects whose draw outcome **CHANGED** (drawn↔skip↔gone, resId, resolved file, `slot`, `src`/`dst`, `op`acity, `tintStr`ength) — quiet until something actually changes, so the exact frame a layer drops out (and why) stands out. Also traces every `set-texture`/`create-texture` **slot assignment** (via `GodotAdvHost.TraceOps`). Works live or with `--shot-sequence`. Use it before theorising about layering/blend/geometry: it showed the grey BG = the slot-selecting globals resolving to 0 → every texture collapsing into slot 0 (see engine-re.md §"Grey-background root cause"). e.g. `godot --path godot -- --boot --gfx-log out/gfx.log` then click to the bad page. ## Asset resolution / graphics