docs(spec): expand probe design with concrete line formats + code sites
User feedback: "add the probes you need. Better info, better code." Original spec had a single ACDREAM_PROBE_INDOOR=1 with vague "log lookup results" guidance. Replaced with five individually-toggleable probes, each with: - Specific env var name + DebugPanel checkbox name. - Concrete log-line format. - Exact code site to instrument. - The hypothesis it disambiguates. Probe set: - ACDREAM_PROBE_INDOOR_WALK — dispatcher entity walk per cell - ACDREAM_PROBE_INDOOR_LOOKUP — render-data lookup hit/miss + SetupParts - ACDREAM_PROBE_INDOOR_UPLOAD — WB upload result (requested + completed) - ACDREAM_PROBE_INDOOR_XFORM — composed world transform for cell geom - ACDREAM_PROBE_INDOOR_CULL — visibility/frustum filter decisions Plus ACDREAM_PROBE_INDOOR_ALL master toggle. Implementation outline added: new RenderingDiagnostics static class (mirrors L.2a's PhysicsDiagnostics pattern), DebugPanel subsection, edits to WbDrawDispatcher + WbMeshAdapter. Acceptance criteria refreshed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f6e9c58932
commit
e798cb7898
1 changed files with 84 additions and 21 deletions
|
|
@ -98,23 +98,74 @@ Six untested hypotheses, in rough order of probability:
|
|||
|
||||
## 3. Solution
|
||||
|
||||
**Phase 1: Diagnostics.** Add a runtime-toggleable `ACDREAM_PROBE_INDOOR=1`
|
||||
env-var (mirrored as a DebugPanel checkbox) that prints one line per frame
|
||||
with:
|
||||
### Phase 1 — Diagnostics (this phase's work)
|
||||
|
||||
- Number of cell entities walked by the dispatcher.
|
||||
- Per-cell-entity: `TryGetRenderData(envCellId)` hit/miss.
|
||||
- On hit: `renderData.IsSetup`, `renderData.SetupParts.Count`.
|
||||
- For each SetupPart: `TryGetRenderData(partGfxObjId)` hit/miss.
|
||||
- The composed world matrix for the cell-geometry part (so we can see
|
||||
where the floor actually ends up in world space).
|
||||
- Whether the entity was culled by `visibleCellIds` (and why).
|
||||
Five probes, each individually toggleable via env-var + DebugPanel
|
||||
checkbox. The probes live in a new
|
||||
`AcDream.Core.Rendering.RenderingDiagnostics` static class (mirroring
|
||||
the `AcDream.Core.Physics.PhysicsDiagnostics` pattern shipped in L.2a)
|
||||
so they're discoverable from one place and survive across the
|
||||
Core / App seam.
|
||||
|
||||
Run the client, walk into Holtburg Inn, capture probe output. The log
|
||||
tells us exactly which step in the chain is breaking.
|
||||
Each probe is **rate-limited**: by default, one line per (envCellId,
|
||||
frame-modulo-30) — i.e., once per second per cell at 30 Hz — to avoid
|
||||
log spam. When `ACDREAM_PROBE_INDOOR_VERBOSE=1` is also set, the
|
||||
rate-limit drops and every frame logs.
|
||||
|
||||
**Phase 2: Fix the specific break.** Once the probe identifies the
|
||||
failure point, implement the surgical fix. Likely shapes per hypothesis:
|
||||
| Env var (and DebugPanel mirror) | Probe | Code location | Line format |
|
||||
|---|---|---|---|
|
||||
| `ACDREAM_PROBE_INDOOR_WALK` | Cell-entity dispatcher walk | `WbDrawDispatcher.WalkVisibleEntities` (rate-limited per cellId) | `[indoor-walk] cellEnt=0xID pos=(x,y,z) parentCell=0xID landblockVisible=B aabbVisible=B cellInVis=B drawn=B` |
|
||||
| `ACDREAM_PROBE_INDOOR_LOOKUP` | Render-data lookup for cell entities | `WbDrawDispatcher.DrawAccumulated` per cell entity | `[indoor-lookup] cellId=0xID hit=B isSetup=B partCount=N hasEnvCellGeom=B partsHit=N partsMiss=N` |
|
||||
| `ACDREAM_PROBE_INDOOR_UPLOAD` | WB upload result for envCellId | `WbMeshAdapter.IncrementRefCount` (on first call per id) + a callback hooked into `_meshManager.Tick()` for completion | `[indoor-upload] cellId=0xID requested=true completed=B partsCount=N cellGeomVerts=N error="..."` |
|
||||
| `ACDREAM_PROBE_INDOOR_XFORM` | Composed world transform for cell-geometry SetupPart | `WbDrawDispatcher` inside the `IsSetup` branch at line 607-621, for partGfxObjId matching `(envCellId | 0x1_00000000UL)` | `[indoor-xform] cellId=0xID cellOrigin=(x,y,z) entityWorld=(...) partTransform=(...) composed=(x,y,z y-axis,z-axis) detExpected≈1 detActual=F` |
|
||||
| `ACDREAM_PROBE_INDOOR_CULL` | Visibility / cull decision per cell entity | `WbDrawDispatcher.WalkVisibleEntities` (the two filter sites at lines 304-305 and 317-319) | `[indoor-cull] cellEnt=0xID reason="visibleCellIds-miss" or "frustum" or "served" details="..."` |
|
||||
|
||||
The five probes can be enabled independently or together. The user's
|
||||
common case is `ACDREAM_PROBE_INDOOR_ALL=1` which sets all five at
|
||||
once.
|
||||
|
||||
#### Implementation outline
|
||||
|
||||
1. **New file** `src/AcDream.Core/Rendering/RenderingDiagnostics.cs` —
|
||||
five static `bool` properties, each backed by an env-var read at
|
||||
startup, each runtime-settable from the DebugPanel.
|
||||
2. **DebugPanel section** — new "Indoor rendering diagnostics" block
|
||||
in the existing DebugPanel "Diagnostics" group, with one checkbox
|
||||
per probe + a master "all" toggle.
|
||||
3. **WbDrawDispatcher edits** — instrument the walk and the IsSetup
|
||||
draw branch. The walk probe needs to know whether the entity passed
|
||||
the cell-visibility filter; the cull probe needs the same data.
|
||||
Cleanest: emit BOTH lines in one place when either probe is on.
|
||||
4. **WbMeshAdapter edits** — `IncrementRefCount` logs an `[indoor-upload]
|
||||
requested=true` line when the id is recognized as an EnvCell
|
||||
(high-bit check `(id & 0xFFFF) >= 0x0100`). On Tick(), when a
|
||||
completion drains for an envCellId, log the result line with the
|
||||
actual ObjectMeshData/ObjectRenderData fields.
|
||||
5. **No GameWindow changes** beyond passing the diagnostics class
|
||||
into the dispatcher (if not already accessible).
|
||||
|
||||
#### Capture procedure
|
||||
|
||||
1. Build with the probe instrumentation. `dotnet build` green.
|
||||
2. Launch with `ACDREAM_PROBE_INDOOR_ALL=1`. Walk to Holtburg Inn,
|
||||
stand at the doorway, then step inside, then walk around the room.
|
||||
3. Stop the client, grep `launch.log` for `[indoor-*]` lines.
|
||||
4. The captured log identifies WHICH hypothesis matches:
|
||||
- **H1 (null upload)** → `[indoor-upload] completed=false`
|
||||
- **H2 (empty batches)** → `[indoor-upload] cellGeomVerts=0`
|
||||
- **H3 (cull bug)** → `[indoor-cull] reason="visibleCellIds-miss"`
|
||||
- **H4 (double-spawn)** → `[indoor-lookup] partCount` includes
|
||||
static-object IDs that ALSO appear in `landblock.Entities`
|
||||
- **H5 (transform double-apply)** → `[indoor-xform] composed`
|
||||
world position lands at `2 × cellOrigin` instead of `cellOrigin`
|
||||
- **H6 (MeshRefs structure)** → ruled out; probe data would still
|
||||
surface it as `hit=true isSetup=true partCount=N` followed by
|
||||
all `partsHit=0`
|
||||
|
||||
### Phase 2 — Fix the specific break (next phase)
|
||||
|
||||
Once the probe identifies the failure point, implement the surgical
|
||||
fix. Likely shapes per hypothesis:
|
||||
|
||||
| Hypothesis | Fix shape |
|
||||
|---|---|
|
||||
|
|
@ -170,16 +221,28 @@ bug), tests verify visibility BFS for indoor entities.
|
|||
|
||||
**Phase 1 (this phase):**
|
||||
|
||||
- [ ] `ACDREAM_PROBE_INDOOR=1` env var + DebugPanel mirror.
|
||||
- [ ] One log line per frame, per cell entity, showing render-data lookup
|
||||
results, SetupParts traversal, and composed transforms.
|
||||
- [ ] `AcDream.Core.Rendering.RenderingDiagnostics` static class created
|
||||
with five `bool` properties + master `IndoorAll` toggle, each backed
|
||||
by an env-var read at startup and runtime-settable.
|
||||
- [ ] DebugPanel "Diagnostics" group has a new "Indoor rendering"
|
||||
subsection with six checkboxes (five probes + master).
|
||||
- [ ] `WbDrawDispatcher` emits `[indoor-walk]`, `[indoor-lookup]`,
|
||||
`[indoor-xform]`, `[indoor-cull]` lines when the respective probe
|
||||
is on. Rate-limited to ~1/sec per cell unless verbose mode active.
|
||||
- [ ] `WbMeshAdapter` emits `[indoor-upload]` lines for EnvCell IDs:
|
||||
one `requested` line on first `IncrementRefCount`, one `completed`
|
||||
line when WB's Tick drains the result (success or failure).
|
||||
- [ ] `dotnet build` clean. `dotnet test` clean (the diagnostics-only
|
||||
change should not affect any test).
|
||||
- [ ] Probe captured at Holtburg Inn confirms which hypothesis matches.
|
||||
- [ ] Phase 2 design (amended spec or new spec) documents the surgical fix.
|
||||
Capture procedure documented in §3 above.
|
||||
- [ ] Phase 2 design (amended spec or new spec) documents the surgical
|
||||
fix matched to the identified hypothesis.
|
||||
|
||||
**Phase 2 (next phase, driven by Phase 1 output):**
|
||||
|
||||
- [ ] `dotnet build` clean, `dotnet test` clean.
|
||||
- [ ] Visual verification: walking into Holtburg Inn renders interior floor +
|
||||
walls correctly.
|
||||
- [ ] Visual verification: walking into Holtburg Inn renders interior
|
||||
floor + walls correctly.
|
||||
- [ ] Roadmap updated.
|
||||
- [ ] Probe left in place for future regressions but defaulted off.
|
||||
- [ ] Probes left in place for future regressions but defaulted off.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue