docs: file #87 — retire WB fork band-aid via geom-only API

Phase 2's one-line WB patch (Setup-prefix guard at ObjectMeshManager.cs:1230)
fixed the symptom but is structurally a band-aid. CLAUDE.md's
no-workarounds rule says we should retire it.

The proper fix is switching our EnvCell rendering from the
general-purpose PrepareMeshDataAsync entry point (which iterates
static-object parts + emitters we don't need + triggers the buggy
TryGet<Setup> call) to WB's narrower PrepareEnvCellGeomMeshDataAsync
API at ObjectMeshManager.cs:386. That function only builds cell
room mesh — which is the only thing we use WB for at the cell
level. Static objects are already hydrated separately, particle
scripts already run via our own EntityScriptActivator.

#87 is the issue tracking that refactor. When it lands the WB fork
returns to pristine state (no acdream-specific commits on the
acdream branch for this file).

Handoff doc updated to flag the patch as a known band-aid pending #87.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-19 14:31:14 +02:00
parent b04ad448fa
commit eeb45e16e3
2 changed files with 72 additions and 1 deletions

View file

@ -48,6 +48,77 @@ Copy this block when adding a new issue:
---
## #87 — Drop WB fork patch by switching to PrepareEnvCellGeomMeshDataAsync
**Status:** OPEN
**Severity:** MEDIUM (band-aid removal; not user-visible)
**Filed:** 2026-05-19
**Component:** rendering, WB integration
**Description:** Phase 2 (2026-05-19) shipped a one-line patch in our
WB fork at `references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/ObjectMeshManager.cs:1230`
(branch `acdream` on the fork, SHA `34460c4`) to guard a blind
`TryGet<Setup>(stab.Id, ...)` call against GfxObj-prefixed ids. That
patch fixes the symptom (missing floors) but is structurally a
band-aid — per CLAUDE.md's no-workarounds rule we should retire it.
The proper fix: switch our EnvCell rendering from
`PrepareMeshDataAsync(envCellId, ...)` (general-purpose entry that
also iterates static-object parts + emitters we don't need) to WB's
narrower `PrepareEnvCellGeomMeshDataAsync(geomId, environmentId, cellStructure, surfaces)`
at [`ObjectMeshManager.cs:386`](../references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/ObjectMeshManager.cs:386).
That function only builds the cell room mesh (floor / walls / ceiling),
which is the only piece we actually use from WB for cells — we already
hydrate static objects as separate `WorldEntity` instances in
`BuildInteriorEntitiesForStreaming`, and we run particle scripts via
our own `EntityScriptActivator` (Phase C.1.5b).
**Root cause / status:** Misuse of WB's general-purpose API for a
geometry-only need. The general-purpose path triggers static-object
iteration that has a bug (TryGet<Setup> without type check) AND that
does work we throw away. Both problems disappear if we use the
geometry-only entry point WB already exposes for exactly this purpose
(it's what WB's own `EnvCellRenderManager` uses internally).
**Trade-offs:**
| | Current (patched WB) | Switch to geom-only API |
|---|---|---|
| WB fork divergence | One-line patch | Zero |
| Future WB upstream merges | Conflicts | Clean |
| Performance | Slightly worse (wasted iteration) | Slightly better |
| Risk to other functionality | None (working today) | Needs re-verification |
**Files (the change):**
- `src/AcDream.App/Rendering/GameWindow.cs` around line 5367-5378
(cell-entity hydration — change `MeshRefs[0].GfxObjId` from `envCellId`
to `envCellId | 0x100000000UL`, the synthetic geom id with bit 32 set).
- `src/AcDream.App/Rendering/Wb/WbMeshAdapter.cs` — add a new method
`PrepareEnvCellGeomMesh(ulong geomId, uint environmentId, ushort cellStructure, List<ushort> surfaces)`
that forwards to `_meshManager.PrepareEnvCellGeomMeshDataAsync(...)`,
and call it from the streaming path instead of the bare
`IncrementRefCount(envCellId)`.
- `references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/ObjectMeshManager.cs:1230`
— revert the type-check guard we added. The function returns to
pristine WB state.
**Acceptance:**
- Floors still render in Holtburg Inn (regression check vs Phase 2).
- `references/WorldBuilder` submodule pointer returns to upstream-clean
(no acdream-specific commits in the fork's `acdream` branch — or
rather, the `acdream` branch fast-forwards back to match upstream's
state for this file).
- Probe re-capture at Holtburg confirms `[indoor-upload] completed` for
all cells previously failing.
- No `[wb-error]` lines.
**Research:** [`docs/research/2026-05-19-indoor-cell-rendering-cause.md`](research/2026-05-19-indoor-cell-rendering-cause.md)
documents the underlying WB bug.
---
## Indoor walking issue cluster (2026-05-19)
The Phase 2 indoor cell rendering fix (floor now renders inside buildings)