diff --git a/docs/ISSUES.md b/docs/ISSUES.md index de9c7915..8ce6f771 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -44,6 +44,49 @@ Copy this block when adding a new issue: --- +## #106 — Outdoor player-cell membership FREEZES at landblock boundaries (whole interiors unenterable) + +**Status:** OPEN +**Severity:** HIGH +**Filed:** 2026-06-09 +**Component:** physics, membership + +**Description:** Walking outdoors across a landblock boundary does NOT update the player's +outdoor cell: `playerCell` stays pinned to the last cell of the previous landblock, +indefinitely. Every downstream consumer degrades: entering any building in the new landblock +never fires the outdoor→indoor membership transition (the interior never renders — "I'm inside +but it looks like I'm standing outside"), and the render root stays anchored at the stale +outdoor cell, producing the "screen distorted with world background" artifacts while running. + +**Root cause / status:** PINNED by live capture 2026-06-09 (`flap-105-capture.log`, 53 MB, +analyzed in `docs/research/2026-06-09-105-capture-analysis-membership-landblock-pin.md`): +playerCell froze at `0xA9B40031` at log line 93363 and never changed for 10,449 frames — +spanning ~130 m of outdoor walking into landblock `0xA9B3` (player y reaching −109 in +A9B4-local coords) and an 8,929-frame stand inside an A9B3 cottage. Within-landblock outdoor +transitions are clean (96/96); all 10 successful indoor entries were same-landblock buildings; +the single failure was the only cross-landblock building entered. The render flood +independently SAW the A9B3 interior cells (`0xA9B301xx` in `[render-sig]`) — rendering is +downstream and healthy; membership is the broken layer. Suspects for the fix session: the +outdoor candidate-cell proposal in `PhysicsEngine.ResolveCellId` / `CellTransit.AddAllOutsideCells` +(a coord-convention bug there was fixed 2026-05-25; cross-landblock proposals may still be +missing or gated), and the `b3ce505` #98 stopgap which GATED the outdoor sweep (the physics +digest carries this workaround debt — this may be its fallout). Retail oracle: +`CObjCell::find_cell_list` Position-variant (`acclient_2013_pseudo_c.txt:308742-308783`) + +`LandDefs` outside-cell coordinate handling. + +**Files:** `src/AcDream.Core/Physics/PhysicsEngine.cs` (ResolveCellId), +`src/AcDream.Core/Physics/CellTransit.cs` (AddAllOutsideCells), +`src/AcDream.Core/Physics/` membership chokepoint (UpdateCellId). + +**Research:** `docs/research/2026-06-09-105-capture-analysis-membership-landblock-pin.md`. + +**Acceptance:** walk outdoors from Holtburg across each neighboring landblock boundary — +`[cell-transit]` (ACDREAM_PROBE_CELL=1) shows the outdoor cell updating to the new landblock's +cells; enter a cross-landblock building — membership transitions indoor and the interior +renders; the running-distortion artifacts stop accumulating with distance. + +--- + ## #105 — Intermittent silent dat-load failure: white/missing cottage walls until relaunch **Status:** OPEN @@ -58,18 +101,21 @@ windows) draw normally. Once broken, broken for the whole session — the failed cached (mesh batches build once, hydration runs once). The failure has never produced a single log line: every dat-read failure on the walls-relevant paths exits silently. -**Root cause / status:** NOT YET ATTRIBUTED — but heavily narrowed (full evidence: -`docs/research/2026-06-09-dat-reader-thread-safety-investigation.md`). Refuted: the dat -library's concurrent read path (Chorizite.DatReaderWriter 2.1.7) is exonerated by line-level -source audit + the in-tree hammer test (`DatConcurrencyStressTests`, ~1.1M concurrent reads, -zero anomalies). Fixed nearby: the teardown dispose-during-read AccessViolation (`8fadf77`). -Remaining candidates: a lifecycle/ordering race in our hydration/streaming pipeline, or a -GL-side staged-upload / bindless-residency failure under load. Tripwire log lines -(`[dat-miss]` / `[tex-miss]` / `[tex-skip]` / `[cell-miss]`, commit `7433b70`) now cover every -silent exit; the next occurrence self-attributes in the launch log. Discriminator: magenta -walls = TextureCache decode miss; see-through + `[tex-skip]`/`[dat-miss]` = mesh-build miss; -see-through + `[cell-miss]` = hydration miss; broken with NO tripwire output = GL-side — -instrument `WbMeshAdapter.Tick`'s upload drain next. +**Root cause / status:** LARGELY SUPERSEDED BY #106 (2026-06-09 evening): the live capture +pinned "whole interior missing / enter house and see outside" to the cross-landblock outdoor +membership freeze — most "broken house" reports were that. What REMAINS under #105 is the +narrower residual observed twice earlier: a single wall section missing (sky/clear color) +**while membership and viewer cell were demonstrably correct and INDOOR** (`viewerCell=0171`, +props drawn, collision present). All data/upload/registration layers are exonerated for it: +four rounds of tripwires (`[dat-miss]`/`[tex-miss]`/`[tex-skip]`/`[cell-miss]`, +`[geom-null]`/`[geom-misroute]`/`[up-null]`, `[finalize-replace]`/`[late-register]`) were +silent across every reproduction, the dat library is exonerated (`DatConcurrencyStressTests`, +~1.1M concurrent reads), and the capture analysis shows no never-flooding building and no +empty indoor floods. The teardown dispose-during-read AccessViolation was fixed nearby +(`8fadf77`). Known-benign noise: `[up-null]` for `0x010002B4`/`0x010008A8` (deterministic, +legitimately empty meshes). If the residual reproduces, the remaining suspects are the +draw-level clip path (the §4 edge-on clip family) — note `BuildFromExterior` has NO pv-trace +hook yet (add one for attribution). Keep all tripwires until this closes. **Files:** `src/AcDream.App/Rendering/Wb/ObjectMeshManager.cs` (texture chains), `src/AcDream.App/Rendering/Wb/DatCollectionAdapter.cs` (`DatDatabaseWrapper.TryGet`), diff --git a/docs/research/2026-06-09-105-capture-analysis-membership-landblock-pin.md b/docs/research/2026-06-09-105-capture-analysis-membership-landblock-pin.md new file mode 100644 index 00000000..fc046a5c --- /dev/null +++ b/docs/research/2026-06-09-105-capture-analysis-membership-landblock-pin.md @@ -0,0 +1,90 @@ +# #105 capture analysis — outdoor membership FREEZES at landblock boundaries (#106 PINNED) + +**Date:** 2026-06-09 (evening). **Branch:** `claude/thirsty-goldberg-51bb9b`. +**Evidence:** `flap-105-capture.log` (53 MB UTF-16LE, `ACDREAM_PROBE_FLAP=1`, 136,736 lines, +30,698 `[flap-cam]` frames, 16,587 `[render-sig]`, 750 `[pv-trace]`), analyzed by 3 parallel +workers (throwaway scripts `q105_*.py` in the worktree root). User live-reproduced during +capture: entered a cottage and "EVERYTHING disappears, like I'm standing outside." + +--- + +## 0. TL;DR + +1. **#106 PINNED: the player's OUTDOOR cell membership never crosses a landblock boundary.** + `playerCell` froze at `0xA9B40031` (line 93363) and stayed frozen for **10,449 frames**: + ~130 m of outdoor walking south across the `A9B4→A9B3` boundary (player y reaching −109.65 + in A9B4-local coords = ~82 m inside A9B3) plus an 8,929-frame stand INSIDE an A9B3 cottage. + Zero indoor candidates ever flickered. Within-landblock outdoor transitions are clean + (96/96, e.g. `0x0031↔0x0029` flipping exactly at the x=144 cell line). +2. **The discriminator landed hard:** all **10 successful** outdoor→indoor entries this + session (7 distinct buildings: 0170, 0150, 0164, 016E, 016C, 010B, 0118) were buildings in + the SAME landblock as the player's outdoor cell — each a single clean flip with the viewer + cell trailing ~48 frames (camera boom still outside), no flicker. The ONE failing entry was + the only CROSS-landblock building entered. +3. **Rendering is downstream and healthy:** while membership said "outdoor," `[render-sig]` + shows the flood drawing the A9B3 interior cells (`0xA9B30100/0103/.../0110`) — the renderer + could see the rooms membership refused to enter. 89 distinct indoor cells flood under + outdoor roots across the session; ids==draw (no misses); **no never-flooding building + exists**; **no indoor flood ever collapsed empty** (all 17 indoor roots always vis≥2). + `feedback_render_downstream_of_membership` proven again. +4. **The outdoor "running distortion" is the same freeze:** the render root stays anchored at + the stale outdoor cell while the player runs away from it (10,415-frame root run at + `0x0031`), so the whole view is built from a wrong anchor. The capture REFUTES flood-level + causes outdoors: in all 26,960 outdoor-root frames, `outPolys=1` and `vis=1` with zero + exceptions. +5. **The §4 indoor flap is unchanged and separate:** vis oscillation exists only under indoor + roots (520 changes, longest 9 consecutive flips, cells 0x013F/0x0143/0x0150/0x0171) plus + ~11 one-to-three-frame OUT↔IN root blips at doorways (e.g. lines 31704..31713) — the known + doorway flap, untouched today. + +## 1. What #106 explains vs what stays in #105 + +- **#106 explains:** "enter house → everything disappears, looks like outside" (cross-landblock + buildings), most of the day's per-session "some houses broken" reports (which houses break + depends on where you've walked = which boundaries you crossed), and the outdoor running + distortion (stale render anchor). +- **Still #105 (residual, twice-observed earlier):** a single wall section missing + (sky/clear color) while membership/viewer were demonstrably INDOOR-correct + (`viewerCell=0171`, props drawn, collision present). All data/upload/registration layers are + exonerated by 4 silent tripwire rounds; if it reproduces, the draw-level clip path (§4 + family) is the remaining suspect space. + +## 2. Fix pointers for #106 (next session) + +- **Membership chokepoint:** the outdoor candidate-cell proposal. The capture shows the + resolver flips outdoor cells fine WITHIN a landblock but never proposes another landblock's + outdoor cell. Look at `PhysicsEngine.ResolveCellId` + `CellTransit.AddAllOutsideCells` + (its coord-convention bug was fixed 2026-05-25 — `feedback_latent_bug_masked_by_fallback`; + cross-landblock proposals may be missing or clamped to the current landblock's 8×8 grid). +- **Check the `b3ce505` #98 stopgap first:** it GATED the outdoor sweep (a flagged WORKAROUND + that already caused #99). If the gate suppresses the sweep that would propose + neighboring-landblock cells, #106 is its fallout — fixing the root (per-cell shadow + architecture A6.P4) or narrowing the gate may be the real fix. Read + `claude-memory/project_physics_collision_digest.md` DO-NOT-RETRY before touching anything. +- **Retail oracle:** `CObjCell::find_cell_list` Position-variant + (`acclient_2013_pseudo_c.txt:308742-308783`) + `LandDefs` outside-coordinate handling + (`get_outside_lcoord` family) — retail resolves outdoor cells from GLOBAL coordinates, so + landblock crossings are inherent. Cross-check ACE `Physics/Common/LandDefs.cs`. +- **Cheap probe for the fix loop:** `ACDREAM_PROBE_CELL=1` (`[cell-transit]`, low volume) + while walking across each Holtburg boundary; acceptance in #106's entry. + +## 3. Apparatus notes (carried forward) + +- `[pv-trace]` is hard-gated to roots `0x016F..0x0175` (`PortalVisibilityBuilder.cs:606-647`) + and `BuildFromExterior` has **NO trace hook** — outside-looking-in cull reasons are + unobservable until one is added (needed if #105's residual reproduces). +- `[flap]`'s `vis`/`outPolys` are PRE-merge (emitted in `Build`, before + `MergeNearbyBuildingFloods` in `RetailPViewRenderer.cs:48-61`); post-merge truth is + `[render-sig] ids=/draw=`. +- Tripwires still live (keep until #105/#106 close): rounds 1–3 + `[up-null]` (known-benign + ids `0x010002B4`, `0x010008A8` — deterministic empty meshes, ignore). +- Capture + scripts: `flap-105-capture.log`, `q105_*.py` (untracked throwaways). + +## 4. The day's full arc (for the next session's orientation) + +dat-reader direction chosen → read path EXONERATED (audit + 1.1M-read hammer, `b3920d8`) → +teardown dispose-during-read AV FIXED (`8fadf77`) → white-walls trapped through 4 tripwire +rounds (all silent) → live capture → **#106 pinned (membership, cross-landblock)**. The day's +"render bug" was a physics bug all along, exactly per +`feedback_render_downstream_of_membership`. Next session: fix #106 (membership/A6 territory, +read the physics digest first).