docs: issue #101 — broken stairs cyl phantom (post-A6.P7 finding)
Visual verification of A6.P7 at Holtburg cottage door passed cleanly (1187 [cyl-skip-bsp] guard fires, 0 [cyl-test] on doors, 30/30 axis-aligned hits, smooth NE/SE slide along door face). While exploring post-verification, the user discovered a different staircase in cells 0xA9B40159 + 0xA9B4015A where the sphere cannot climb at all. Captured working baseline (stairs-working.jsonl, cottage cellar stairs in cells 0xA9B40143/146/147 — clean ↔ Z=90.95-94.00 traversal) and broken scenario (stairs-broken.jsonl, Z stays at 94.00 the entire 4216-record capture). Root cause is NOT a regression of A6.P7. It's a different bug shape: the staircase is built as a multi-part EnvCell entity (entityId 0x0040B500, ~150 parts), with 10 of those parts being 0.80m-radius cylinders forming the steps. Each cyl carries state=0x00000000 — no HAS_PHYSICS_BSP_PS — so A6.P7's BspOnlyDispatch guard correctly doesn't fire. Cyl height 0.80m exceeds A6.P6's step-up budget 0.60m so grounded step-over fails. Falls through to wall-slide which produces the same diagonal radial phantom A6.P7 closed for the door. The [resolve-bldg] lines reveal gfxObj=0x0100081A hasPhys=False bspR=0.00 vAabbR=0.82 — the underlying GfxObj has NO physics BSP; we appear to be synthesizing a cyl from the visual AABB radius. That synthesis path is the suspected misregistration. Filed as issue #101 with severity HIGH. Investigation handoff written covering 4 retail-research questions (cdb on retail at this stair location, Setup trace via entity-source probe, ShadowShapeBuilder vAabbR fallback audit, cell BSP poly dump), do-not-retry list, and 3 candidate fix shapes (don't synthesize cyl from vAabbR / cell BSP for stairs / cyl-height-tolerant step-over). The handoff explicitly defers implementation to a later session pending retail evidence. Files: - docs/research/2026-05-25-stairs-cyl-investigation-handoff.md (new) - docs/ISSUES.md — added #101 entry Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
888272aad1
commit
8795655250
2 changed files with 398 additions and 0 deletions
|
|
@ -761,6 +761,65 @@ family (sling-out — also likely).
|
|||
|
||||
---
|
||||
|
||||
## #101 — Stair-step cylinder phantom blocks player on multi-part EnvCell entity
|
||||
|
||||
**Status:** OPEN
|
||||
**Severity:** HIGH (M1.5 — blocks stair climbing in at least one Holtburg
|
||||
building; same symptom class as the just-closed A6.P7 door bug but
|
||||
different root cause)
|
||||
**Filed:** 2026-05-25
|
||||
**Component:** physics, dat-handling
|
||||
|
||||
**Description:** At a Holtburg staircase in cells `0xA9B40159` +
|
||||
`0xA9B4015A` (XY ≈ 110, 26; user-discovered post-A6.P7 visual
|
||||
verification), the player sphere cannot climb the stairs. Walking into
|
||||
the foot of the stairs from the east, the sphere hits a phantom slide
|
||||
with radial-cyl normals (e.g. `(0.88, -0.47, 0)`) and never gains
|
||||
altitude. Z stays at 94.00 for the entire 4216-record capture in
|
||||
`stairs-broken.jsonl`.
|
||||
|
||||
**Root cause / status:** The staircase is built as ~10 stacked cylinder
|
||||
parts of multi-part entity `entityId=0x0040B500`. Each cyl is
|
||||
`radius=0.80m, height=0.80m` at `Y=26.60`, stepping up in X+Z by 0.25m
|
||||
per step. All parts carry `state=0x00000000` — **no
|
||||
`HAS_PHYSICS_BSP_PS` flag**, so A6.P7's `Transition.BspOnlyDispatch`
|
||||
gate does NOT fire. Cyls are tested. Cyl height (0.80m) exceeds A6.P6's
|
||||
step-up budget (0.60m), so grounded step-over fails too. Falls through
|
||||
to wall-slide → diagonal radial normal → slide tangent driven into
|
||||
perpendicular cell wall → stuck.
|
||||
|
||||
The `[resolve-bldg]` lines show `gfxObj=0x0100081A hasPhys=False
|
||||
bspR=0.00 vAabbR=0.82` — the underlying `GfxObj` has NO physics BSP. We
|
||||
appear to be synthesizing a cyl from the visual AABB radius
|
||||
(`vAabbR=0.82` → registered as `r=0.80`). This synthesis path is the
|
||||
suspected mis-registration.
|
||||
|
||||
This is NOT a regression of A6.P7 (the cottage door works correctly
|
||||
post-A6.P7, visually verified). It's a separate bug shape that A6.P7's
|
||||
fix didn't address.
|
||||
|
||||
**Files:**
|
||||
- Captures: `stairs-broken.jsonl`, `stairs-broken.launch.log`,
|
||||
`stairs-working.jsonl`, `stairs-working.launch.log` (gitignored, on
|
||||
disk for the next session to read)
|
||||
- Suspected mis-registration: `src/AcDream.Core/Physics/ShadowShapeBuilder.cs::FromSetup`
|
||||
- Entity hydration site: `src/AcDream.App/Rendering/GameWindow.cs::BuildInteriorEntitiesForStreaming`
|
||||
|
||||
**Research:**
|
||||
- [`docs/research/2026-05-25-stairs-cyl-investigation-handoff.md`](research/2026-05-25-stairs-cyl-investigation-handoff.md)
|
||||
— full investigation handoff with 4 research questions, do-not-retry
|
||||
list, and 3 candidate fix shapes
|
||||
- A6.P7 background (closed companion):
|
||||
[`docs/research/2026-05-25-a6-door-cyl-retail-dispatch-investigation.md`](research/2026-05-25-a6-door-cyl-retail-dispatch-investigation.md)
|
||||
|
||||
**Acceptance:** Walking west into the broken staircase at cells
|
||||
`0xA9B40159` + `0xA9B4015A`, the player sphere ascends step-by-step to
|
||||
the top (Z=96.47), then can walk back down to the bottom (Z=94.22) — no
|
||||
phantom diagonal slide normals attributed to entity `0x0040B500`.
|
||||
Comparable trajectory to `stairs-working.jsonl` cellar-stairs baseline.
|
||||
|
||||
---
|
||||
|
||||
## #100 — Transparent rectangular patches around every house (terrain rendering)
|
||||
|
||||
**Status:** OPEN
|
||||
|
|
|
|||
339
docs/research/2026-05-25-stairs-cyl-investigation-handoff.md
Normal file
339
docs/research/2026-05-25-stairs-cyl-investigation-handoff.md
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
# M1.5 — Broken stairs (cyl-only multi-part entity) — investigation handoff
|
||||
|
||||
**Date:** 2026-05-25 PM
|
||||
**Status:** Filed as issue #101 (post-A6.P7 visual verification surfaced a NEW
|
||||
bug, not the closed door bug). **Research-only next session.** No
|
||||
implementation until we know what retail does at this exact stair location.
|
||||
**Predecessor handoff:** [`2026-05-25-a6-door-cyl-investigation-handoff.md`](2026-05-25-a6-door-cyl-investigation-handoff.md)
|
||||
(closed by A6.P7 commit `888272a`).
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
A6.P7 visual verification at Holtburg confirmed the cottage door is fixed.
|
||||
While exploring, the user found **a different staircase that doesn't work** —
|
||||
sphere can't climb at all. Captures show:
|
||||
|
||||
- Stairs are in cells `0xA9B40159` + `0xA9B4015A` (NOT the cottage-cellar
|
||||
cells `0xA9B40143/146/147` that work post-A6.P3 cellar fix).
|
||||
- Geometry is a **multi-part entity** `0x0040B500` (entityId; ~150 parts in
|
||||
the setup; 10 of them are stair-step cylinders).
|
||||
- Each step is a separate cylinder (`r=0.80m, h=0.80m`) at `Y=26.60`, stepping
|
||||
up in X and Z (0.25 m per step, Z: 94.22 → 96.47).
|
||||
- `state=0x00000000` on each cyl part — **no `HAS_PHYSICS_BSP_PS` flag**, so
|
||||
A6.P7's dispatch gate (`Transition.BspOnlyDispatch`) does NOT skip them.
|
||||
- The cyls fire 284 `result=Slid` with diagonal radial normals like
|
||||
`(0.88, -0.47, 0)` — the same phantom shape A6.P7 closed for the cottage
|
||||
door, but here the cause is per-cyl-without-BSP, not per-entity-with-both.
|
||||
- **Player Z stayed at 94.00 for the entire 4216-record capture** — never
|
||||
gained altitude.
|
||||
|
||||
This is **NOT** a regression of A6.P7. The fix did exactly what retail does
|
||||
for entities with `HAS_PHYSICS_BSP_PS`. The stair bug is a separate class:
|
||||
**cyl-only entities (no BSP) whose cyl geometry shouldn't physically block
|
||||
the player but does.**
|
||||
|
||||
---
|
||||
|
||||
## What today shipped (DO NOT redo)
|
||||
|
||||
### A6.P7 — retail-binary cyl/BSP dispatch (commit `888272a`)
|
||||
- File: `src/AcDream.Core/Physics/PhysicsBody.cs` (added
|
||||
`PhysicsStateFlags.HasPhysicsBsp = 0x00010000`)
|
||||
- File: `src/AcDream.Core/Physics/TransitionTypes.cs` (added
|
||||
`Transition.BspOnlyDispatch(uint)` predicate + per-entry guard at the
|
||||
cyl/sphere branch)
|
||||
- Test: `tests/AcDream.Core.Tests/Physics/A6P7DispatchRulesTests.cs` (7 tests)
|
||||
- Investigation:
|
||||
[`docs/research/2026-05-25-a6-door-cyl-retail-dispatch-investigation.md`](2026-05-25-a6-door-cyl-retail-dispatch-investigation.md).
|
||||
- **Visual-verified at Holtburg cottage door 2026-05-25.** Captures:
|
||||
`launch-a6p7.log`, `launch-a6p7-v2.log` — 1187 `[cyl-skip-bsp]`, 0
|
||||
`[cyl-test]` on the door, 30 axis-aligned hits, no phantom diagonals.
|
||||
|
||||
---
|
||||
|
||||
## The new bug — captures + evidence
|
||||
|
||||
### Captures (on disk, gitignored — DO NOT commit them; treat as live data)
|
||||
- **Working baseline** (cellar stairs that work): `stairs-working.jsonl`
|
||||
(16.9 MB, ~22K records). Z range 90.95 ↔ 94.00 (full cellar climb). 12
|
||||
cell transitions; only 23 `hit=yes` events; no diagonal normals; user
|
||||
ran up + down twice. Cells `0xA9B40143/146/147`.
|
||||
- **Broken stairs**: `stairs-broken.jsonl` (8.1 MB, 4216 records). Z stayed
|
||||
at 94.00 for the entire capture. Cells `0xA9B40159` + `0xA9B4015A`. The
|
||||
player tried multiple approach angles; never climbed any step.
|
||||
- **Launch logs with probes**: `stairs-working.launch.log`,
|
||||
`stairs-broken.launch.log`. Contain `[cyl-test]`, `[cyl-skip-bsp]`,
|
||||
`[bsp-test]`, `[resolve]`, `[resolve-bldg]` probe lines.
|
||||
|
||||
### Reproduction
|
||||
Login as `+Acdream` at Holtburg. The cellar stairs work (verified). The
|
||||
broken stairs the user found are at world XY around (110, 26), Z range
|
||||
94 → 96. Walk west into them — sphere hits something diagonal and gets
|
||||
stuck oscillating between `n=(0, 1, 0)` and `n=(0.87, -0.49, 0)` slides.
|
||||
|
||||
### Geometry summary (from `stairs-broken.launch.log`)
|
||||
The blocker is multi-part entity `entityId=0x0040B500`. Ten of its parts
|
||||
are cylinders forming a staircase at `Y=26.60`:
|
||||
|
||||
| Part | World XY | Z (cyl bottom) |
|
||||
|---|---|---|
|
||||
| `0x40B5008C` (part 140) | (108.72, 26.60) | 96.47 |
|
||||
| `0x40B5008D` (part 141) | (108.97, 26.60) | 96.22 |
|
||||
| `0x40B5008E` (part 142) | (109.22, 26.60) | 95.97 |
|
||||
| `0x40B5008F` (part 143) | (109.47, 26.60) | 95.72 |
|
||||
| `0x40B50090` (part 144) | (109.72, 26.60) | 95.47 |
|
||||
| `0x40B50091` (part 145) | (109.97, 26.60) | 95.22 |
|
||||
| `0x40B50092` (part 146) | (110.22, 26.60) | 94.97 |
|
||||
| `0x40B50093` (part 147) | (110.47, 26.60) | 94.72 |
|
||||
| `0x40B50094` (part 148) | (110.72, 26.60) | 94.47 |
|
||||
| `0x40B50095` (part 149) | (110.97, 26.60) | 94.22 |
|
||||
|
||||
Each cyl: `radius=0.80, height=0.80, state=0x00000000`. The entity also
|
||||
has a BSP part `obj=0xB5008900 gfx=0x01000C16 radius=2.645 pos=(109.30,
|
||||
26.30, 95.75)` but it's effectively non-physics
|
||||
(`hasPhys=False bspR=0.00 vAabbR=0.82`) — the `vAabbR` here is the
|
||||
**visual** AABB radius being borrowed as a cylinder fallback because the
|
||||
underlying `GfxObj` has no physics BSP.
|
||||
|
||||
### What's blocking the player
|
||||
|
||||
Sphere at `(112.115, 25.995, 94.00)` wants to move west. The closest cyl
|
||||
`0x40B50095` is at `(110.97, 26.60, 94.22)`:
|
||||
- `distXY = 1.295m` (just barely outside reach `0.80 + 0.48 = 1.28m`)
|
||||
- But during sub-stepping the sphere center crosses 1.28m → cyl overlaps
|
||||
- Radial normal direction from cyl center to sphere: `(0.884, -0.467, 0)` —
|
||||
matches observed phantom hits `(0.88, -0.47)`, `(0.86, -0.51)`, etc.
|
||||
|
||||
The cyl is **too tall (0.80m) to step over** under A6.P6's grounded
|
||||
step-over check (step-up budget = 0.60m). Falls through to the
|
||||
wall-slide branch which produces the diagonal radial normal that drives
|
||||
the sphere's slide tangent into the perpendicular cell wall, then
|
||||
re-blocks. Net: stuck.
|
||||
|
||||
### Why A6.P7 doesn't help
|
||||
A6.P7 gates the cyl branch on `(state & 0x10000) != 0`. These stair cyls
|
||||
have `state=0x00000000` — bit not set. Guard does NOT fire. Cyls are
|
||||
tested. Sphere blocks.
|
||||
|
||||
---
|
||||
|
||||
## What this session needs — retail investigation
|
||||
|
||||
**Mandate:** report-only research, NO implementation. Use the `/investigate`
|
||||
skill. The fix design comes in a subsequent session once the retail
|
||||
behavior is settled.
|
||||
|
||||
### Question 1 — What does retail DO at this exact staircase?
|
||||
|
||||
**Use cdb.** The toolchain in `CLAUDE.md` "Retail debugger toolchain" is
|
||||
ready. The matching binary + PDB are verified.
|
||||
|
||||
Concrete experiment:
|
||||
1. Have the user run the retail acclient.exe (Microsoft AC official build
|
||||
v11.4186) at the same world location (cells `0xA9B40159` + `0xA9B4015A`,
|
||||
XY ≈ (110, 26)). The user needs to be IN the building, AT the foot of
|
||||
these stairs.
|
||||
2. Attach cdb with breakpoints:
|
||||
- `acclient!CCylSphere::collides_with_sphere` at `0x53a880` — counter
|
||||
`$t0`, log every 100 hits with the `this` pointer and the moving
|
||||
sphere's position, `gc`. Auto-detach after 5000.
|
||||
- `acclient!CCylSphere::intersects_sphere` (the dispatch from
|
||||
`CPhysicsObj::FindObjCollisions` cyl branch) — counter `$t1`, log
|
||||
entity address.
|
||||
- `acclient!CObjCell::find_env_collisions` — counter `$t2`. Tells us if
|
||||
retail uses cell BSP for stair collision.
|
||||
- `acclient!CPartArray::FindObjCollisions` — counter `$t3`. Confirms BSP
|
||||
dispatch path.
|
||||
3. Have the user walk straight into the broken stairs from outside, then
|
||||
try to climb them. Capture 30 seconds.
|
||||
4. Detach. Analyze:
|
||||
- Does `CCylSphere::collides_with_sphere` fire on the stair entity? If
|
||||
yes → retail's cyls ARE active here, and retail somehow handles them
|
||||
differently (different step-up threshold? cell-context-aware?). If
|
||||
no → retail's cyls are excluded by something we don't replicate.
|
||||
- Does `CObjCell::find_env_collisions` fire heavily? If yes → retail
|
||||
might be using cell BSP polygons for the stairs (and the entity cyls
|
||||
are decorative/click-targets only).
|
||||
|
||||
### Question 2 — What's the Setup ID? Compare retail's PhysicsObj construction
|
||||
|
||||
Our `[resolve-bldg]` lines show the entity is built from GfxObj
|
||||
`0x0100081A` with `hasPhys=False`. **What's the Setup ID for entity
|
||||
`0x0040B500`?** Trace through our streaming code to find which Setup
|
||||
emitted the 150-part build.
|
||||
|
||||
Steps:
|
||||
1. Grep `src/AcDream.App/Rendering/GameWindow.cs` for the
|
||||
`BuildInteriorEntitiesForStreaming` path (CLAUDE.md says it hydrates
|
||||
EnvCell static objects with id `0x40xxxxxx`).
|
||||
2. Add a temporary `[entity-source]` probe that logs the Setup id when an
|
||||
entity gets registered. Or check existing diagnostic output — the
|
||||
`gfxObj=0x0100081A` is the part's GfxObj, but we need the parent Setup.
|
||||
3. With the Setup id in hand, look up retail's behavior:
|
||||
- Decompile / grep `docs/research/named-retail/acclient_2013_pseudo_c.txt`
|
||||
for `CPhysicsObj::InitPartArrayFromSetup` or similar to see how retail
|
||||
builds the part_array from a Setup. Does retail include every part as
|
||||
a collision shape, or filter by some flag?
|
||||
|
||||
### Question 3 — Why is `vAabbR` becoming a cylinder?
|
||||
|
||||
The `[resolve-bldg]` line shows `gfxObj=0x0100081A hasPhys=False bspR=0.00
|
||||
vAabbR=0.82`. We registered a `r=0.80` cyl. The 0.80 ≈ 0.82 match is
|
||||
suspicious — we're using the **visual AABB radius** as a fallback cyl
|
||||
radius when there's no physics BSP.
|
||||
|
||||
Steps:
|
||||
1. Find the code path in our tree that does this fallback. Likely in
|
||||
`src/AcDream.Core/Physics/ShadowShapeBuilder.cs` `FromSetup` or in
|
||||
`RegisterMultiPart`. Look for cases where `GfxObj.PhysicsBSP` is null
|
||||
and a cyl is synthesized.
|
||||
2. Cross-reference retail: does retail synthesize a cyl from visual bounds
|
||||
when physics is null? Or does retail skip such parts entirely for
|
||||
collision (visual-only)?
|
||||
3. ACE check: `references/ACE/Source/ACE.Server/Physics/PhysicsObj.cs` —
|
||||
how does ACE construct the part_array from a Setup with mixed
|
||||
physics/visual-only parts?
|
||||
|
||||
### Question 4 — Cell BSP fallback
|
||||
|
||||
If retail's stairs are walked via cell BSP polygons (not entity cyls),
|
||||
what's in cell `0xA9B40159`'s BSP at this XY/Z? Is there a walkable
|
||||
polygon staircase that we're not iterating?
|
||||
|
||||
Steps:
|
||||
1. Use `ACDREAM_DUMP_CELLS=0xA9B40159,0xA9B4015A` to dump the cell BSPs to
|
||||
JSON. (Confirm the env var path; see existing `CellDump` infra near
|
||||
issue #98's apparatus.)
|
||||
2. Look for inclined polygons in the dump that form the staircase. If
|
||||
present → retail likely uses these for collision; our entity cyls are
|
||||
either a setup misinterpretation or redundant.
|
||||
|
||||
---
|
||||
|
||||
## Files to read FIRST next session
|
||||
|
||||
| Path | Why |
|
||||
|---|---|
|
||||
| `docs/ISSUES.md` (#101) | The filed issue with severity + acceptance |
|
||||
| `docs/research/2026-05-25-a6-door-cyl-retail-dispatch-investigation.md` | A6.P7 background (closed; companion bug) |
|
||||
| `docs/research/named-retail/acclient_2013_pseudo_c.txt:276776` | `CPhysicsObj::FindObjCollisions` |
|
||||
| Setup dat reader path in `src/AcDream.Core/Physics/ShadowShapeBuilder.cs` | Cyl synthesis from Setup; the suspected fallback |
|
||||
| `src/AcDream.App/Rendering/GameWindow.cs::BuildInteriorEntitiesForStreaming` | Entity hydration for EnvCell statics |
|
||||
| `references/ACE/Source/ACE.Server/Physics/PhysicsObj.cs` | ACE PartArray construction |
|
||||
| `references/ACE/Source/ACE.Server/Physics/Common/Setup.cs` | ACE Setup → PartArray pipeline |
|
||||
|
||||
---
|
||||
|
||||
## Tests that must stay green
|
||||
|
||||
Same as A6.P7 list:
|
||||
|
||||
```
|
||||
dotnet test tests/AcDream.Core.Tests/AcDream.Core.Tests.csproj --no-build -c Debug --filter "FullyQualifiedName=AcDream.Core.Tests.Physics.CellarUpTrajectoryReplayTests.LiveCompare_FirstCap_FixClosesCottageFloorCap|FullyQualifiedName=AcDream.Core.Tests.Physics.DoorBugTrajectoryReplayTests.Directional_OutsideIn_SouthApproach_BlocksAtSlabSouthFace|FullyQualifiedName=AcDream.Core.Tests.Physics.DoorBugTrajectoryReplayTests.Directional_InsideOut_NorthApproach_BlocksAtSlabNorthFace|FullyQualifiedName=AcDream.Core.Tests.Physics.DoorBugTrajectoryReplayTests.CornerSlide_AlcoveEastToCottageNorth_ShouldBlock|FullyQualifiedName=AcDream.Core.Tests.Physics.DoorBugTrajectoryReplayTests.Geometric_DoorSlabAtSphereHeight_OverlapsInZ|FullyQualifiedName=AcDream.Core.Tests.Physics.DoorBugTrajectoryReplayTests.InsideOut_Tick3254_WithCottageWalls_ShouldBlock|FullyQualifiedName~BSPQueryTests.FindCollisions_Path5|FullyQualifiedName~CellTransitTests.A6P5|FullyQualifiedName~DoorCollisionApparatusTests.Apparatus_DeadCenter|FullyQualifiedName~A6P7DispatchRulesTests"
|
||||
```
|
||||
|
||||
Expected: 20/20 pass.
|
||||
|
||||
---
|
||||
|
||||
## Things NOT to do (do-not-retry)
|
||||
|
||||
1. **Don't lower step-up height** to make A6.P6's grounded step-over fit the
|
||||
0.80m cyl. Step-up budget = 0.60m is retail-faithful. Tweaking it would
|
||||
regress every other surface where 0.60m is correct (curbs, low ledges).
|
||||
2. **Don't extend A6.P7's `BspOnlyDispatch` to entities with `state=0`.**
|
||||
That gate is retail-specific (`HAS_PHYSICS_BSP_PS`). Skipping cyls
|
||||
purely because peer parts exist with BSP would diverge from retail and
|
||||
break NPC cyl-only entities.
|
||||
3. **Don't disable cyl fallback when `hasPhys=False` without checking
|
||||
retail.** Until we know how retail handles `GfxObj` with no physics
|
||||
BSP, "just skip the cyl" might break other content (small decorative
|
||||
items that DO collide in retail).
|
||||
4. **Don't add per-entity workarounds** ("if entity id 0x0040B500, skip
|
||||
cyls"). Per CLAUDE.md no-workarounds rule.
|
||||
5. **Don't enlarge the sphere's step-up budget for tall cyls.** Retail's
|
||||
threshold is what it is. If retail steps over 0.80m cyls in this
|
||||
scenario, the mechanism is something else.
|
||||
|
||||
---
|
||||
|
||||
## Three fix-shape candidates (for the FOLLOWING session, not this one)
|
||||
|
||||
Listed in rough order of retail-faithfulness based on the limited evidence
|
||||
we have. The retail investigation will decide which is right.
|
||||
|
||||
1. **Don't synthesize cyls from visual AABB when `GfxObj.PhysicsBSP` is
|
||||
null.** Suppress at registration time in `ShadowShapeBuilder.FromSetup`.
|
||||
Retail-anchored: if retail's `CPartArray` doesn't include such parts in
|
||||
the collision list, our registration shouldn't either. The cell BSP
|
||||
would then be the only collision source.
|
||||
2. **Use cell BSP polygons** for stair geometry; entity cyls are
|
||||
decorative-only for this entity class. Requires: (a) confirming cell
|
||||
`0xA9B40159` BSP has walkable stair polys, (b) ensuring our cell BSP
|
||||
query iterates them. Likely a no-op on our side once (1) is done.
|
||||
3. **Make `step_sphere_up` cyl-height-tolerant** — if the sphere is on a
|
||||
walkable plane and a cyl is detected, attempt step-up even when cyl
|
||||
height > step-up budget IF a walkable surface exists at the top of the
|
||||
cyl. Retail-anchored ONLY if cdb shows retail does this on these
|
||||
specific stairs.
|
||||
|
||||
---
|
||||
|
||||
## Pickup prompt for next session
|
||||
|
||||
```
|
||||
A6 — Broken stairs cyl investigation (issue #101). Investigation-only session.
|
||||
|
||||
Read first (in this order):
|
||||
1. docs/research/2026-05-25-stairs-cyl-investigation-handoff.md
|
||||
(this file — full context, captures, geometry, do-not-retry list)
|
||||
2. docs/ISSUES.md #101
|
||||
3. docs/research/2026-05-25-a6-door-cyl-retail-dispatch-investigation.md
|
||||
(A6.P7 background — closed; companion bug)
|
||||
|
||||
State both altitudes:
|
||||
Currently working toward: M1.5 — Indoor world feels right
|
||||
Current phase: A6 — broken-stairs investigation (issue #101)
|
||||
|
||||
Session mandate: retail investigation, NOT implementation. Use the
|
||||
/investigate skill. Specific questions (each must be answered with cited
|
||||
evidence — retail line numbers, cdb traces, dat dumps):
|
||||
|
||||
1. Does retail's CCylSphere::collides_with_sphere fire on the stair-step
|
||||
cylinders at cells 0xA9B40159/0xA9B4015A when a player walks in to
|
||||
climb them? If yes — how does retail walk past 0.80m-tall cyls? If
|
||||
no — what excludes them?
|
||||
|
||||
2. What's the Setup ID for entity 0x0040B500? Trace from
|
||||
GameWindow.cs::BuildInteriorEntitiesForStreaming. Cross-reference how
|
||||
retail's CPhysicsObj::InitPartArrayFromSetup (or equivalent) builds
|
||||
the collision shape list — does retail include parts with
|
||||
hasPhys=False?
|
||||
|
||||
3. Why does our ShadowShapeBuilder synthesize an r=0.80 cyl from
|
||||
vAabbR=0.82 when GfxObj.PhysicsBSP is null? Identify the code path.
|
||||
Does retail do this?
|
||||
|
||||
4. Dump cell 0xA9B40159's BSP polygons (ACDREAM_DUMP_CELLS). Does the
|
||||
cell BSP have walkable stair polygons? If yes — retail's stair
|
||||
collision is the cell BSP, not the entity cyls.
|
||||
|
||||
Deliverable: a short report (~2-3 pages) covering the 4 questions with
|
||||
retail line numbers, cdb trace excerpts, code citations. Then propose
|
||||
which of the 3 fix-shape candidates is most retail-faithful (or a fifth
|
||||
shape that emerges from the research).
|
||||
|
||||
DO NOT implement the fix this session. Save it for the session after.
|
||||
|
||||
Do-not-retry list (in handoff doc) — read it before starting.
|
||||
|
||||
Tests to keep green if any code changes happen (none expected this
|
||||
session): see handoff doc.
|
||||
|
||||
Reproduction setup for the broken scenario:
|
||||
ACDREAM_PROBE_BUILDING=1 ACDREAM_PROBE_RESOLVE=1
|
||||
ACDREAM_CAPTURE_RESOLVE=<path>.jsonl
|
||||
walk to cells 0xA9B40159/A in Holtburg (XY ≈ 110, 26)
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue