diag(phys): [bsp-test] probe + grounded apparatus test + handoff
Visual verification of Task 7 ship: doors block at dead-center (the small Cylinder catches) but the BSP slab doesn't catch off-center or inside-walking-out approaches. Probe-instrumented live capture proves multi-part registration is correct — every door spawns with shapes=cyl1+bsp1, and the BSP part is visited 135 times for a single door at player approaches as close as 0.42 m, with cacheHit=True. But zero [resolve-bldg] attributions for the BSP shape. Three artifacts added: 1. TransitionTypes.cs — new [bsp-test] probe in the BSP collision dispatch, fires BEFORE the cache lookup. Mirrors [cyl-test] on the Cylinder branch. Distinguishes "cache miss → silent skip" from "queried but no hit" (the latter doesn't show up in [resolve-bldg] which only fires on attributed hits). 2. DoorCollisionApparatusTests.cs — new grounded test (Apparatus_Grounded_50cmOffCenter_*) attempts to reproduce the production bug via a seeded PhysicsBody (Contact + OnWalkable + ContactPlane + WalkablePolygon). Currently doesn't reproduce because the apparatus's stub-terrain + synthetic-floor setup diverges from production's real Holtburg geometry. Captured as "documents-the-bug" — flip the assertion shape when the fix lands. 3. docs/research/2026-05-24-door-collision-task7-shipped-but-bug-remains.md — full session handoff. Identifies the remaining bug as a Path 5 (Contact branch + StepSphereUp) misbehavior at thin tall obstacles, not in the multi-part registration we just shipped. Leading hypothesis: DoStepUp's downward probe finds the same flat floor on the OTHER side of the door (Holtburg cottages have no Z change between exterior and interior floor), declares step-up success, BSP collision returns OK, sphere walks through. Recommended next move: relaunch with ACDREAM_DUMP_STEPUP=1 to verify the hypothesis. What this commit DOES NOT do: fix the remaining step-up bug. The A6.P4 multi-part registration foundation is correct and stays. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ca9341c2cb
commit
163a1f0d35
3 changed files with 360 additions and 0 deletions
|
|
@ -0,0 +1,247 @@
|
||||||
|
# Door collision — Task 7 shipped, partial fix, deeper bug remains
|
||||||
|
|
||||||
|
**Date:** 2026-05-24 (evening, continuation of door collision investigation)
|
||||||
|
**Branch:** `claude/strange-albattani-3fc83c`
|
||||||
|
**Status:** A6.P4 architecture is correct. Multi-part registration works.
|
||||||
|
The Holtburg door bug PARTIALLY fixed — center blocks, but off-center
|
||||||
|
and inside-out still walk through. Root cause is downstream in the
|
||||||
|
engine's grounded BSP collision path (Path 5 + step-up), NOT in the
|
||||||
|
multi-part registration we just shipped.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
**Three commits shipped** (composable foundation):
|
||||||
|
|
||||||
|
| SHA | Title | What it does |
|
||||||
|
|---|---|---|
|
||||||
|
| `e1d94d7` | dat-inspection test | Confirmed door part `0x010044B5` has full 1.9×0.26×2.5 m BSP slab (6 Landblock polys). Hypothesis A from prior handoff was wrong. |
|
||||||
|
| `3b7dc46` | `GetNearbyObjects` dedup fix | Changed `HashSet<uint>` (entityId) → `HashSet<ShadowEntry>`. Multi-part shapes no longer silently dropped. |
|
||||||
|
| `ca9341c` | Task 7 live wiring | `RegisterLiveEntityCollision` uses `ShadowShapeBuilder.FromSetup` + `RegisterMultiPart`. Doors now register cyl+bsp instead of just cyl. |
|
||||||
|
|
||||||
|
**Live verification (visual user test):**
|
||||||
|
|
||||||
|
| Scenario | Result |
|
||||||
|
|---|---|
|
||||||
|
| Dead center, walk into closed door (outside) | ✅ Blocks |
|
||||||
|
| 50 cm off-center, walk into closed door (outside) | ❌ Walks through |
|
||||||
|
| Inside walking out (closed door) | ❌ Walks through |
|
||||||
|
| Use door → swing → walk through | ✅ Works (ETHEREAL flip path) |
|
||||||
|
|
||||||
|
**Probe-instrumented live capture confirms multi-part registration works:**
|
||||||
|
|
||||||
|
- Every door spawn shows `[entity-source] shapes=cyl1+bsp1` — both shapes register.
|
||||||
|
- BSP part `0x010044B5` is visited 135 times for a single door at player approaches as close as `distXY=0.415 m`.
|
||||||
|
- `cacheHit=True` for every visit — the cache is populated.
|
||||||
|
- BUT: zero `[resolve-bldg]` attributions for the BSP shape (all 19 attributed hits show `gfxObj=0x00000000` = the Cylinder shape).
|
||||||
|
|
||||||
|
So the BSP is being QUERIED but never produces an attributed hit. The
|
||||||
|
sphere walks through despite the BSP geometry being present and
|
||||||
|
visited.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What's in the tree right now
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git log --oneline -8
|
||||||
|
ca9341c feat(phys): A6.P4 Task 7 — RegisterLiveEntityCollision uses ShadowShapeBuilder + RegisterMultiPart
|
||||||
|
3b7dc46 fix(phys): GetNearbyObjects dedup-by-entityId silently drops multi-part shadows
|
||||||
|
e1d94d7 test(phys): door setup + GfxObj dat-inspection — Hypothesis A falsified
|
||||||
|
c89df8e docs(handoff): door collision per-part BSP session handoff (2026-05-24)
|
||||||
|
1498697 diag(phys): [cyl-test] probe — log every Cylinder shadow collision test
|
||||||
|
3e5dc8c test(phys): Task 6 regression — Deregister clears _entityShapes cache
|
||||||
|
d5ffb03 feat(phys): UpdatePosition handles multi-part entities
|
||||||
|
fca0a13 feat(phys): ShadowObjectRegistry.RegisterMultiPart
|
||||||
|
```
|
||||||
|
|
||||||
|
**Uncommitted (to commit next):**
|
||||||
|
- `src/AcDream.Core/Physics/TransitionTypes.cs` — new `[bsp-test]` probe in
|
||||||
|
the BSP collision dispatch, mirrors `[cyl-test]`. Fires when a BSP entry
|
||||||
|
is visited, BEFORE the cache lookup. Distinguishes "cache miss → silent
|
||||||
|
skip" from "queried but no hit." Gated on `ACDREAM_PROBE_BUILDING=1`.
|
||||||
|
- `tests/AcDream.Core.Tests/Physics/DoorCollisionApparatusTests.cs` —
|
||||||
|
new test `Apparatus_Grounded_50cmOffCenter_FrontApproach_DocumentsBug`
|
||||||
|
that attempts to reproduce the production bug with a grounded body +
|
||||||
|
seeded ContactPlane. Currently fails because the apparatus's behavior
|
||||||
|
diverges from production (apparatus blocks immediately at tick 0 with
|
||||||
|
a Z+ normal from the synthetic floor; production walks through).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Path 5 vs Path 6 — the divergence
|
||||||
|
|
||||||
|
`BSPQuery.FindCollisions` dispatches to 6 paths based on `ObjectInfo`
|
||||||
|
state. The crucial difference:
|
||||||
|
|
||||||
|
- **Path 6 (Default)** — fires when `obj.State` has no `Contact` flag.
|
||||||
|
Calls `SphereIntersectsPolyInternal` and `SetCollide` on hit.
|
||||||
|
**Apparatus tests use this path** (no body, `isOnGround=false`). They
|
||||||
|
all PASS — the door's BSP blocks the sphere correctly.
|
||||||
|
|
||||||
|
- **Path 5 (Contact branch)** — fires when `obj.State.HasFlag(Contact)`.
|
||||||
|
Calls `SphereIntersectsPolyInternal`; on hit, calls
|
||||||
|
`StepSphereUp → DoStepUp → DoStepDown` to attempt climbing over the
|
||||||
|
obstacle. Returns OK if step succeeds, Slid if step fails.
|
||||||
|
**Production uses this path** (player grounded → `isOnGround=true` →
|
||||||
|
engine sets `Contact` flag at `PhysicsEngine.cs:631`). Production
|
||||||
|
WALKS THROUGH.
|
||||||
|
|
||||||
|
So the bug is somewhere in Path 5's step-up logic. The leading
|
||||||
|
hypothesis (not yet proven):
|
||||||
|
|
||||||
|
> When the player is standing on flat ground in front of the door,
|
||||||
|
> step-up's `DoStepDown` probes 0.6 m downward from the sphere's
|
||||||
|
> current position. It finds the SAME flat ground extending to the
|
||||||
|
> OTHER SIDE of the door (Holtburg cottages have no Z change between
|
||||||
|
> exterior and interior floor — both at Z=94). `find_walkable`
|
||||||
|
> declares step-up SUCCESS, the BSP collision returns `OK`, and the
|
||||||
|
> sphere walks through the door.
|
||||||
|
>
|
||||||
|
> The fix probably involves: step-up should reject if a forward probe
|
||||||
|
> at the lifted height STILL hits the same obstacle. The current
|
||||||
|
> DoStepDown probes only DOWNWARD; it doesn't verify that the
|
||||||
|
> forward motion at the lifted height is clear.
|
||||||
|
|
||||||
|
This is speculation — needs apparatus verification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why the apparatus didn't reproduce the bug
|
||||||
|
|
||||||
|
The grounded apparatus test (`Apparatus_Grounded_50cmOffCenter_*`) was
|
||||||
|
supposed to fail in the same way as production (walk through). Instead
|
||||||
|
it BLOCKED at tick 0 with normal=(0,0,1) — sphere position unchanged.
|
||||||
|
|
||||||
|
Diagnostic output:
|
||||||
|
```
|
||||||
|
[bsp-test] obj=0x000F424F gfx=0x010044B5 ... pos=(11.99,12.12,1.27)
|
||||||
|
distXY=1.234 cacheHit=True
|
||||||
|
[resolve] in=(12.500,11.000,0.480) tgt=(12.500,11.100,0.480)
|
||||||
|
out=(12.500,11.000,0.480) ok=True hit=yes n=(0,0,1) walkable=True
|
||||||
|
```
|
||||||
|
|
||||||
|
`ACDREAM_DUMP_STEPUP=1` produced no `stepup: ENTER` lines, so
|
||||||
|
`DoStepUp` was NOT called. The hit normal `(0,0,1)` came from
|
||||||
|
somewhere else (likely the seeded walkable polygon or the synthetic
|
||||||
|
floor interaction with the engine's terrain step-down).
|
||||||
|
|
||||||
|
The apparatus's stub terrain (Z=-1000) + synthetic walkable poly at
|
||||||
|
Z=0 may be causing the engine to take a different code path than
|
||||||
|
production's real Holtburg terrain. Reproducing production fully
|
||||||
|
would require:
|
||||||
|
|
||||||
|
1. Real terrain heightmap covering the test landblock at Z=94
|
||||||
|
2. EnvCell or stab geometry near the test door
|
||||||
|
3. Proper cottage/cell setup so portal-reachable cells include
|
||||||
|
the door's outdoor cell when player is indoor
|
||||||
|
|
||||||
|
This is significant apparatus investment. Worth it IF the bug
|
||||||
|
requires multi-tick simulation in real geometry to surface. For
|
||||||
|
now, the apparatus shows the broad shape: with proper grounded
|
||||||
|
state + seeded body, the engine doesn't take the same path as
|
||||||
|
the airborne (Path 6) test.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommended next steps (ranked)
|
||||||
|
|
||||||
|
### Option A — Live diagnostic with ACDREAM_DUMP_STEPUP=1 (cheapest)
|
||||||
|
|
||||||
|
Relaunch with `ACDREAM_PROBE_BUILDING=1` + `ACDREAM_DUMP_STEPUP=1`.
|
||||||
|
Walk into a closed door off-center. The step-up dump will show:
|
||||||
|
- Whether `DoStepUp` fires at all when the BSP hits
|
||||||
|
- If so, what the input normal is
|
||||||
|
- Whether `stepDown` succeeds or fails
|
||||||
|
|
||||||
|
If `stepDown` succeeds (i.e., step-up climbs over the door), we've
|
||||||
|
confirmed the hypothesis above and can target the fix.
|
||||||
|
|
||||||
|
### Option B — Build a richer apparatus
|
||||||
|
|
||||||
|
Replace the stub terrain with a real heightmap-like surface at Z=94
|
||||||
|
spanning the test landblock. Replace the synthetic walkable poly with
|
||||||
|
a proper terrain polygon at the door's world XY. This should let
|
||||||
|
Path 5 run the SAME way as production. Then iterate on the fix
|
||||||
|
locally in <500 ms.
|
||||||
|
|
||||||
|
Estimated effort: 1-2 hours of apparatus work.
|
||||||
|
|
||||||
|
### Option C — Direct retail cdb trace
|
||||||
|
|
||||||
|
Attach cdb to a running retail client at a Holtburg cottage doorway,
|
||||||
|
break on `CTransition::step_up` or `CTransition::step_down`, and
|
||||||
|
observe how retail handles step-up against a door. Compare against
|
||||||
|
acdream's behavior.
|
||||||
|
|
||||||
|
Estimated effort: 30 min - 2 hours depending on what we find.
|
||||||
|
|
||||||
|
### Option D — Pivot to fix-and-verify
|
||||||
|
|
||||||
|
Hypothesis-based fix: in `DoStepUp`, reject step-up if the input
|
||||||
|
collision normal is mostly horizontal AND the obstacle's bounding
|
||||||
|
sphere height range significantly exceeds the step-up height. The
|
||||||
|
door has BS radius 1.975 m centered at Z=1.275 → top of BS at Z=3.25,
|
||||||
|
way above step-up=0.6. If we detect "this obstacle is too tall to
|
||||||
|
step over," fall back to wall-slide.
|
||||||
|
|
||||||
|
Risk: might break stairs / ramps. Need apparatus to verify.
|
||||||
|
|
||||||
|
### Recommendation
|
||||||
|
|
||||||
|
Option A first (~5 min, no code changes needed). If hypothesis
|
||||||
|
confirmed, then Option D (with apparatus from Option B for
|
||||||
|
regression testing).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files touched this session (cumulative)
|
||||||
|
|
||||||
|
**Committed:**
|
||||||
|
- `src/AcDream.Core/Physics/ShadowObjectRegistry.cs` (dedup fix)
|
||||||
|
- `src/AcDream.App/Rendering/GameWindow.cs` (Task 7 wiring)
|
||||||
|
- `tests/AcDream.Core.Tests/Physics/DoorSetupGfxObjInspectionTests.cs` (NEW)
|
||||||
|
- `tests/AcDream.Core.Tests/Physics/DoorCollisionApparatusTests.cs` (NEW)
|
||||||
|
- `docs/research/2026-05-24-door-dat-inspection-findings.md` (NEW)
|
||||||
|
|
||||||
|
**Uncommitted (this doc + 2 file changes):**
|
||||||
|
- `src/AcDream.Core/Physics/TransitionTypes.cs` (added `[bsp-test]` probe)
|
||||||
|
- `tests/AcDream.Core.Tests/Physics/DoorCollisionApparatusTests.cs`
|
||||||
|
(added grounded test scenario — fails for unrelated apparatus
|
||||||
|
reasons but the probe wiring is sound)
|
||||||
|
|
||||||
|
**Memory updated:** `feedback_dedup_keys_after_cardinality_change.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pickup prompt for next session
|
||||||
|
|
||||||
|
```
|
||||||
|
A6.P4 Task 7 shipped (RegisterLiveEntityCollision uses
|
||||||
|
ShadowShapeBuilder + RegisterMultiPart) and the foundation fix
|
||||||
|
(GetNearbyObjects dedup on full ShadowEntry instead of entityId).
|
||||||
|
Production verification: center blocks, but off-center + inside-out
|
||||||
|
still walk through closed doors. The multi-part registration is
|
||||||
|
correct (verified by live probes); the remaining bug is downstream
|
||||||
|
in BSPQuery Path 5's step-up logic.
|
||||||
|
|
||||||
|
Read docs/research/2026-05-24-door-collision-task7-shipped-but-bug-remains.md
|
||||||
|
|
||||||
|
State both altitudes:
|
||||||
|
Currently working toward: M1.5 — Indoor world feels right
|
||||||
|
Current phase: A6.P4 door collision — step-up misbehavior
|
||||||
|
investigation. Multi-part registration shipped;
|
||||||
|
step-up at thin tall obstacles is the remaining bug.
|
||||||
|
|
||||||
|
Recommended first move: Option A from the findings doc — relaunch
|
||||||
|
with ACDREAM_PROBE_BUILDING=1 + ACDREAM_DUMP_STEPUP=1, walk into
|
||||||
|
a Holtburg cottage door off-center. The step-up dump will reveal
|
||||||
|
whether DoStepUp is incorrectly succeeding for the door's BSP slab
|
||||||
|
hit (the leading hypothesis: DoStepDown finds the same flat floor
|
||||||
|
on the other side of the door, declaring step-up success).
|
||||||
|
|
||||||
|
DO NOT re-investigate the multi-part registration or GetNearbyObjects
|
||||||
|
dedup — both are confirmed working. Focus on the step-up path 5
|
||||||
|
behavior for thin tall obstacles.
|
||||||
|
```
|
||||||
|
|
@ -2254,6 +2254,21 @@ public sealed class Transition
|
||||||
// ── BSP object: use the full 6-path retail dispatcher ────
|
// ── BSP object: use the full 6-path retail dispatcher ────
|
||||||
// ACE: PhysicsObj.FindObjCollisions → Setup.BSP.find_collisions
|
// ACE: PhysicsObj.FindObjCollisions → Setup.BSP.find_collisions
|
||||||
var physics = engine.DataCache.GetGfxObj(obj.GfxObjId);
|
var physics = engine.DataCache.GetGfxObj(obj.GfxObjId);
|
||||||
|
|
||||||
|
// A6.P4 door investigation (2026-05-24): log every BSP shadow
|
||||||
|
// visit before the cache lookup so we distinguish "cache miss
|
||||||
|
// → silently skipped" from "queried but no hit" (only the
|
||||||
|
// latter shows up in [resolve-bldg], which fires only on
|
||||||
|
// attributed hits). Mirrors [cyl-test] on the Cylinder branch.
|
||||||
|
if (PhysicsDiagnostics.ProbeBuildingEnabled)
|
||||||
|
{
|
||||||
|
Vector3 dxy = obj.Position - sp.GlobalCurrCenter[0].Origin;
|
||||||
|
float distXY = MathF.Sqrt(dxy.X * dxy.X + dxy.Y * dxy.Y);
|
||||||
|
bool cacheHit = physics?.BSP?.Root is not null;
|
||||||
|
Console.WriteLine(System.FormattableString.Invariant(
|
||||||
|
$"[bsp-test] obj=0x{obj.EntityId:X8} gfx=0x{obj.GfxObjId:X8} state=0x{obj.State:X8} radius={obj.Radius:F3} pos=({obj.Position.X:F2},{obj.Position.Y:F2},{obj.Position.Z:F2}) distXY={distXY:F3} cacheHit={cacheHit}"));
|
||||||
|
}
|
||||||
|
|
||||||
if (physics?.BSP?.Root is null) continue;
|
if (physics?.BSP?.Root is null) continue;
|
||||||
|
|
||||||
// Transform player spheres to object-local space.
|
// Transform player spheres to object-local space.
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,104 @@ public class DoorCollisionApparatusTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reproduces the LIVE bug: a grounded player (isOnGround=true with
|
||||||
|
/// seeded ContactPlane) walking off-center toward a closed door
|
||||||
|
/// passes through. The path-difference test: this hits Path 5
|
||||||
|
/// (Contact branch + StepSphereUp), while the other apparatus
|
||||||
|
/// tests above hit Path 6 (Default). If Path 5 incorrectly
|
||||||
|
/// declares step-up success the BSP collision returns OK and the
|
||||||
|
/// sphere walks through — exactly what the user reports in the
|
||||||
|
/// live Holtburg session 2026-05-24.
|
||||||
|
/// </summary>
|
||||||
|
[Fact]
|
||||||
|
public void Apparatus_Grounded_50cmOffCenter_FrontApproach_DocumentsBug()
|
||||||
|
{
|
||||||
|
if (!TryBuildScenario(out var ctx)) return;
|
||||||
|
|
||||||
|
PhysicsDiagnostics.ProbeResolveEnabled = true;
|
||||||
|
PhysicsDiagnostics.ProbeBuildingEnabled = true;
|
||||||
|
Env.SetEnvironmentVariable("ACDREAM_DUMP_STEPUP", "1");
|
||||||
|
|
||||||
|
// Synthetic floor plane at Z = 0 so the grounded sphere has a
|
||||||
|
// walkable plane to rest on. Sphere foot center starts at Z=radius
|
||||||
|
// = 0.48, head at 0.48 + 1.20 = 1.68.
|
||||||
|
var floorPlane = new Plane(0f, 0f, 1f, 0f); // z = 0 plane
|
||||||
|
var floorVerts = new[]
|
||||||
|
{
|
||||||
|
new Vector3( 0f, 0f, 0f),
|
||||||
|
new Vector3(24f, 0f, 0f),
|
||||||
|
new Vector3(24f, 24f, 0f),
|
||||||
|
new Vector3( 0f, 24f, 0f),
|
||||||
|
};
|
||||||
|
|
||||||
|
var body = new PhysicsBody
|
||||||
|
{
|
||||||
|
Position = new Vector3(12.5f, 11f, 0.48f),
|
||||||
|
Orientation = Quaternion.Identity,
|
||||||
|
ContactPlaneValid = true,
|
||||||
|
ContactPlane = floorPlane,
|
||||||
|
ContactPlaneCellId = TestCellId,
|
||||||
|
WalkablePolygonValid = true,
|
||||||
|
WalkablePlane = floorPlane,
|
||||||
|
WalkableVertices = floorVerts,
|
||||||
|
WalkableUp = Vector3.UnitZ,
|
||||||
|
TransientState = TransientStateFlags.Contact | TransientStateFlags.OnWalkable,
|
||||||
|
};
|
||||||
|
|
||||||
|
var perTick = new Vector3(0f, 0.10f, 0f);
|
||||||
|
Vector3 pos = body.Position;
|
||||||
|
uint cellId = TestCellId;
|
||||||
|
bool isOnGround = true;
|
||||||
|
bool blocked = false;
|
||||||
|
Vector3 lastNormal = Vector3.Zero;
|
||||||
|
int ticks = 0;
|
||||||
|
|
||||||
|
for (int tick = 0; tick < 30; tick++)
|
||||||
|
{
|
||||||
|
Vector3 target = pos + perTick;
|
||||||
|
var result = ctx.engine.ResolveWithTransition(
|
||||||
|
pos, target, cellId,
|
||||||
|
SphereRadius, SphereHeight,
|
||||||
|
StepUpHeight, StepDownHeight,
|
||||||
|
isOnGround,
|
||||||
|
body: body,
|
||||||
|
moverFlags: ObjectInfoState.IsPlayer | ObjectInfoState.EdgeSlide,
|
||||||
|
movingEntityId: 0);
|
||||||
|
|
||||||
|
ticks = tick;
|
||||||
|
body.Position = result.Position;
|
||||||
|
pos = result.Position;
|
||||||
|
cellId = result.CellId;
|
||||||
|
isOnGround = result.IsOnGround;
|
||||||
|
lastNormal = result.CollisionNormal;
|
||||||
|
|
||||||
|
if (result.CollisionNormalValid)
|
||||||
|
{
|
||||||
|
blocked = true;
|
||||||
|
_out.WriteLine($"Tick {tick}: BLOCKED at pos=({pos.X:F3},{pos.Y:F3},{pos.Z:F3}) normal=({lastNormal.X:F3},{lastNormal.Y:F3},{lastNormal.Z:F3})");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_out.WriteLine($"Final pos = ({pos.X:F3}, {pos.Y:F3}, {pos.Z:F3}) after {ticks + 1} ticks; blocked={blocked}");
|
||||||
|
_out.WriteLine($"Grounded={isOnGround}");
|
||||||
|
|
||||||
|
// EXPECTED FAILURE (documents-the-bug): the grounded sphere walks
|
||||||
|
// straight through, reaching the far side at Y > 12.30. When the
|
||||||
|
// fix lands, flip this to Assert.True(blocked) — same shape as
|
||||||
|
// the Path-6 apparatus tests above.
|
||||||
|
PhysicsDiagnostics.ProbeResolveEnabled = false;
|
||||||
|
PhysicsDiagnostics.ProbeBuildingEnabled = false;
|
||||||
|
Env.SetEnvironmentVariable("ACDREAM_DUMP_STEPUP", null);
|
||||||
|
|
||||||
|
Assert.True(pos.Y > 12.30f,
|
||||||
|
$"This test documents the production bug. If this is failing " +
|
||||||
|
$"because the sphere now blocks, the door fix worked — flip " +
|
||||||
|
$"the assertion to Assert.True(blocked) and Assert.True(pos.Y < 12.0f). " +
|
||||||
|
$"Current pos=({pos.X:F3},{pos.Y:F3},{pos.Z:F3}) blocked={blocked}");
|
||||||
|
}
|
||||||
|
|
||||||
// ───────────────────────────────────────────────────────────────
|
// ───────────────────────────────────────────────────────────────
|
||||||
// Apparatus setup
|
// Apparatus setup
|
||||||
// ───────────────────────────────────────────────────────────────
|
// ───────────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue