docs: indoor walkable-plane BSP port partial-ship handoff
Foundation work (6 commits ff548b9..f845b22) landed but visual
verification 2026-05-19 FAILED to fix the user-reported indoor bugs.
Documenting the deeper diagnosis + the next phase target without
reverting the foundation work.
What landed (kept):
- BSPQuery.FindWalkableInternal gained ref ushort hitPolyId (Task 1).
- New public BSPQuery.FindWalkableSphere wrapper over the existing
retail-faithful walkable finder (Task 2).
- Transition.TryFindIndoorWalkablePlane refactored through it,
PointInPolygonXY deleted (Task 3).
- [indoor-walkable] runtime-toggleable probe (Task 4).
- 5 new tests + 9 updated existing tests, all green; build clean.
What didn't fix: cellar descent FAIL, 2nd-floor walking FAIL
(intermittent falling-stuck), single-floor cottage REGRESSION (was
stable, now intermittent falling-stuck), phantom collisions PERSIST.
Probe evidence: 1443 MISS / 2 HIT over 1445 calls. Smoking gun:
foot-sphere-tangent-to-floor case fails PolygonHitsSpherePrecise's
|dist| > radius - epsilon check by ~0.0002. The BSP walker is
correct; the caller (TryFindIndoorWalkablePlane) is misusing it.
Root cause (deeper than originally diagnosed): TryFindIndoorWalkablePlane
exists only as a Phase 2 commit eb0f772 stop-gap. Retail doesn't
synthesize a ContactPlane per frame — retail RETAINS the previous
frame's plane when the BSP says no collision. Retail's find_walkable
only runs inside step_sphere_down (a sweep), never as a standing-still
query.
Next phase target: port retail's ContactPlane retention so the
resolver retains state across frames. Likely eliminates the per-frame
TryFindIndoorWalkablePlane call entirely. Foundation work (BSP walker
+ probe + tests) remains useful regardless.
ISSUES #83 remains OPEN with the deeper diagnosis.
Roadmap header updated to reflect partial-ship status.
Handoff at docs/research/2026-05-19-indoor-walkable-plane-bsp-port-shipped-handoff.md.
Spec: docs/superpowers/specs/2026-05-19-indoor-walkable-plane-bsp-port-design.md
Plan: docs/superpowers/plans/2026-05-19-indoor-walkable-plane-bsp-port.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f845b2241a
commit
c6b3fd6ebf
3 changed files with 253 additions and 18 deletions
|
|
@ -282,29 +282,77 @@ slopes shows matching shading.
|
|||
|
||||
---
|
||||
|
||||
## #83 — Walking up stairs broken
|
||||
## #83 — Indoor multi-Z walking broken (cellars, 2nd floors, intermittent falling-stuck)
|
||||
|
||||
**Status:** OPEN
|
||||
**Severity:** HIGH (blocks vertical indoor traversal)
|
||||
**Status:** OPEN — foundation work landed 2026-05-19, root-cause fix deferred to a follow-up investigation phase
|
||||
**Severity:** HIGH (blocks vertical indoor traversal + degrades single-floor cases)
|
||||
**Filed:** 2026-05-19
|
||||
**Component:** physics, movement
|
||||
**Component:** physics, movement, resolver
|
||||
|
||||
**Description:** When the player tries to walk up stairs inside a
|
||||
building, movement is broken — gets stuck, gets bounced, or fails to
|
||||
ascend.
|
||||
**Description:** Walking UP stairs in single-floor houses works
|
||||
(grounded step-up routes through retail-faithful `BSPQuery.FindWalkableInternal`
|
||||
via `StepSphereDown`). Walking DOWN into cellars fails ("ground blocking" —
|
||||
can't descend). Walking on 2nd floors works partially but intermittently
|
||||
gets stuck in the falling animation. "Phantom collisions" / invisible
|
||||
obstacles in rooms persist. The original title "Walking up stairs broken"
|
||||
was misleading per user's clarification 2026-05-19.
|
||||
|
||||
**Root cause / status:** The retail physics has explicit step-up logic
|
||||
(`CPhysicsObj::step_up` etc.) ported into `PhysicsEngine` for outdoor
|
||||
terrain ramps. For indoor stairs (EnvCell CellStruct geometry composed
|
||||
of polygons), the step-up resolver may not be examining cell BSP
|
||||
correctly, OR cell BSP and cell mesh disagree on stair Z values.
|
||||
**Partial fix landed 2026-05-19 (6 commits `ff548b9` → `f845b22`).**
|
||||
Foundation work: extended `BSPQuery.FindWalkableInternal` to expose the
|
||||
hit polygon's dictionary key id; added thin public wrapper
|
||||
`BSPQuery.FindWalkableSphere` over the existing retail-faithful BSP
|
||||
walkable-finder (acclient_2013_pseudo_c.txt:326211 / :326793); refactored
|
||||
`Transition.TryFindIndoorWalkablePlane` to route through that wrapper
|
||||
instead of its Phase-2 linear first-match XY scan; added `[indoor-walkable]`
|
||||
runtime-toggleable probe line for diagnostic visibility. 5 new unit tests
|
||||
+ 1 integration test, 9 pre-existing IndoorWalkablePlane tests updated
|
||||
to the new signature.
|
||||
|
||||
**Files:**
|
||||
- `src/AcDream.Core/Physics/PhysicsEngine.cs`
|
||||
- `src/AcDream.Core/Physics/TransitionTypes.cs` (cell BSP query path).
|
||||
**Foundation work did NOT fix the user-reported bugs.** Visual verification
|
||||
2026-05-19: cellar descent FAIL, 2nd-floor walking FAIL (intermittent
|
||||
falling-stuck), single-floor cottage REGRESSED to intermittent falling-stuck
|
||||
(was stable before), phantom collisions PERSIST. The probe captured 1443
|
||||
MISS / 2 HIT over 1445 indoor-walkable calls — the BSP walker correctly
|
||||
rejects the foot-sphere-tangent-to-floor case (sphere center is exactly
|
||||
at `floorZ + radius` when grounded, so `PolygonHitsSpherePrecise` fails
|
||||
the `|dist| > radius - epsilon` check by ~0.0002).
|
||||
|
||||
**Acceptance:** Walking forward at the base of an inn stairwell ascends
|
||||
to the second floor without getting stuck.
|
||||
**Root cause (deeper than originally diagnosed):** `Transition.TryFindIndoorWalkablePlane`
|
||||
fundamentally exists as a Phase 2 commit `eb0f772` stop-gap to synthesize
|
||||
a ContactPlane every frame when the indoor BSP returns OK. Retail doesn't
|
||||
do this — retail RETAINS the previous frame's `ContactPlane` when the
|
||||
collision dispatcher says "no collision." There is no retail analog of
|
||||
`find_walkable` being called as a standing-still query — retail's
|
||||
`find_walkable` only runs inside a downward sphere sweep
|
||||
(`step_sphere_down`), where the sphere is moving and the overlap test
|
||||
is meaningful. In our `TryFindIndoorWalkablePlane` flow, the sphere is
|
||||
tangent (grounded), not moving — the algorithm correctly returns "no
|
||||
overlap." The single-floor cottage worked previously because the OLD
|
||||
linear scan ignored Z and falsely returned HIT for any XY-overlapping
|
||||
walkable; the new BSP-walker correctly identifies "no overlap" and
|
||||
falls through to the outdoor terrain backstop, which only happens to
|
||||
produce sensible Z for single-floor outdoor-adjacent cases.
|
||||
|
||||
**Files in the foundation work:**
|
||||
- `src/AcDream.Core/Physics/BSPQuery.cs` — `FindWalkableInternal` signature extension, new `FindWalkableSphere` public wrapper
|
||||
- `src/AcDream.Core/Physics/TransitionTypes.cs` — `TryFindIndoorWalkablePlane` refactor, `PointInPolygonXY` deletion, `[indoor-walkable]` probe
|
||||
- `tests/AcDream.Core.Tests/Physics/BSPQueryTests.cs` — 4 new unit tests
|
||||
- `tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs` — new integration test
|
||||
- `tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs` — 9 tests updated to new signature
|
||||
|
||||
**Next investigation phase (deferred):** Port retail's `ContactPlane` retention
|
||||
mechanism so the resolver retains the previous frame's contact plane when
|
||||
the BSP says "no collision," instead of re-synthesizing it per frame. The
|
||||
proper fix likely eliminates `TryFindIndoorWalkablePlane` entirely. Needs
|
||||
deep investigation of retail's `CTransition::transitional_insert` /
|
||||
`CPhysicsObj::transition` / `LastKnownContactPlane` interactions. Foundation
|
||||
work (BSP walker + probe + tests) remains useful regardless of approach.
|
||||
|
||||
**Acceptance:** Walk down stairs into a cellar without getting stuck.
|
||||
Walk on a 2nd floor without intermittent falling-stuck. Single-floor
|
||||
cottage walking remains stable (no regression).
|
||||
|
||||
**Handoff:** [`docs/research/2026-05-19-indoor-walkable-plane-bsp-port-shipped-handoff.md`](research/2026-05-19-indoor-walkable-plane-bsp-port-shipped-handoff.md).
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue