docs(roadmap): A4 shipped + #90 cell-tracking ping-pong filed
Phase A4 (multi-cell BSP iteration) ships in three commits (e6369e2,493c5e5,691493e— with revert3add110+ reapply during visual verification that proved A4 is not the cause of the issue surfaced). 1139 + 8 baseline maintained. 10 new unit tests pass. Wires retail's CTransition::check_other_cells (acclient_2013_pseudo_c.txt:272717-272798) into Transition.FindEnvCollisions. Visual verification at the Holtburg inn vestibule surfaced a separate, pre-existing M2 blocker (filed as #90): CellId ping-pongs between outdoor 0xA9B40022 and indoor 0xA9B40164 on every wall push-back because the push-back exits the indoor CellBSP volume, causing the resolver to flip back to outdoor and bypass walls on outdoor ticks. Indoor BSP results (Collided/Adjusted/Slid all firing) prove walls ARE detected when the player is indoor; the aggregate "walls walk through" appearance comes from CellId classification instability, not from collision detection. Bug reproduces fully with A4 reverted (launch-revert2.log captured 18 cell-id flips between 0xA9B40022 ↔ 0xA9B40164, 11 inside=True building-transit events, 61 indoor-bsp queries firing the full result distribution). A4 is correct and tested but dormant in practice until #90 is fixed. Updates: - docs/research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md (new) - docs/plans/2026-04-11-roadmap.md (A4 shipped row added) - CLAUDE.md (Indoor walking Phase A4 paragraph + next-step pointer to #90 with retail oracle anchor at acclient_2013_pseudo_c.txt:308742-308783) - docs/ISSUES.md (#90 filed, HIGH severity, M2-blocker) - docs/research/2026-05-21-open-items-pickup-prompt.md (landscape table updated — A4 closed, #90 promoted to top blocker) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
691493e579
commit
1534990102
5 changed files with 281 additions and 4 deletions
32
CLAUDE.md
32
CLAUDE.md
|
|
@ -801,6 +801,38 @@ Diagnostic infrastructure: `[indoor-bsp]`, `[cell-cache]`, `[cell-transit]`,
|
|||
Handoff: [`docs/research/2026-05-19-indoor-walking-phase2-shipped-handoff.md`](docs/research/2026-05-19-indoor-walking-phase2-shipped-handoff.md).
|
||||
Phase 1 handoff: [`docs/research/2026-05-19-cluster-a-shipped-handoff.md`](docs/research/2026-05-19-cluster-a-shipped-handoff.md).
|
||||
|
||||
**Indoor walking Phase A4 — Multi-cell BSP iteration shipped 2026-05-20.**
|
||||
Three commits land the slices (with one revert/reapply during visual
|
||||
verification proving A4 wasn't the cause of the bug that surfaced):
|
||||
- `e6369e2` — `CellTransit.FindCellSet` overload exposes the candidate set
|
||||
- `493c5e5` — `Transition.CheckOtherCells` + `ApplyOtherCellResult` combine helper
|
||||
- `691493e` — wire `CheckOtherCells` into `FindEnvCollisions` (orig `967d065`, revert `3add110`, reapply)
|
||||
|
||||
Ports retail's `CTransition::check_other_cells` at
|
||||
`acclient_2013_pseudo_c.txt:272717-272798`. After the primary cell's BSP
|
||||
returns OK, every other cell the foot-sphere overlaps is queried. Halt
|
||||
on first Collided/Adjusted/Slid; Slid clears the contact-plane fields.
|
||||
10 new unit tests; 1139 + 8 baseline maintained.
|
||||
|
||||
**Visual verification surfaced a separate, pre-existing M2 blocker**:
|
||||
at the Holtburg inn doorway, the CellId ping-pongs between outdoor
|
||||
`0xA9B40022` and indoor vestibule `0xA9B40164` every few ticks. Indoor
|
||||
BSP DOES detect walls (Collided/Adjusted/Slid fire on push-back), but
|
||||
the push-back exits the indoor CellBSP volume → ResolveCellId
|
||||
reclassifies as outdoor → wall checks bypassed on outdoor ticks → net
|
||||
appearance "walls walk through." Bug reproduces fully with A4 reverted
|
||||
(see `launch-revert2.log`), confirming A4 is not the cause. A4 is
|
||||
correct and tested but **dormant in practice** until the ping-pong is
|
||||
fixed. Handoff:
|
||||
[`docs/research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md`](docs/research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md).
|
||||
|
||||
**Next: cell-tracking ping-pong fix.** Retail oracle:
|
||||
`acclient_2013_pseudo_c.txt:308742-308783` (`CObjCell::find_cell_list`
|
||||
Position-variant). Look for the cell-array hysteresis / stickiness
|
||||
logic that prevents flipping CellId on a single push-back. Likely
|
||||
modifies `PhysicsEngine.ResolveCellId` to prefer the previous indoor
|
||||
classification when the sphere is close to the indoor CellBSP volume.
|
||||
|
||||
**Next phase is Claude's choice** per work-order autonomy. Candidates:
|
||||
M2 critical path (F.2 / F.3 / F.5a / L.1c / L.1b — kill-a-drudge demo);
|
||||
or the pre-existing "next phase candidates" list below.
|
||||
|
|
|
|||
|
|
@ -509,6 +509,31 @@ propagates through portal connectivity data in `CEnvCell`.
|
|||
|
||||
---
|
||||
|
||||
## #90 — Cell-id ping-pong at indoor doorway threshold
|
||||
|
||||
**Status:** OPEN
|
||||
**Severity:** HIGH (blocks visible value of Phase A4 multi-cell BSP iteration; user-reported as "walls walk through everywhere in the inn")
|
||||
**Filed:** 2026-05-20
|
||||
**Component:** physics — cell tracking
|
||||
|
||||
**Description:** Walking into the Holtburg inn through its doorway causes the player's CellId to ping-pong between outdoor cell `0xA9B40022` and indoor vestibule cell `0xA9B40164` every few ticks. Indoor BSP DOES detect walls (Collided/Adjusted/Slid all fire on push-back), but the push-back exits the indoor CellBSP's bounding volume → `PhysicsEngine.ResolveCellId` reclassifies the player as outdoor → next tick bypasses indoor BSP entirely → player advances freely → re-enters → repeats. Net aggregate behaviour: walls APPEAR to walk through even though indoor wall hits ARE firing on the indoor frames.
|
||||
|
||||
**Root cause / status:** Cell-id stickiness missing. When the indoor BSP pushes the foot-sphere back during wall collision, the resulting world position lies just outside the indoor cell's CellBSP volume (the BSP's volume is tightly bounded to the room's interior). The cell resolver then re-evaluates and prefers the outdoor cell. Retail likely has hysteresis or a "keep previous cell unless clearly outside" rule.
|
||||
|
||||
**Files:**
|
||||
- `src/AcDream.Core/Physics/PhysicsEngine.cs:259-329` — `ResolveCellId` outdoor-then-indoor branch logic
|
||||
- `src/AcDream.Core/Physics/CellTransit.cs:235-325` — `FindCellList` / `BuildCellSetAndPickContaining` containment test
|
||||
- `src/AcDream.Core/Physics/BSPQuery.cs:950-963` — `PointInsideCellBsp` (radius-less)
|
||||
- `src/AcDream.Core/Physics/CellTransit.cs::CheckBuildingTransit` (line ~162) — outdoor→indoor entry test
|
||||
|
||||
**Research:** [`docs/research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md`](research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md) — full ping-pong analysis with launch-revert2.log evidence (61 indoor-bsp queries firing, 11 inside=True building-transit events, 18 cell-id flips between `0xA9B40022` ↔ `0xA9B40164`).
|
||||
|
||||
Retail oracle for cell-id hysteresis: `acclient_2013_pseudo_c.txt:308742-308783` (`CObjCell::find_cell_list` Position-variant). Not yet decompiled in detail. Bug-A cousin (see [`docs/research/2026-05-20-indoor-walking-bug-a-handoff.md`](research/2026-05-20-indoor-walking-bug-a-handoff.md)) — different symptom (free-fall vs walk-through), same family (doorway-edge geometry mismatch).
|
||||
|
||||
**Acceptance:** Walking into the Holtburg inn, the player's CellId promotes to `0xA9B40164` and STAYS there while the user is spatially inside the inn (not flipping back to outdoor on each wall push-back). Walls visibly block. Indoor BSP results dominate the per-tick collision evaluation while user is inside the inn. A4's `[other-cells]` probe starts firing for indoor cells adjacent to the primary.
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
**Status:** DONE
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
| C.1.5b | Per-part PES transforms + dat-hydrated entity DefaultScript dispatch. Closes issue #56. Shipped 2026-05-12 across 5 commits (`1e3c33b` docs+plan, `f3bc15e` SetupPartTransforms helper, `11521f4` ParticleHookSink applies `CreateParticleHook.PartIndex`, `5ca5827` activator refactor + GameWindow resolver lambda, `8735c39` GpuWorldState 4 new fire-sites). **Slice A** — new [`SetupPartTransforms.Compute(setup)`](../../src/AcDream.Core/Meshing/SetupPartTransforms.cs) walks `PlacementFrames[Resting]` → `[Default]` → first-available (mirrors `SetupMesh.Flatten` priority) and returns `Matrix4x4` per part; new `ParticleHookSink.SetEntityPartTransforms(entityId, partTransforms)` mirrors the existing `_rotationByEntity` pattern; `SpawnFromHook` now transforms hook offset through `partTransforms[partIndex]` before applying entity rotation. **Slice B** — activator's `ServerGuid==0` guard relaxed: keys by `entity.ServerGuid` when non-zero, else `entity.Id` (collision-free with server guids in the `0x40xxxxxx` interior / `0x80xxxxxx` scenery / `0xC0xxxxxx` ranges). Resolver delegate refactored to return `ScriptActivationInfo(ScriptId, PartTransforms)` so one dat lookup yields both pieces. `GpuWorldState` fires the activator from 4 new sites: `AddLandblock` + `AddEntitiesToExistingLandblock` (Far→Near promotion) for OnCreate, `RemoveLandblock` + `RemoveEntitiesFromLandblock` (Near→Far demotion) for OnRemove. ServerGuid==0 filter on AddLandblock avoids double-firing pending-bucket merges. **Reality discovery folded into spec §3**: EnvCell `StaticObjects` are already hydrated as `WorldEntity` instances by `GameWindow.BuildInteriorEntitiesForStreaming` (with stable `entity.Id` in `0x40xxxxxx`) — no synthetic-ID scheme or separate walker class needed (handoff §4 Q1/Q2 mooted). **Visual verification 2026-05-12**: Holtburg Town network portal swirl distributes across the arch (no ground-burial), Inn fireplace flames render over the firebox, cottage chimney smoke columns render, spell-cast animation-hook particles all match retail. 18 new + 4 updated tests, all Vfx/Meshing/Streaming/Activator green. Spec: [`docs/superpowers/specs/2026-05-13-phase-c1.5b-design.md`](../superpowers/specs/2026-05-13-phase-c1.5b-design.md). Plan: [`docs/superpowers/plans/2026-05-13-phase-c1.5b.md`](../superpowers/plans/2026-05-13-phase-c1.5b.md). | Live ✓ |
|
||||
| Indoor walking Phase 1 — BSP cluster (partial) | 2026-05-19. Probe + WorldPicker cell-BSP occlusion (#86 closed) + CellId promotion via AABB containment (partial #84 fix). Seven commits across 5 phases: `18a2e28` plan, `27d7de1` Phase A `[indoor-bsp]` probe + toggle, `3764867` Phase B CellBspRayOccluder in WorldPicker, `4e308d5` Phase B screen-rect tests, `c19d6fb` Phase D AABB containment + L.2e bare-low-byte fix, `fda6af7` Phase E `[cell-cache]` diagnostic, `1f11ba9` Phase E extended AABB/bsphere/poly-count fields. **#86 closed** (picker occlusion). **#84 partially closed** (spawn-in-building stuck-above-floor resolved; threshold/doorway walls remain open under #87). **#85 open** (wall pass-through root cause confirmed as same as #84 remaining symptom — CellId doesn't stay promoted during outdoor→indoor walking). **#87 filed** (portal-based indoor cell tracking — retail-faithful follow-up). `[indoor-bsp]` + `[cell-cache]` probes stay in place as scaffolding for the follow-up phase. Handoff: [`docs/research/2026-05-19-cluster-a-shipped-handoff.md`](../research/2026-05-19-cluster-a-shipped-handoff.md). Plan: [`docs/superpowers/plans/2026-05-19-indoor-walking-phase1-bsp-cluster.md`](../superpowers/plans/2026-05-19-indoor-walking-phase1-bsp-cluster.md). | Tests ✓ |
|
||||
| Indoor walking Phase 2 — Portal-based cell tracking | 2026-05-19. Portal-graph traversal replaces Phase D's AABB containment. Six commits: `1969c55` CellBSP+Portals wired into CellPhysics; `aad6976` CellTransit.FindCellList + FindTransitCellsSphere + AddAllOutsideCells + ResolveCellId rename; `069534a` BuildingPhysics + CheckBuildingTransit for outdoor→indoor entry; `702b30a` code-review polish; `3ffe1e4` pass foot-sphere center to ResolveCellId (critical fix — was passing CheckPos instead of GlobalSphere[0].Origin, causing PointInsideCellBsp to return false at floor level); `eb0f772` TryFindIndoorWalkablePlane synthesizes walkable plane from cell floor poly so the resolver doesn't fall through to outdoor SampleTerrainWalkable. **Closes #87, #85, and the wall-pass-through portion of #84 (fully closes #84).** Files #88 (indoor static object vibration — pre-existing) and #89 (BSPQuery.SphereIntersectsCellBsp — approximation in CheckBuildingTransit). `[cell-transit]`, `[indoor-bsp]`, `[check-bldg]`, `[cell-cache]` probes stay in place. Handoff: [`docs/research/2026-05-19-indoor-walking-phase2-shipped-handoff.md`](../research/2026-05-19-indoor-walking-phase2-shipped-handoff.md). | Live ✓ |
|
||||
| Indoor walking Phase A4 — Multi-cell BSP iteration | 2026-05-20. Ports retail's `CTransition::check_other_cells` (`acclient_2013_pseudo_c.txt:272717-272798`). After the primary cell's BSP returns OK, every other cell the foot-sphere overlaps is queried via `BSPQuery.FindCollisions`. Halt on first Collided/Adjusted/Slid; Slid clears the contact-plane fields. Three commits land the slices: `e6369e2` `CellTransit.FindCellSet` overload (refactor `FindCellList` to expose the candidate set); `493c5e5` `Transition.CheckOtherCells` + `ApplyOtherCellResult` combine helper; `691493e` (orig `967d065`, then `3add110` revert, then this reapply) wires `CheckOtherCells` into `FindEnvCollisions`. 10 new unit tests; 1139 + 8 baseline maintained. **Visual verification surfaced a separate, pre-existing M2 blocker:** at the Holtburg inn doorway the CellId ping-pongs between outdoor `0xA9B40022` and indoor vestibule `0xA9B40164` rapidly because indoor BSP push-back exits the indoor CellBSP volume → ResolveCellId reclassifies as outdoor → wall checks bypassed on outdoor ticks. Bug reproduces fully with A4 reverted (`launch-revert2.log`), confirming A4 is not the cause. A4 is correct and tested but **dormant in practice** until the ping-pong is fixed. Handoff: [`docs/research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md`](../research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md). Spec: [`docs/superpowers/specs/2026-05-20-phase-a4-multi-cell-bsp-design.md`](../superpowers/specs/2026-05-20-phase-a4-multi-cell-bsp-design.md). Plan: [`docs/superpowers/plans/2026-05-20-phase-a4-multi-cell-bsp.md`](../superpowers/plans/2026-05-20-phase-a4-multi-cell-bsp.md). | Live ✓ (dormant pending cell-tracking fix) |
|
||||
|
||||
Plus polish that doesn't get its own phase number:
|
||||
- FlyCamera default speed lowered + Shift-to-boost
|
||||
|
|
|
|||
|
|
@ -0,0 +1,218 @@
|
|||
# Phase A4 shipped + cell-tracking ping-pong finding — 2026-05-20
|
||||
|
||||
**Status:** A4 (multi-cell BSP iteration) shipped in 3 commits + 1 revert + 1 reapply
|
||||
+ 1 doc. Build green, 1139 + 8 baseline failures (same as pre-A4 baseline).
|
||||
A4 is **dormant in practice** because of a separate, pre-existing cell-tracking
|
||||
bug at the inn doorway that prevents the player from stably remaining in an
|
||||
indoor cell.
|
||||
|
||||
## TL;DR
|
||||
|
||||
- A4 ports retail's `CTransition::check_other_cells` (`acclient_2013_pseudo_c.txt:272717-272798`).
|
||||
After the primary cell's BSP returns OK, every other cell the foot-sphere overlaps
|
||||
is queried via `BSPQuery.FindCollisions`. Halt on first
|
||||
Collided/Adjusted/Slid; Slid clears the contact-plane fields. Matches retail
|
||||
exactly.
|
||||
- 10 new unit tests pass; full test suite holds at the prior 8-failure baseline.
|
||||
Three commits land the slices (FindCellSet overload → CheckOtherCells helper →
|
||||
FindEnvCollisions wire-up).
|
||||
- **Visual verification surfaced a different bug**: walking into the Holtburg
|
||||
inn ping-pongs the player's CellId between indoor `0xA9B40164` and outdoor
|
||||
`0xA9B40022` rapidly. Indoor BSP DOES detect walls (Collided / Adjusted /
|
||||
Slid all fire on push-back), but the push-back moves the sphere outside the
|
||||
indoor CellBSP's volume → `ResolveCellId` reclassifies the player as outdoor
|
||||
→ next tick bypasses indoor BSP entirely → player advances freely → re-enters
|
||||
→ repeats.
|
||||
- Because the player never STAYS in an indoor cell, A4's multi-cell pass is
|
||||
rarely (if ever) actually exercised in production. The user's reported
|
||||
"walls walk through everywhere in the inn" reproduces fully with A4 wire-up
|
||||
reverted, confirming A4 is not the cause.
|
||||
|
||||
## What shipped
|
||||
|
||||
| SHA | Phase | Description |
|
||||
|---|---|---|
|
||||
| `b100d54` | A4 spec | docs/superpowers/specs/2026-05-20-phase-a4-multi-cell-bsp-design.md |
|
||||
| `a8a0366` | A4 plan | docs/superpowers/plans/2026-05-20-phase-a4-multi-cell-bsp.md |
|
||||
| `e6369e2` | A4 slice 1 | `CellTransit.FindCellSet` overload + 3 unit tests |
|
||||
| `493c5e5` | A4 slice 2 | `Transition.CheckOtherCells` + `ApplyOtherCellResult` + 6 unit tests |
|
||||
| `967d065` | A4 slice 3 | Wire `CheckOtherCells` into `FindEnvCollisions` + 1 integration test |
|
||||
| `3add110` | A4 revert | Temporary revert of slice 3 to confirm A4 wasn't the cause |
|
||||
| `691493e` | A4 reapply | Restored slice 3 after revert test proved A4 not the cause |
|
||||
|
||||
Total: ~380 LOC added (3 new test files + helper methods); 1139 + 8 baseline
|
||||
maintained throughout.
|
||||
|
||||
## Visual verification — what we tested
|
||||
|
||||
Launched twice with the light-probe set (`ACDREAM_PROBE_INDOOR_BSP`,
|
||||
`ACDREAM_PROBE_CELL`, `ACDREAM_PROBE_CELL_CACHE`).
|
||||
|
||||
### Launch 1 — A4 wire-up active (`launch-a4.log`, 782 lines)
|
||||
|
||||
User walked from spawn toward the Holtburg inn. Log captured:
|
||||
- Player CellId stayed at outdoor `0xA9B4002A` the entire session.
|
||||
- 0 indoor-bsp probes fired.
|
||||
- 0 other-cells probes fired (A4 wire-up only runs for indoor cells).
|
||||
- User reported "all interior walls in the inn can be walked through; going
|
||||
from indoor to outdoor broken."
|
||||
|
||||
But — A4 wire-up only fires when `cellLow >= 0x0100`. The player never reached
|
||||
that state. So A4 couldn't possibly be the cause of the reported behavior.
|
||||
|
||||
### Launch 2 — A4 wire-up reverted (`launch-revert2.log`, 18490 lines)
|
||||
|
||||
User walked into and out of the inn multiple times. Log captured:
|
||||
- 18 cell-transit events: outdoor cells `0xA9B40021` / `0xA9B40022` /
|
||||
`0xA9B4002A` ping-ponging with indoor cell `0xA9B40164` (vestibule).
|
||||
- 11 `[check-bldg] inside=True` events — player crossed the building threshold.
|
||||
- 61 indoor-bsp queries against `0xA9B40164` (58) and `0xA9B40162` (3).
|
||||
- Indoor BSP results: 40 OK + 7 Adjusted + 7 Collided + 7 Slid.
|
||||
- User confirmed: "walls still walked through (same bug)" with A4 reverted.
|
||||
|
||||
**The bug reproduces with A4 reverted, proving A4 is not responsible.**
|
||||
|
||||
## The actual bug — cell-tracking ping-pong at doorway threshold
|
||||
|
||||
The repeating cycle observed in the revert log:
|
||||
|
||||
1. Player at outdoor cell `0xA9B40022`, walking toward inn door.
|
||||
2. `CheckBuildingTransit` returns `inside=True` for portal to `0xA9B40164`.
|
||||
3. ResolveCellId promotes CellId to `0xA9B40164`.
|
||||
4. Next tick: indoor branch of FindEnvCollisions fires. BSP query against
|
||||
`0xA9B40164`'s walls returns Adjusted/Collided/Slid. The sphere is pushed
|
||||
back (Adjusted/Slid) or halted (Collided).
|
||||
5. The push-back moves the sphere's world position BACK toward the outdoor
|
||||
side, beyond the indoor CellBSP's volume.
|
||||
6. ResolveCellId re-evaluates: indoor CellBSP no longer contains the sphere
|
||||
center → falls through to outdoor resolution → returns `0xA9B40022`.
|
||||
7. CellId flips back to outdoor. Next tick: indoor BSP not queried, player
|
||||
keeps advancing.
|
||||
8. Player re-crosses the building threshold → goto 2.
|
||||
|
||||
Net effect: the player visually moves through the doorway zone, walls
|
||||
intermittently push them back, but most ticks classify them as OUTDOOR and
|
||||
those ticks bypass wall collision entirely. The aggregate behavior LOOKS LIKE
|
||||
"walls walk through" even though wall hits are firing.
|
||||
|
||||
### Why A4 doesn't help here
|
||||
|
||||
A4 multi-cell iteration only runs when the primary cell BSP returns OK. In the
|
||||
ping-pong cycle, the primary cell BSP returns NON-OK (Collided/Adjusted/Slid)
|
||||
on most indoor frames — so A4 short-circuits early at the existing `if (cellState
|
||||
!= TransitionState.OK) return cellState;` path. A4 would help if the player
|
||||
were STABLY indoor (cellLow >= 0x100) AND the primary cell's BSP had sparse
|
||||
geometry that missed walls in adjacent cells. The ping-pong prevents both
|
||||
conditions.
|
||||
|
||||
### Why this is a Bug A cousin
|
||||
|
||||
The 2026-05-20 Bug A investigation
|
||||
([docs/research/2026-05-20-indoor-walking-bug-a-handoff.md](2026-05-20-indoor-walking-bug-a-handoff.md))
|
||||
documented a similar doorway-edge problem: indoor cell floor polys don't
|
||||
extend past the doorway threshold, causing free-fall when stepping out.
|
||||
|
||||
The current ping-pong is the same family of bug, different symptom: the
|
||||
indoor CellBSP volume doesn't extend past the doorway threshold either, so
|
||||
the push-back from a wall collision exits the cell's containment volume,
|
||||
and the cell-id resolver bounces the player back to outdoor.
|
||||
|
||||
Hypothesis: the inn's vestibule cell `0xA9B40164` has a CellBSP that's tightly
|
||||
bounded to the room's interior volume. The doorway threshold is right at the
|
||||
boundary. Walking against an interior wall pushes the foot-sphere back toward
|
||||
the boundary → exits CellBSP → outdoor classification.
|
||||
|
||||
## Next steps (not blocking A4 ship)
|
||||
|
||||
Two paths to investigate the ping-pong, both out of A4's scope:
|
||||
|
||||
1. **CellBSP-volume retention.** Match retail's behaviour: once a player enters
|
||||
an indoor cell, don't flip back to outdoor until they cross the EXIT portal
|
||||
plane, not just because they exited the CellBSP volume on a push-back.
|
||||
Likely a `ResolveCellId` modification that prefers the previous indoor
|
||||
classification when sphere is "close enough" to the indoor CellBSP volume.
|
||||
|
||||
2. **CellBSP-volume expansion.** Pad the indoor cell's CellBSP volume by the
|
||||
sphere radius (~0.48m) on all sides. The push-back stays within the
|
||||
padded volume. Risk: may incorrectly classify nearby outdoor positions as
|
||||
indoor.
|
||||
|
||||
The retail oracle for cell-id stickiness is at
|
||||
`acclient_2013_pseudo_c.txt:308742-308783` (`CObjCell::find_cell_list` Position-
|
||||
variant) and the cell-array hysteresis logic around it. Not yet ported in
|
||||
detail.
|
||||
|
||||
## Why ship A4 anyway
|
||||
|
||||
- **Correctness.** A4 matches retail's `check_other_cells` exactly. 10 unit
|
||||
tests pin the halt semantics + integration test verifies the wire-up. Pure
|
||||
port, no design improvisation.
|
||||
- **No regressions.** 1139-passing + 8-pre-existing-failing baseline holds.
|
||||
All A1 / A1.5 / A1.6 / A1.7 / Bug B fixes remain green.
|
||||
- **Foundation for A3.** A3 (synthesis removal) is unblocked by A4 being in
|
||||
place — it can rely on multi-cell BSP coverage for floor synthesis once the
|
||||
ping-pong is fixed and players stay indoor long enough.
|
||||
- **Reverting it would lose work.** A4 is correct and tested. The dormant
|
||||
state is caused by an unrelated bug. Reverting would just make the
|
||||
unrelated bug harder to investigate (no multi-cell foundation to build on).
|
||||
|
||||
## What this is NOT
|
||||
|
||||
This is **NOT** a fix for the user's "walls walk through" report. That bug is
|
||||
pre-existing, caused by cell-tracking instability at doorway thresholds.
|
||||
|
||||
This is **NOT** a regression introduced by A4. The bug reproduces fully with
|
||||
A4's wire-up reverted (verified by `launch-revert2.log`).
|
||||
|
||||
This is **NOT** the same as Bug A (synthesis removal). Bug A's symptom was
|
||||
free-fall on doorway exit; this is wall walk-through due to CellId classification
|
||||
flipping back to outdoor on each push-back.
|
||||
|
||||
## Code anchors
|
||||
|
||||
- Phase A4 wire-up: [src/AcDream.Core/Physics/TransitionTypes.cs:1614-1631](../../src/AcDream.Core/Physics/TransitionTypes.cs#L1614).
|
||||
- `CheckOtherCells` + `ApplyOtherCellResult`: TransitionTypes.cs (search `CheckOtherCells`).
|
||||
- `FindCellSet` overload: [src/AcDream.Core/Physics/CellTransit.cs](../../src/AcDream.Core/Physics/CellTransit.cs) (search `FindCellSet`).
|
||||
- ResolveCellId outdoor branch (where the ping-pong happens): [src/AcDream.Core/Physics/PhysicsEngine.cs:259-329](../../src/AcDream.Core/Physics/PhysicsEngine.cs#L259).
|
||||
|
||||
## Probe captures
|
||||
|
||||
- `launch-a4.log` (782 lines) — A4 active, player stayed outdoor (didn't reach
|
||||
inn). Confirms A4's indoor branch never fired in that session.
|
||||
- `launch-revert.log` (1.2M lines) — A4 reverted, player parked at outdoor cell
|
||||
with 400K+ `[check-bldg]` probes all returning `inside=False`. Player never
|
||||
moved.
|
||||
- `launch-revert2.log` (18490 lines) — A4 reverted, player walked into inn
|
||||
multiple times. Captured the ping-pong cycle. Indoor BSP results breakdown:
|
||||
40 OK + 7 Adjusted + 7 Collided + 7 Slid. 11 `inside=True` building-transit
|
||||
events.
|
||||
|
||||
## How to start a fresh session
|
||||
|
||||
Open a new Claude Code session, then:
|
||||
|
||||
```
|
||||
Pick up the cell-tracking ping-pong investigation that blocked Phase A4
|
||||
from being exercised in practice.
|
||||
|
||||
1. Read docs/research/2026-05-20-phase-a4-shipped-cell-pingpong-finding.md
|
||||
FIRST. It documents A4 ship (correct, dormant) + the ping-pong bug it
|
||||
surfaced.
|
||||
|
||||
2. A4 is shipped (3 commits at e6369e2, 493c5e5, 691493e). Don't touch it.
|
||||
1139 + 8 baseline holds.
|
||||
|
||||
3. The real M2 blocker: at the Holtburg inn doorway, CellId ping-pongs
|
||||
between 0xA9B40022 (outdoor) and 0xA9B40164 (vestibule) every few ticks
|
||||
because indoor BSP push-back exits the indoor CellBSP volume → outdoor
|
||||
reclassification → walls bypassed on outdoor ticks.
|
||||
|
||||
4. Investigate cell-id hysteresis. Retail oracle:
|
||||
acclient_2013_pseudo_c.txt:308742-308783 (CObjCell::find_cell_list
|
||||
Position-variant). Look for the cell-array stickiness logic that retail
|
||||
uses to prevent ping-pong.
|
||||
|
||||
5. CLAUDE.md rules: no workarounds, retail-faithful, probe-first.
|
||||
|
||||
State M2 as the milestone, "cell-tracking ping-pong fix" as the phase.
|
||||
```
|
||||
|
|
@ -6,14 +6,15 @@ relate, what depends on what, what order makes sense.
|
|||
|
||||
The pasteable session-start prompt is at the bottom of this doc.
|
||||
|
||||
## The landscape at a glance
|
||||
## The landscape at a glance (updated 2026-05-20)
|
||||
|
||||
| # | Item | Domain | Depends on | M2-blocker? |
|
||||
|---|---|---|---|:---:|
|
||||
| A4 | Walls walk-through in vestibule cells — multi-cell BSP iteration | Collision | — | **YES** |
|
||||
| stairs | Stairs walk-through — likely falls out of A4 | Collision | A4 | YES (if still broken after A4) |
|
||||
| **#90 ping-pong** | **NEW TOP BLOCKER** — CellId flips between outdoor `0xA9B40022` and indoor vestibule `0xA9B40164` on each wall push-back at the inn doorway; user perceives "walls walk through everywhere" | Collision — cell tracking | — | **YES** (M2) |
|
||||
| A4 | ~~Walls walk-through in vestibule cells — multi-cell BSP iteration~~ | Collision | — | **CLOSED 2026-05-20** (shipped, but dormant in practice until #90 is fixed) |
|
||||
| stairs | Stairs walk-through — likely same root cause as #90 (also a doorway-edge geometry issue) | Collision | #90 | YES (likely subsumed by #90) |
|
||||
| A2 | PHSP inversion — `polygon_hits_sphere` early-return logically inverted vs retail | Collision math | — | Low (subtle correctness only) |
|
||||
| A3 | Synthesis removal — delete `TryFindIndoorWalkablePlane`, rely on retail CP retention | Architectural | A4 + A2 | No (cleanup, retail-faithful) |
|
||||
| A3 | Synthesis removal — delete `TryFindIndoorWalkablePlane`, rely on retail CP retention | Architectural | A4 + #90 + A2 | No (cleanup, retail-faithful) |
|
||||
| L-indoor | Lighting indoors broken | Rendering | — | No (M7 polish) |
|
||||
| L-spotlight | Items projecting spotlight on walls | Rendering | — | No (M7 polish) |
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue