R1 + R2 + R3 + R3.5 v1 + R3.5 v2 all shipped this session (ed72704→2bfeafd). Primary #78 fix works (cottage walls solid from inside). Three transition / sky issues remain that resist symptom-level patching: A — Exit indoor→outdoor: "objects through ground + building parts missing" B — Inside through window: "sky doesn't render" C — Entry outdoor→indoor: "floor transparent showing cellar + wrong texture" Root cause: architectural mismatch with WB's RenderInsideOut reference. We draw initial terrain unconditionally + depth-clear-if-inside as a workaround; WB skips initial terrain when inside and renders terrain ONLY at the stencil-gated step. The R3.5 v1+v2 patches were symptom fixes that kept producing new edge cases — the exact "patching symptoms" anti-pattern the predecessor revert handoff called out. Handoff doc captures: what shipped, what works, what doesn't (with verbatim user reports), the architectural diagnosis (WB vs our pipeline), the recommended next-session approach (brainstorm → write-plan → execute with the full superpowers workflow), and a self-contained pickup prompt. No code changes in this commit — handoff is doc-only. The 5 implementation commits (ed72704→2bfeafd) remain at HEAD; next session decides whether to revert R3.5 v1+v2 for a cleaner diff vs the R3 baseline, or layer the restructure on top. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
271 lines
19 KiB
Markdown
271 lines
19 KiB
Markdown
# Phase A8 — R3.5 transition-flicker iteration PAUSED. Handoff for restructure session.
|
|
|
|
**Date:** 2026-05-26 (PM)
|
|
**Status:** R1 + R2 + R3 + R3.5 v1 + R3.5 v2 all shipped. Primary #78 indoor fix WORKS. Three distinct transition/sky issues surfaced during R4 visual verification that resist symptom-level patching. **Paused for proper brainstorm → write-plan → execute-plan workflow in a fresh session.**
|
|
**Branch:** `claude/strange-albattani-3fc83c` (worktree)
|
|
**HEAD:** `2bfeafd`
|
|
**Predecessor handoff:** [docs/research/2026-05-26-a8-revert-handoff.md](2026-05-26-a8-revert-handoff.md)
|
|
**Original re-plan:** [docs/superpowers/plans/2026-05-26-phase-a8-replan.md](../superpowers/plans/2026-05-26-phase-a8-replan.md)
|
|
**Entity-taxonomy fix-shape (approved):** [docs/research/2026-05-26-a8-entity-taxonomy.md](2026-05-26-a8-entity-taxonomy.md)
|
|
|
|
---
|
|
|
|
## TL;DR
|
|
|
|
R1 (IsBuildingShell flag), R2 (EntitySet partition reshape), R3 (render-frame integration of WB-order stencil pipeline) all shipped clean. The primary #78 fix WORKS: standing inside a Holtburg cottage, the walls now block outdoor visibility — no see-through buildings, no see-through scenery. M1.5's "indoor world feels right" is partially achieved.
|
|
|
|
Visual verification (R4) surfaced **three remaining issues** that are NOT individual bugs — they're symptoms of an **architectural mismatch** between our render frame and WB's `RenderInsideOut` reference. Specifically: we draw terrain unconditionally before the stencil work and use depth-clear-if-inside as a workaround, while WB skips initial terrain entirely when inside and renders terrain ONLY at the stencil-gated step. Two patch attempts (R3.5 v1 and R3.5 v2) papered over parts of the symptom but kept producing new edge cases — the exact "patching symptoms" anti-pattern CLAUDE.md and the predecessor revert handoff explicitly call out.
|
|
|
|
**Next session must brainstorm the right architecture, write a plan, and execute.** Do NOT continue inline patches.
|
|
|
|
---
|
|
|
|
## What shipped this session (5 commits)
|
|
|
|
| Commit | Task | What it does |
|
|
|---|---|---|
|
|
| `ed72704` | R1 | Adds `WorldEntity.IsBuildingShell: bool init` set in `LandblockLoader.Buildings` loop; propagated through `GameWindow.cs:5129-5136` hydration. 2 LandblockLoader tests lock the data-layer guarantee. |
|
|
| `55f26f2` | R2 (amended) | Reshapes `WbDrawDispatcher.EntitySet` from `IndoorOnly`/`OutdoorOnly` to taxonomy-aware `IndoorPass` / `OutdoorScenery` / `LiveDynamic`. Adds `private static bool EntityMatchesSet(WorldEntity, EntitySet)` truth-table predicate. 7 tests cover the partition. |
|
|
| `60f07bc` | R3 | Wires the stencil pipeline into `GameWindow` render frame with WB-order: `MarkAndPunch → IndoorPass → EnableOutdoorPass → terrain re-draw → OutdoorScenery → DisableStencil → LiveDynamic`. Stencil-marks **camera's own cell's exit portals only** (WB Step 5 deferred). |
|
|
| `38d5374` | R3.5 v1 | Adds `cameraReallyInside = PointInCell(camPos, visibility.CameraCell)` gate for the stencil branch (kept `cameraInsideCell` for sky / lighting / depth-clear). Attempt to close the exit-transition flicker. |
|
|
| `2bfeafd` | R3.5 v2 | Also gates the depth-clear-if-inside on `cameraReallyInside`. Attempt to close the "objects through ground" symptom the v1 fix exposed. |
|
|
|
|
All 5 commits are kept; none are reverted. Build green at HEAD. Test failures within the documented 14-23 pre-existing flaky window.
|
|
|
|
---
|
|
|
|
## What's WORKING (the primary fix)
|
|
|
|
Standing inside any Holtburg cottage (ground floor or cellar), looking around:
|
|
- **Walls are solid.** No outdoor scenery visible through walls. No buildings visible through walls.
|
|
- **The original #78 symptom is gone.** This is the primary acceptance criterion for the A8 phase.
|
|
- User confirmed: *"Ok better. ... When I look out now from inside it is not showing buildings below or any windows inside the house."*
|
|
|
|
The architectural win is real:
|
|
- `WorldEntity.IsBuildingShell` correctly tags cottage walls at the dat-source boundary (`LandblockLoader.Buildings` loop).
|
|
- `WbDrawDispatcher.EntitySet.IndoorPass` correctly routes cell mesh + cell statics + building shells together — fixing the previous Round-3 regression where cottage walls disappeared.
|
|
- Camera's-own-cell-portals-only approximation (Step 5 deferred) avoids the "see through wall to another room's outdoor" regression from previous Round 2.
|
|
|
|
---
|
|
|
|
## What's NOT WORKING (3 transition/sky issues)
|
|
|
|
Verbatim user reports from R4 visual verification (post R3.5 v2):
|
|
|
|
### Issue A — Exit indoor→outdoor: "objects through ground + building parts missing"
|
|
|
|
> "If I stand outside or just pass outside I get the flicker where objects are visible through ground and walls of other buildings are missing"
|
|
|
|
**My diagnosis:** during the 3-frame grace window after camera physically exits a cell (`CellVisibility._cellSwitchGraceFrames`), `cameraInsideCell` stays true but `cameraReallyInside` becomes false (PointInCell on the previous cell returns false). With v2:
|
|
- Sky still skipped (cameraInsideCell)
|
|
- Initial terrain still drawn (unconditional, line 7115)
|
|
- depth-clear NOT fired (cameraReallyInside)
|
|
- Stencil branch NOT taken (cameraReallyInside)
|
|
- Outdoor branch (`Draw(set: All)`) runs
|
|
|
|
This *should* be correct — terrain depth preserved, all entities depth-tested. But the user still sees the symptom. **Working hypothesis:** with the depth buffer holding terrain Z (~99.99 post the -0.01 nudge from f48c74a), entities at world Z below terrain may still win depth tests in certain camera angles. Or the issue is something else entirely that the v2 didn't address.
|
|
|
|
### Issue B — Inside looking through window: "Sky don't render"
|
|
|
|
> "Sky dont render when I look from inside to outside"
|
|
|
|
**My diagnosis:** when inside, sky pass is skipped (`if (!cameraInsideCell) { _skyRenderer?.RenderSky(...); ... }` at line 7079). The stencil-gated outdoor pass re-draws terrain + outdoor scenery in portal silhouettes, but **NOT sky**. Through a window, the user sees terrain (where it projects in the portal silhouette) and beyond the terrain horizon — fog color (the framebuffer clear color is set to fog haze at line 6894, not sky color).
|
|
|
|
This is a **known WB-pipeline limitation** — WB itself doesn't draw sky inside-out. To fix in acdream we'd add a stencil-gated `_skyRenderer.RenderSky` call inside the indoor branch between `EnableOutdoorPass` and the terrain re-draw. Not done in any R3.5 patch.
|
|
|
|
### Issue C — Entry outdoor→indoor: "floor transparent showing cellar + wrong texture"
|
|
|
|
> "When going from outside to inside flickering so that parts of the floor is transparent so I see the cellar from above and wrong texture on the floor"
|
|
|
|
**My diagnosis (LOWER CONFIDENCE):** the cottage floor and cellar ceiling are at adjacent world Z values. Both meshes are loaded (cottage cell + cellar cell both in `VisibleCellIds` when standing in the cottage). During the entry transition frame, depth-fight may occur between cottage floor (Z=100.02 with the +0.02 cell origin bump) and cellar ceiling (whatever Z that mesh sits at). "Wrong texture" suggests the cellar ceiling is winning depth at floor pixels and its texture is showing through. This is **likely a pre-existing data-model / multi-cell-Z artifact, not strictly an A8 bug**, but it became visible because the new pipeline doesn't have the depth-clear-if-inside masking it on every frame anymore.
|
|
|
|
---
|
|
|
|
## Architectural diagnosis — the root cause
|
|
|
|
Reading `references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/VisibilityManager.cs:73-239` carefully:
|
|
|
|
**WB's RenderInsideOut order:**
|
|
1. (No initial terrain. Depth buffer is empty from frame-start `glClear`.)
|
|
2. MarkAndPunch — stencil bit 1 + depth = 1.0 at exit-portal silhouettes only.
|
|
3. Render interior EnvCells with stencil OFF, normal `DepthFunc.Less`. Cell mesh wins fresh depth at most pixels.
|
|
4. Enable stencil restriction (`StencilFunc Equal 1, 0x01`).
|
|
5. **Render terrain + scenery + static objects** — at portal silhouettes ONLY (stencil-restricted). Terrain depth (close, ~99.99) wins against the 1.0 punch in portal areas → outdoor visible through windows.
|
|
6. (Step 5: WB's 3-stencil-bit pipeline for cross-building visibility — deferred.)
|
|
|
|
**Our R3.5 v2 order:**
|
|
1. **Terrain drawn unconditionally** (line 7115; color + depth at ~99.99).
|
|
2. depth-clear-if-cameraReallyInside (depth → 1.0; redundant with MarkAndPunch).
|
|
3. MarkAndPunch (no-op against the depth-cleared 1.0).
|
|
4. IndoorPass — cell mesh + statics + building shells.
|
|
5. EnableOutdoorPass + terrain RE-draw + OutdoorScenery (stencil-gated).
|
|
6. DisableStencil + LiveDynamic.
|
|
|
|
**The mismatch:** we draw terrain TWICE (initial + re-draw) and have a depth-clear that's a workaround for the initial terrain draw. WB avoids both by skipping the initial terrain entirely when inside. Our pipeline is a "FRANKENSTEIN" — it works in the steady-state indoor case (the primary #78 fix) but breaks at transitions and during grace frames because the interactions between (initial terrain + depth-clear + grace + cameraInsideCell vs cameraReallyInside flag asymmetry) keep producing new edge cases.
|
|
|
|
**The R3.5 v1 and v2 patches were symptom-fixes**, not root-cause fixes. CLAUDE.md is explicit about this: *"When you spot a bug or encounter a behavioral mismatch, fix the underlying cause — do not ship a band-aid, suppression flag, grace period, retry loop, or any other 'make the symptom go away' shortcut, unless the user has explicitly approved that shape."* The user has now correctly pulled the emergency brake.
|
|
|
|
---
|
|
|
|
## Recommended next-session approach
|
|
|
|
Use the **superpowers full workflow**:
|
|
|
|
### Phase 1: BRAINSTORM (use `superpowers:brainstorming`)
|
|
|
|
Settle the design BEFORE writing a plan. Key brainstorm questions:
|
|
|
|
1. **Should the initial terrain draw be conditional?**
|
|
- WB faithfully: yes, skip when `cameraReallyInside`. Terrain draws only at stencil-gated step.
|
|
- Hybrid: keep initial terrain unconditional but remove the depth-clear so terrain depth wins against indoor cells at non-portal pixels. *(Would break the #78 fix — cottage floor at +0.02 would lose to terrain at -0.01.)*
|
|
- **Probably WB-faithful is the right call.**
|
|
|
|
2. **Should sky be re-drawn stencil-gated when inside?**
|
|
- WB: no. Sky color shows as fog-clear-color through windows.
|
|
- acdream enhancement: yes, render `_skyRenderer.RenderSky` between `EnableOutdoorPass` and the terrain re-draw inside the indoor branch.
|
|
- **Tradeoff:** WB-faithfulness vs. user's expectation that windows show sky. Retail probably shows sky through windows; investigate retail's polygon-clip scissor approach.
|
|
|
|
3. **What's the deal with the entry-flicker "floor transparent showing cellar"?**
|
|
- Is it depth-fight between cottage floor mesh (Z=100.02) and cellar ceiling mesh (Z=?)? Need a brief investigation to confirm.
|
|
- Is it a one-frame visibility-update lag where cottage cell isn't yet in VisibleCellIds during the entry transition frame?
|
|
- Is it pre-existing in main (test by reverting all of A8 and entering a cottage on main)?
|
|
- **Don't try to fix this in A8.** Identify, file as separate follow-up (likely candidate for #103 family or new #106).
|
|
|
|
4. **Should we eliminate `cameraInsideCell` vs `cameraReallyInside` asymmetry?**
|
|
- Today: `cameraInsideCell` (grace-aware) gates sky/lighting; `cameraReallyInside` (PointInCell, no grace) gates depth-clear + stencil branch.
|
|
- The split is a workaround for the grace-mechanism conflict with the render path. With WB-faithful order (no initial terrain, no depth-clear), can we use `cameraReallyInside` everywhere? Or does that introduce sky flicker at the threshold?
|
|
- The grace mechanism was added to prevent cell-id flicker at doorways. Does PointInCell with its existing epsilon already provide enough hysteresis?
|
|
- **Likely path: unify on `cameraReallyInside` and remove the grace mechanism entirely.** Simpler is better.
|
|
|
|
5. **Are R3.5 v1 + v2 patches worth keeping or should we revert them before the restructure?**
|
|
- v1 (stencil branch gate): subsumed by the restructure since the stencil branch will use `cameraReallyInside`.
|
|
- v2 (depth-clear gate): subsumed since depth-clear gets DELETED entirely.
|
|
- **Recommendation:** revert v1 and v2 (`git revert 2bfeafd 38d5374` or new commits) at the start of the implementation session, work from the R3 baseline. Cleaner diff, easier review.
|
|
|
|
### Phase 2: WRITE-PLAN (use `superpowers:writing-plans`)
|
|
|
|
Expected plan shape (TDD where possible):
|
|
- **Task RR1**: Revert R3.5 v1 + v2 (`git revert 38d5374 2bfeafd`). Result: HEAD at logical state of `60f07bc` (R3 baseline).
|
|
- **Task RR2**: Restructure render frame to WB-faithful order. Sub-steps:
|
|
- Move `cameraReallyInside` computation up next to `cameraInsideCell` (~line 7011-7014).
|
|
- Gate the initial terrain draw (line 7115) on `!cameraReallyInside`.
|
|
- Delete the depth-clear-if-inside block entirely.
|
|
- Decide on `cameraInsideCell` vs `cameraReallyInside` unification (per Phase 1 brainstorm Q4).
|
|
- Inside branch: keep existing structure (MarkAndPunch → IndoorPass → EnableOutdoorPass → terrain → OutdoorScenery → DisableStencil → LiveDynamic).
|
|
- **Task RR3 (optional)**: Add stencil-gated sky pass for sky-through-windows (per Phase 1 brainstorm Q2). Or defer as #105.
|
|
- **Task RR4**: Visual verification matrix (same as R4: cottage interior, cellar, inn, dungeon; PLUS exit transition, entry transition, sky-through-windows).
|
|
- **Task RR5**: Ship docs (R5 from original plan; file the genuine follow-ups; close #78).
|
|
|
|
GL integration tasks are visual-verification-only by nature (the partition logic + EntitySet are already unit-tested). Don't burn cycles writing unit tests for GL state — the existing infrastructure tests (26 dispatcher + 5 stencil + 2 PortalPolygons + 1 ProbeVisibility = 34) already lock the non-GL bits.
|
|
|
|
### Phase 3: EXECUTE-PLAN (use `superpowers:subagent-driven-development`)
|
|
|
|
Same pattern as this session: fresh Sonnet subagent per task, two-stage review (spec compliance + code quality). The CRITICAL extra review check beyond default — **add to the spec reviewer prompt**: *"Does the implementation match WB's RenderInsideOut order at `references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/VisibilityManager.cs:73-239`? Specifically: NO initial terrain draw when inside, NO depth-clear, terrain rendered ONLY stencil-gated?"*
|
|
|
|
---
|
|
|
|
## Pickup prompt for next session
|
|
|
|
```
|
|
Phase A8 — render frame restructure to match WB's RenderInsideOut order
|
|
faithfully. R1+R2+R3+R3.5 v1+v2 shipped this session (commits ed72704 →
|
|
2bfeafd). Primary #78 fix works (cottage interior solid walls). Three
|
|
transition/sky issues remain that resist symptom patching.
|
|
|
|
Read first (in this order — REQUIRED):
|
|
1. docs/research/2026-05-26-a8-r3.5-restructure-handoff.md (this doc — full
|
|
story of why we paused; the architectural mismatch; recommended path)
|
|
2. docs/research/2026-05-26-a8-entity-taxonomy.md (approved fix-shape)
|
|
3. docs/research/2026-05-26-a8-revert-handoff.md (predecessor; the original
|
|
A8 attempt's revert lessons — still applies)
|
|
4. docs/superpowers/plans/2026-05-26-phase-a8-replan.md (this session's
|
|
plan — R1+R2+R3 still apply; R3.5 patches and the WB-faithful
|
|
restructure are NEW work)
|
|
5. references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/VisibilityManager.cs:73-239
|
|
(the proven reference — read it verbatim BEFORE designing the restructure)
|
|
6. CLAUDE.md — find "currently working toward" to refresh state
|
|
|
|
State both altitudes:
|
|
Currently working toward: M1.5 — Indoor world feels right
|
|
Current phase: A8 — render frame restructure to WB-faithful order
|
|
HEAD: 2bfeafd (R3.5 v2)
|
|
Clean revert points: 60f07bc (R3 baseline) or 55f26f2 (R2)
|
|
Test baseline: build green; 1238 pass / 14 fail (documented flaky window)
|
|
|
|
Session flow — MUST use full superpowers workflow:
|
|
|
|
### Phase 1 — BRAINSTORM (use superpowers:brainstorming)
|
|
|
|
Settle the design. Do NOT skip this. The previous session jumped to
|
|
patching after R3 and that produced this handoff. Five questions in the
|
|
recommended-next-session-approach section of this handoff doc must be
|
|
answered before any code is written.
|
|
|
|
Brainstorm output: a short design note in chat + an updated entry in the
|
|
entity-taxonomy doc OR a fresh design doc. Get user approval before
|
|
Phase 2.
|
|
|
|
### Phase 2 — WRITE-PLAN (use superpowers:writing-plans)
|
|
|
|
Expected: tasks RR1 (revert R3.5), RR2 (restructure render frame), RR3
|
|
(optional sky-through-windows), RR4 (visual verification), RR5 (ship
|
|
docs). Plan path: docs/superpowers/plans/2026-05-2X-phase-a8-restructure.md
|
|
(date when written).
|
|
|
|
### Phase 3 — EXECUTE (use superpowers:subagent-driven-development)
|
|
|
|
Fresh Sonnet subagent per task with two-stage review. Add the WB-order
|
|
check to the spec reviewer prompt (see handoff doc).
|
|
|
|
## Constraints
|
|
|
|
- Per CLAUDE.md "no workarounds without approval" — fix the root cause.
|
|
The R3.5 v1+v2 patches were symptom fixes. Do not repeat that pattern.
|
|
- Visual verification is the acceptance test. Test scenarios in the
|
|
handoff's "What's NOT working" section MUST all be re-tested.
|
|
- Existing infrastructure (Tasks 1-6 + R1 + R2 + R3) is correct and
|
|
shipped. The restructure is a render-frame surgery, not a partition
|
|
reshape or data-layer change.
|
|
|
|
## What success looks like
|
|
|
|
After this restructure ships:
|
|
- Standing INSIDE cottage / cellar / inn / dungeon: solid walls
|
|
(unchanged from this session's R3 win).
|
|
- EXITING indoor → outdoor: clean transition. No "objects through
|
|
ground." No "buildings missing." Brief lighting transition is OK if
|
|
sky-on-cameraInsideCell is kept, otherwise no lighting transition.
|
|
- ENTERING outdoor → indoor: clean transition. No floor-transparent
|
|
showing cellar. If the floor-cellar-z-fight is pre-existing on
|
|
main, file as a separate issue and accept it as not-A8-scope.
|
|
- LOOKING THROUGH WINDOWS from inside: terrain visible at the
|
|
portal silhouette. Sky visible (if RR3 included) OR fog color (if
|
|
RR3 deferred and noted in #105).
|
|
- dotnet build green; test failures within the documented 14-23
|
|
flaky window.
|
|
```
|
|
|
|
---
|
|
|
|
## Files state at session end
|
|
|
|
```
|
|
Branch: claude/strange-albattani-3fc83c
|
|
HEAD: 2bfeafd fix(render): Phase A8 R3.5 v2 — gate depth-clear on cameraReallyInside too
|
|
Parent: 38d5374 fix(render): Phase A8 R3.5 — gate stencil branch on PointInCell containment
|
|
GP: 60f07bc feat(render): Phase A8 R3 — wire stencil pipeline into render frame (WB order)
|
|
GGP: 55f26f2 feat(render): Phase A8 R2 — WbDrawDispatcher.EntitySet taxonomy partition
|
|
GGGP: ed72704 feat(world): Phase A8 R1 — tag WorldEntity.IsBuildingShell at LandblockLoader
|
|
|
|
Working tree: clean
|
|
Build: green (0 warnings, 0 errors)
|
|
Tests: 1238 pass / 14 fail (all within documented 14-23 flaky window;
|
|
zero new failures attributable to A8 R1/R2/R3/R3.5)
|
|
Untracked log files: launch-a8-verify*.log (deletable)
|
|
```
|
|
|
|
The five commits are all NEW additions to main; no destructive history rewrites. Next session can:
|
|
- Continue from HEAD with the restructure layered on top (R3.5 patches subsumed by it).
|
|
- OR `git revert 38d5374 2bfeafd` for a cleaner diff against R3 baseline.
|
|
|
|
Either path is valid — pick whichever the brainstorm settles on.
|