docs(plan): remove per-frame indoor walkable-plane synthesis (Bug A)
Six-task plan for Bug A slice (spec 2026-05-20): 1. Replace synthesis call site with return TransitionState.OK 2. Delete Transition.TryFindIndoorWalkablePlane method + constant 3. Delete IndoorWalkablePlaneTests.cs + TransitionTypesTests.cs 4. Run physics suite, confirm baseline holds 5. Single commit per spec 6. User visual verification (5 scenarios) Net delta: ~-480 lines. BSPQuery.FindWalkableSphere + its 5 unit tests retained as the underlying retail-faithful walkable-finder API. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3bec18f0e4
commit
686f27f227
1 changed files with 472 additions and 0 deletions
|
|
@ -0,0 +1,472 @@
|
||||||
|
# Indoor Walkable-Plane Synthesis Removal Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Delete the per-frame `Transition.TryFindIndoorWalkablePlane` synthesis + outdoor-terrain fallthrough from the indoor branch of `FindEnvCollisions`, restoring retail's "ContactPlane retained on OK" behavior.
|
||||||
|
|
||||||
|
**Architecture:** Pure deletion. Replace the ~50-line synthesis block in `FindEnvCollisions` with `return TransitionState.OK;`. Delete the now-orphan helper method + constant + 2 test files (9 tests total). Net delta about -480 lines.
|
||||||
|
|
||||||
|
**Tech Stack:** C# .NET 10, xUnit, existing `BSPQuery` / `Transition` / `CellPhysics` types.
|
||||||
|
|
||||||
|
**Spec:** [`docs/superpowers/specs/2026-05-20-indoor-walkable-synthesis-removal-design.md`](../specs/2026-05-20-indoor-walkable-synthesis-removal-design.md)
|
||||||
|
|
||||||
|
**Predecessor:** [`docs/superpowers/specs/2026-05-20-indoor-bsp-worldorigin-fix-design.md`](../specs/2026-05-20-indoor-bsp-worldorigin-fix-design.md) (Bug B, shipped `de8ffde`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
**Files modified:**
|
||||||
|
|
||||||
|
- `src/AcDream.Core/Physics/TransitionTypes.cs` — three deletions in this one file:
|
||||||
|
1. The synthesis block in `FindEnvCollisions` (about lines 1506-1558), replaced with `return TransitionState.OK;`.
|
||||||
|
2. The `TryFindIndoorWalkablePlane` method itself (about lines 1269-1372, including doc-comment).
|
||||||
|
3. The `INDOOR_WALKABLE_PROBE_DISTANCE` constant (about lines 1374-1381).
|
||||||
|
|
||||||
|
**Files deleted:**
|
||||||
|
|
||||||
|
- `tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs` (291 lines, 8 tests).
|
||||||
|
- `tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs` (111 lines, 1 test).
|
||||||
|
|
||||||
|
**Files intentionally preserved:**
|
||||||
|
|
||||||
|
- `src/AcDream.Core/Physics/BSPQuery.cs` — `FindWalkableSphere` + `FindWalkableInternal`'s `hitPolyId` ref param stay.
|
||||||
|
- `tests/AcDream.Core.Tests/Physics/BSPQueryTests.cs` — all 5 `FindWalkableSphere_*` tests + the Bug B regression test stay.
|
||||||
|
- `src/AcDream.Core/Physics/PhysicsDiagnostics.cs` — `[cp-write]` probe stays.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 1: Replace per-frame synthesis call site with `return OK`
|
||||||
|
|
||||||
|
The synthesis block sits inside the indoor branch of `FindEnvCollisions`, immediately after the `cellState != TransitionState.OK` early-return.
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `src/AcDream.Core/Physics/TransitionTypes.cs` (about lines 1506-1558).
|
||||||
|
|
||||||
|
- [ ] **Step 1: Read the lines to confirm exact whitespace**
|
||||||
|
|
||||||
|
Run Read on `src/AcDream.Core/Physics/TransitionTypes.cs` with offset=1498 and limit=65. Confirm the block from the `if (cellState != TransitionState.OK)` early-return through the trailing `}` closing the indoor BSP branch matches what the Edit will operate on.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Apply the Edit to TransitionTypes.cs**
|
||||||
|
|
||||||
|
Use the Edit tool with the following parameters. The `old_string` is the existing synthesis block; the `new_string` is the bare `return TransitionState.OK;`.
|
||||||
|
|
||||||
|
OLD_STRING (paste into Edit's `old_string` exactly, including leading whitespace):
|
||||||
|
|
||||||
|
```
|
||||||
|
if (cellState != TransitionState.OK)
|
||||||
|
{
|
||||||
|
if (!ObjectInfo.State.HasFlag(ObjectInfoState.Contact))
|
||||||
|
ci.CollidedWithEnvironment = true;
|
||||||
|
return cellState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Synthesize indoor walkable contact plane ──────────────
|
||||||
|
// Indoor walking Phase 2 follow-up (2026-05-19). When the BSP
|
||||||
|
// returns OK (no wall collision), the player is standing on a
|
||||||
|
// floor poly inside the cell. We must NOT fall through to
|
||||||
|
// outdoor terrain (SampleTerrainWalkable) — the outdoor terrain
|
||||||
|
// Z is below the indoor floor due to the +0.02f Z-bump applied
|
||||||
|
// for render z-fight prevention. ValidateWalkable would then see
|
||||||
|
// the player 0.5m above the outdoor plane → marks them as
|
||||||
|
// airborne → walkable=False → falling animation, never recovers.
|
||||||
|
//
|
||||||
|
// Retail: CEnvCell::find_env_collisions returns from the cell
|
||||||
|
// branch with the cell's walkable plane set — no fall-through
|
||||||
|
// to terrain.
|
||||||
|
bool walkableHit = TryFindIndoorWalkablePlane(
|
||||||
|
cellPhysics, localCenter, sphereRadius,
|
||||||
|
out var indoorPlane,
|
||||||
|
out var indoorVertices,
|
||||||
|
out uint hitPolyId);
|
||||||
|
|
||||||
|
if (PhysicsDiagnostics.ProbeIndoorBspEnabled)
|
||||||
|
{
|
||||||
|
if (walkableHit)
|
||||||
|
{
|
||||||
|
// dz = signed gap between foot and synthesized plane.
|
||||||
|
// Plane: N·p + D = 0 ⇒ pZ_on_plane = -D/N.z (for upward-facing planes)
|
||||||
|
// gap = foot.Z - pZ_on_plane = foot.Z - (-D/N.z) = foot.Z + D/N.z
|
||||||
|
float dz = footCenter.Z + indoorPlane.D / indoorPlane.Normal.Z;
|
||||||
|
Console.WriteLine(System.FormattableString.Invariant(
|
||||||
|
$"[indoor-walkable] cell=0x{sp.CheckCellId:X8} wpos=({footCenter.X:F3},{footCenter.Y:F3},{footCenter.Z:F3}) probe={INDOOR_WALKABLE_PROBE_DISTANCE:F2} result=HIT poly=0x{hitPolyId:X4} wn=({indoorPlane.Normal.X:F3},{indoorPlane.Normal.Y:F3},{indoorPlane.Normal.Z:F3}) wD={indoorPlane.D:F3} dz={dz:+0.00;-0.00;+0.00}"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine(System.FormattableString.Invariant(
|
||||||
|
$"[indoor-walkable] cell=0x{sp.CheckCellId:X8} wpos=({footCenter.X:F3},{footCenter.Y:F3},{footCenter.Z:F3}) probe={INDOOR_WALKABLE_PROBE_DISTANCE:F2} result=MISS"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walkableHit)
|
||||||
|
{
|
||||||
|
return ValidateWalkable(
|
||||||
|
footCenter,
|
||||||
|
sphereRadius,
|
||||||
|
indoorPlane,
|
||||||
|
isWater: false,
|
||||||
|
waterDepth: 0f,
|
||||||
|
cellId: sp.CheckCellId,
|
||||||
|
walkableVertices: indoorVertices);
|
||||||
|
}
|
||||||
|
// If no walkable floor was found under the player indoors
|
||||||
|
// (rare — cell with only walls/ceiling), fall through to
|
||||||
|
// outdoor terrain as a defensive backstop. Indoor walking
|
||||||
|
// will report walkable=False until the player moves over a
|
||||||
|
// cell with a proper floor poly.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
NEW_STRING (paste into Edit's `new_string`):
|
||||||
|
|
||||||
|
```
|
||||||
|
if (cellState != TransitionState.OK)
|
||||||
|
{
|
||||||
|
if (!ObjectInfo.State.HasFlag(ObjectInfoState.Contact))
|
||||||
|
ci.CollidedWithEnvironment = true;
|
||||||
|
return cellState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indoor BSP returned OK — no wall collision. ContactPlane
|
||||||
|
// is RETAINED from the prior tick's seed
|
||||||
|
// (PhysicsEngine.ResolveWithTransition:583, the
|
||||||
|
// init_contact_plane equivalent) OR refreshed by Path 3
|
||||||
|
// step-down / Path 4 land if those fired this tick. Either
|
||||||
|
// way, no synthesis is needed here — matches retail's
|
||||||
|
// BSPTREE::find_collisions OK path
|
||||||
|
// (acclient_2013_pseudo_c.txt:323938).
|
||||||
|
//
|
||||||
|
// Do NOT fall through to outdoor terrain backstop: the
|
||||||
|
// player is in an indoor cell, and the outdoor terrain
|
||||||
|
// Z is below the indoor floor by ~0.02m (the render Z-bump),
|
||||||
|
// which would mark the player as airborne and trigger the
|
||||||
|
// falling-animation stuck symptom (the original Bug A).
|
||||||
|
// 2026-05-20 slice 2 of indoor ContactPlane retention.
|
||||||
|
return TransitionState.OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Build to verify the source still compiles**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
dotnet build -c Debug 2>&1 | tail -5
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Build succeeded.` with 0 errors. (The `TryFindIndoorWalkablePlane` method is still defined; we haven't removed it yet. It just has no callers now, which is a warning at most.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 2: Delete the orphan `TryFindIndoorWalkablePlane` method + constant
|
||||||
|
|
||||||
|
After Task 1, `TryFindIndoorWalkablePlane` has no production callers. Tests in `IndoorWalkablePlaneTests.cs` and `TransitionTypesTests.cs` still reference it — they will be deleted in Task 3. For now, the build will go RED after this task and recover in Task 3.
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `src/AcDream.Core/Physics/TransitionTypes.cs` (about lines 1269-1381).
|
||||||
|
|
||||||
|
- [ ] **Step 1: Read the method + constant block**
|
||||||
|
|
||||||
|
Run Read on `src/AcDream.Core/Physics/TransitionTypes.cs` with offset=1268 and limit=115. Confirm the block from the `/// <summary>` doc-comment opening `TryFindIndoorWalkablePlane`, through the method body, through the `INDOOR_WALKABLE_PROBE_DISTANCE` constant + its doc-comment, ends at the blank line before the `/// <summary>` doc-comment for `FindEnvCollisions`.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Apply the Edit**
|
||||||
|
|
||||||
|
Use the Edit tool. The `old_string` is the entire method + constant block (lines about 1269-1381). The `new_string` is empty (just a single blank line to keep the file structure clean between the `Fmt` helper above and the `Environment collision` section header).
|
||||||
|
|
||||||
|
OLD_STRING starts with this line:
|
||||||
|
```
|
||||||
|
/// <summary>
|
||||||
|
/// Synthesize the indoor walkable contact plane for the player's current
|
||||||
|
```
|
||||||
|
|
||||||
|
and ends with this line:
|
||||||
|
```
|
||||||
|
private const float INDOOR_WALKABLE_PROBE_DISTANCE = 0.5f;
|
||||||
|
```
|
||||||
|
|
||||||
|
Read the file FIRST (Step 1 above) to capture the exact bytes between those two markers, then paste them as `old_string`.
|
||||||
|
|
||||||
|
NEW_STRING:
|
||||||
|
```
|
||||||
|
```
|
||||||
|
|
||||||
|
(empty — just delete the block entirely. The `// Environment collision — outdoor terrain` section header at about line 1265 sits directly above the deleted region; after deletion it will sit directly above the `FindEnvCollisions` doc-comment, which is the correct placement.)
|
||||||
|
|
||||||
|
- [ ] **Step 3: Build to confirm source-only orphaned helper is gone**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
dotnet build -c Debug src/AcDream.Core/AcDream.Core.csproj 2>&1 | tail -5
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Build succeeded.` with 0 errors in `AcDream.Core.csproj`. (`AcDream.Core.Tests.csproj` will fail to build at this point — the test files still reference `TryFindIndoorWalkablePlane`. That's intentional; Task 3 fixes it.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 3: Delete the obsolete test files
|
||||||
|
|
||||||
|
The two test files in `tests/AcDream.Core.Tests/Physics/` exist solely to cover `Transition.TryFindIndoorWalkablePlane`. With the method deleted, the tests are dead code. Delete both files outright.
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Delete: `tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs`
|
||||||
|
- Delete: `tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs`
|
||||||
|
|
||||||
|
- [ ] **Step 1: Confirm the file contents are TryFindIndoorWalkablePlane-only**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
grep -c 'TryFindIndoorWalkablePlane' tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: both files have non-zero matches (confirming they touch the deleted method). If either has 0 matches, STOP and investigate — that file is not what the spec assumed.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Delete the files**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
git rm tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
```
|
||||||
|
rm 'tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs'
|
||||||
|
rm 'tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs'
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Build to confirm both projects compile**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
dotnet build -c Debug 2>&1 | tail -5
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Build succeeded.` with 0 errors across all projects. If there's still a build failure pointing at `TryFindIndoorWalkablePlane`, search the codebase for any other reference:
|
||||||
|
```
|
||||||
|
grep -rn 'TryFindIndoorWalkablePlane' src tests
|
||||||
|
```
|
||||||
|
|
||||||
|
(should return 0 results after Tasks 1-3 are complete).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 4: Run the physics test suite, confirm baseline holds
|
||||||
|
|
||||||
|
After deletion, the test count drops by 9 (the 9 deleted tests). The 6 pre-existing physics failures (3 MotionInterpreter + 2 BSPStepUp + 1 PositionManager) should still be the only failures.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Run physics tests**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj -c Debug --no-build --nologo --filter "FullyQualifiedName~Physics"
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected (the failing count should match the pre-existing baseline of 6):
|
||||||
|
```
|
||||||
|
Failed! - Failed: 6, Passed: ...(around 398-402), Skipped: 0, Total: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
If you see 7+ failures or any failure name NOT in this set, STOP and investigate:
|
||||||
|
```
|
||||||
|
AcDream.Core.Tests.Physics.MotionInterpreterTests.GetMaxSpeed_WalkForward_ReturnsWalkAnimSpeed
|
||||||
|
AcDream.Core.Tests.Physics.MotionInterpreterTests.GetMaxSpeed_Idle_ReturnsZero
|
||||||
|
AcDream.Core.Tests.Physics.MotionInterpreterTests.GetMaxSpeed_WalkBackward_ReturnsWalkAnimSpeedTimesBackwardsFactor
|
||||||
|
AcDream.Core.Tests.Physics.BSPStepUpTests.C3_Path6_AirborneMoverHitsSteepSlope_SetsCollide
|
||||||
|
AcDream.Core.Tests.Physics.BSPStepUpTests.D4_AirborneMover_TallWall_PersistsSlidingNormalAcrossFrames
|
||||||
|
AcDream.Core.Tests.Physics.PositionManagerTests.ComputeOffset_BothActive_Combined
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Run the full Core test suite for good measure**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj -c Debug --no-build --nologo
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: 8 failed total (the 6 physics above + the 2 non-physics ones from the broader 1126-test suite). If the broader suite shows new failures, investigate.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 5: Commit the change (single commit per spec)
|
||||||
|
|
||||||
|
The spec calls for a single commit covering the synthesis removal + method deletion + test deletion.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Stage all changes**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
git add src/AcDream.Core/Physics/TransitionTypes.cs
|
||||||
|
git add -u tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs
|
||||||
|
git status
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected `git status`:
|
||||||
|
```
|
||||||
|
Changes to be committed:
|
||||||
|
modified: src/AcDream.Core/Physics/TransitionTypes.cs
|
||||||
|
deleted: tests/AcDream.Core.Tests/Physics/IndoorWalkablePlaneTests.cs
|
||||||
|
deleted: tests/AcDream.Core.Tests/Physics/TransitionTypesTests.cs
|
||||||
|
```
|
||||||
|
|
||||||
|
If the test files were removed via `git rm` in Task 3 they should already be staged; `git add -u` just ensures any straggler is captured.
|
||||||
|
|
||||||
|
- [ ] **Step 2: Commit with the spec's commit message**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
git commit -m "fix(physics): remove per-frame indoor walkable-plane synthesis
|
||||||
|
|
||||||
|
The indoor branch of FindEnvCollisions called Transition.TryFindIndoorWalkablePlane
|
||||||
|
every frame to re-synthesize the ContactPlane after BSP returned OK.
|
||||||
|
The synthesis routed through BSPQuery.FindWalkableSphere -> walkable_hits_sphere,
|
||||||
|
which correctly rejects tangent contact via |dist| > radius - epsilon. For a
|
||||||
|
grounded player standing on or brushing a floor, the foot sphere is
|
||||||
|
tangent: 99.87% MISS rate per the 2026-05-20 [cp-write] probe.
|
||||||
|
Each MISS fell through to outdoor terrain backstop, writing a
|
||||||
|
ContactPlane that's below the indoor floor by ~0.02m, marking the
|
||||||
|
player airborne and triggering the falling-animation stuck symptom.
|
||||||
|
|
||||||
|
Fix: delete the synthesis + outdoor-fallthrough from the indoor OK
|
||||||
|
path. ContactPlane is retained from the prior tick's seed
|
||||||
|
(PhysicsEngine.ResolveWithTransition:583, init_contact_plane equivalent)
|
||||||
|
or refreshed by BSP Path 3 / Path 4 during the same tick. Matches
|
||||||
|
retail's BSPTREE::find_collisions OK path
|
||||||
|
(acclient_2013_pseudo_c.txt:323938).
|
||||||
|
|
||||||
|
Also deletes:
|
||||||
|
- Transition.TryFindIndoorWalkablePlane (~80 lines)
|
||||||
|
- INDOOR_WALKABLE_PROBE_DISTANCE constant
|
||||||
|
- [indoor-walkable] probe log line
|
||||||
|
- IndoorWalkablePlaneTests.cs (8 tests, the helper's coverage)
|
||||||
|
- TransitionTypesTests.cs (1 test, also tested the helper)
|
||||||
|
|
||||||
|
Net: ~-480 lines. BSPQuery.FindWalkableSphere + its 5 tests retained
|
||||||
|
as the underlying retail-faithful walkable-finder API.
|
||||||
|
|
||||||
|
Closes Bug A in the indoor ContactPlane retention phase.
|
||||||
|
Spec: docs/superpowers/specs/2026-05-20-indoor-walkable-synthesis-removal-design.md.
|
||||||
|
Predecessor: de8ffde (Bug B, BSP world-origin fix).
|
||||||
|
|
||||||
|
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Verify commit landed**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
git log --oneline -7
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: top of log shows the new fix commit, followed by `3bec18f` (Bug A spec), `de8ffde` (Bug B fix), `39d4e65` (Bug B regression test), `56816fc` (Bug B plan), `865634f` (Bug B spec), `66de00d` ([cp-write] probe).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Task 6: Hand off to user for visual verification
|
||||||
|
|
||||||
|
The fix's primary acceptance test is visual: the user walks the 5 scenarios with the probes enabled and reports whether the stuck-falling symptom is gone.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Close any stale acdream client process**
|
||||||
|
|
||||||
|
Run:
|
||||||
|
```
|
||||||
|
$proc = Get-Process -Name AcDream.App -ErrorAction SilentlyContinue
|
||||||
|
if ($proc) {
|
||||||
|
$proc.CloseMainWindow() | Out-Null
|
||||||
|
$proc.WaitForExit(5000) | Out-Null
|
||||||
|
}
|
||||||
|
Start-Sleep -Seconds 3
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Launch the probed build in the background**
|
||||||
|
|
||||||
|
Run as a PowerShell command with `run_in_background: true`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call"
|
||||||
|
$env:ACDREAM_LIVE = "1"
|
||||||
|
$env:ACDREAM_TEST_HOST = "127.0.0.1"
|
||||||
|
$env:ACDREAM_TEST_PORT = "9000"
|
||||||
|
$env:ACDREAM_TEST_USER = "testaccount"
|
||||||
|
$env:ACDREAM_TEST_PASS = "testpassword"
|
||||||
|
$env:ACDREAM_DEVTOOLS = "1"
|
||||||
|
$env:ACDREAM_PROBE_INDOOR_BSP = "1"
|
||||||
|
$env:ACDREAM_PROBE_CONTACT_PLANE = "1"
|
||||||
|
dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Debug *>&1 | Tee-Object -FilePath "launch-buga-postfix.log"
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 3: Tell the user to walk the 5 scenarios + close**
|
||||||
|
|
||||||
|
Tell the user:
|
||||||
|
|
||||||
|
> Bug A fix landed. Launch is in the background. Please walk these 5 scenarios (about 30 seconds each):
|
||||||
|
>
|
||||||
|
> 1. **Cottage entry** (outdoor to indoor).
|
||||||
|
> 2. **Indoor standstill** about 10 seconds. Acceptance: stable, no flicker.
|
||||||
|
> 3. **2nd-floor walking** (the one that was broken). Acceptance: no stuck-falling when brushing upper floor edges.
|
||||||
|
> 4. **Cellar descent**.
|
||||||
|
> 5. **Single-floor cottage walk** (M1 regression check).
|
||||||
|
>
|
||||||
|
> Close the window when done.
|
||||||
|
|
||||||
|
- [ ] **Step 4: Read + analyze the post-fix log**
|
||||||
|
|
||||||
|
When the user reports the window is closed (or the background command notification arrives), convert and grep the log:
|
||||||
|
|
||||||
|
```
|
||||||
|
Get-Content launch-buga-postfix.log -Encoding Unicode | Out-File launch-buga-postfix.utf8.log -Encoding utf8
|
||||||
|
```
|
||||||
|
|
||||||
|
Then in Bash:
|
||||||
|
```
|
||||||
|
echo "=== [cp-write] caller distribution (post-Bug-A) ==="
|
||||||
|
grep -oE 'caller=[A-Za-z_.:0-9]+' launch-buga-postfix.utf8.log | sort | uniq -c | sort -rn | head -15
|
||||||
|
echo ""
|
||||||
|
echo "=== [indoor-walkable] lines (expect ZERO) ==="
|
||||||
|
grep -c '\[indoor-walkable\]' launch-buga-postfix.utf8.log
|
||||||
|
echo ""
|
||||||
|
echo "=== Transition.ValidateWalkable cp-writes (expect dramatic drop) ==="
|
||||||
|
grep -c 'caller=Transition\.ValidateWalkable' launch-buga-postfix.utf8.log
|
||||||
|
echo ""
|
||||||
|
echo "=== indoor-bsp result distribution ==="
|
||||||
|
grep -oE '\[indoor-bsp\].*result=[A-Z]+' launch-buga-postfix.utf8.log | grep -oE 'result=[A-Z]+' | sort | uniq -c
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected:
|
||||||
|
- `[indoor-walkable]` count: **0** (the probe line was deleted).
|
||||||
|
- `Transition.ValidateWalkable` cp-write count: dramatic drop from the pre-fix 370 (pre-Bug-B saw 224+146 from indoor synthesis HIT path + outdoor fallthrough). Post-Bug-A should see only the outdoor terrain calls that legitimately fire when the player IS outdoors, perhaps tens of calls.
|
||||||
|
- BSP `FindCollisions:1615` + `StepSphereDown:1123` (Path 3 + 4 BSP-internal writes): unchanged or similar to post-Bug-B counts. These are the legitimate retail-path CP writers.
|
||||||
|
- `PhysicsEngine.ResolveWithTransition:583`: unchanged (per-tick seed still fires).
|
||||||
|
|
||||||
|
- [ ] **Step 5: Deliver the assessment to the user**
|
||||||
|
|
||||||
|
Tell the user one of the following based on their visual report:
|
||||||
|
|
||||||
|
**Success path:**
|
||||||
|
> Visual verification clean. `[indoor-walkable]` probe gone (expected — deleted). `Transition.ValidateWalkable` cp-write count dropped from 370 to N. Stuck-falling symptom resolved per user report. Bug A closed. Indoor ContactPlane retention phase complete (2 slices: Bug B [world-origin], Bug A [synthesis removal]).
|
||||||
|
|
||||||
|
**Partial success (Bug A resolves stuck-falling, but a new "one-frame flicker" appears on outdoor->indoor transitions or after teleport):**
|
||||||
|
> Visual verification mostly clean, but a one-frame flicker on outdoor->indoor transitions. This is R2 (spec section) — acceptable for now. File as follow-up issue if it becomes annoying.
|
||||||
|
|
||||||
|
**Failure path (stuck-falling persists):**
|
||||||
|
> Visual verification shows stuck-falling unchanged. Hypothesis was wrong — the per-frame synthesis was not the dominant cause, or there's a deeper issue with the OK-path retention. Investigate by adding a `[ci-cp-final]` probe at the bottom of `FindTransitionalPosition` to capture what `ci.CP` actually IS when the resolver finishes the OK case. Hand off as a separate session.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Self-Review
|
||||||
|
|
||||||
|
Run after writing this plan:
|
||||||
|
|
||||||
|
**1. Spec coverage:**
|
||||||
|
- Spec section "Fix > Code changes" → Tasks 1 (synthesis call) + 2 (method + constant deletion). Covered.
|
||||||
|
- Spec section "Fix > Test changes" → Task 3. Covered.
|
||||||
|
- Spec section "Acceptance criteria > Probe-equivalence" → Task 6 step 4. Covered.
|
||||||
|
- Spec section "Acceptance criteria > Visual verification" → Task 6 steps 2-3. Covered.
|
||||||
|
- Spec section "Acceptance criteria > M1-baseline regression check" → Task 6 step 3 scenario 5. Covered.
|
||||||
|
- Spec section "Risks" → R1/R2/R3 mitigations live as falsification language in Task 6 step 5. R4 is "decision noted in spec, no action needed."
|
||||||
|
- Spec section "Out of scope" → not implemented. Acceptable.
|
||||||
|
|
||||||
|
**2. Placeholder scan:** No TBD/TODO. Every step has concrete commands + expected output.
|
||||||
|
|
||||||
|
**3. Type consistency:** No new types introduced; everything is a deletion. Existing names (`TryFindIndoorWalkablePlane`, `INDOOR_WALKABLE_PROBE_DISTANCE`, `FindEnvCollisions`, `BSPQuery.FindWalkableSphere`) are spelled consistently.
|
||||||
|
|
||||||
|
**4. Build-order discipline:** Task 1 leaves source-only code compiling (helper has no callers but still defined). Task 2 deletes the helper, breaking the test build. Task 3 deletes the tests, restoring build green. Task 4 confirms baseline. The temporary RED state between Tasks 2 and 3 is intentional and noted in Task 2 Step 3.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue