feat(phys): A6.P4 door — cdb-driven NegPolyHit dispatch (incomplete; needs BSP near-miss recording)
cdb attached to retail at a Holtburg cottage door while user walked the inside-out off-center scenario. Three trace iterations identified that retail's collision-recording happens via SPHEREPATH::set_neg_poly_hit (fires hundreds of times during inside-out walk), NOT via the more obvious-named COLLISIONINFO setters (which fire 0 times). Apparatus scripts at tools/cdb/door-inside-out-v[1-3].cdb + symbol-probe.cdb. Our codebase has NegPolyHitDispatch defined but never called. The downstream TransitionalInsert NegPolyHit handler was a stub. Two-part fix landed: 1. BSPQuery.FindCollisions Path 5 (Contact branch) restructured — distinguishes full hit (hit0 == true → StepSphereUp) from near-miss (hit0 == false but hitPoly0 != null → NegPolyHitDispatch). Mirrors retail BSPTREE::find_collisions at acclient_2013_pseudo_c.txt:0053a630-0053a6fb. 2. Transition.TransitionalInsert NegPolyHit handler — dispatches to step_up + step_up_slide (NegStepUp=true) or records collision normal + returns Collided (NegStepUp=false). Mirrors retail CTransition::transitional_insert at acclient_2013_pseudo_c.txt:0050b7af-0050b7e6. Tests: all 11 fix-relevant + regression tests pass including issue #98. VISUAL VERIFICATION (user-driven inside-out off-center): still squeezes through. Diagnostic [neg-poly-dispatch] probe shows ZERO hits in production. The Path 5 restructuring doesn't surface NegPolyHit because our SphereIntersectsPolyInternal only sets hitPoly on FULL hits — retail's sphere_intersects_poly sets var_5c (closest polygon) even on near-misses via BSP-traversal side effect. Remaining fix (next session): add near-miss polygon recording to SphereIntersectsPolyInternal. Once it sets hitPoly on near-miss BSP traversal, the Path 5 NegPolyHit dispatch (this commit) will fire and the TransitionalInsert handler (this commit) will block. Full handoff with cdb trace table + next-step plan: docs/research/2026-05-25-door-bug-cdb-retail-trace-findings.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a657ca946c
commit
fd1548af61
7 changed files with 382 additions and 29 deletions
34
tools/cdb/door-inside-out-v2.cdb
Normal file
34
tools/cdb/door-inside-out-v2.cdb
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
$$
|
||||
$$ Retail cdb trace v2 — find what records the collision when retail blocks the door.
|
||||
$$ v1 had SPHEREPATH::set_collide which never fired (0 hits despite retail BLOCKING).
|
||||
$$ Switching to the COLLISIONINFO family.
|
||||
$$
|
||||
$$ BP1: CPhysicsObj::FindObjCollisions (entry count)
|
||||
$$ BP2: COLLISIONINFO::set_collision_normal (the "I got blocked" record)
|
||||
$$ BP3: COLLISIONINFO::set_sliding_normal (slide-along response)
|
||||
$$ BP4: COLLISIONINFO::add_object (which entity caused the collision)
|
||||
$$
|
||||
|
||||
.logopen C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\retail-door-v2.log
|
||||
|
||||
.sympath C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\refs
|
||||
.symopt+ 0x40
|
||||
.reload /f acclient.exe
|
||||
|
||||
r $t0 = 0
|
||||
r $t1 = 0
|
||||
r $t2 = 0
|
||||
r $t3 = 0
|
||||
r $t4 = 0
|
||||
|
||||
bp acclient!CPhysicsObj::FindObjCollisions "r $t1 = @$t1 + 1; r $t0 = @$t0 + 1; .if (@$t1 % 5000 == 0) { .printf /D \"[BP1] FindObj=%d setColN=%d setSldN=%d addObj=%d\\n\", @$t1, @$t2, @$t3, @$t4 }; .if (@$t0 >= 30000) { .printf /D \"=== DETACH total=%d findObj=%d setColN=%d setSldN=%d addObj=%d ===\\n\", @$t0, @$t1, @$t2, @$t3, @$t4; qd } .else { gc }"
|
||||
|
||||
bp acclient!COLLISIONINFO::set_collision_normal "r $t2 = @$t2 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP2] set_collision_normal hit#%d nx_h=0x%08X ny_h=0x%08X nz_h=0x%08X\\n\", @$t2, dwo(poi(@esp+4)+0), dwo(poi(@esp+4)+4), dwo(poi(@esp+4)+8); .if (@$t0 >= 30000) { qd } .else { gc }"
|
||||
|
||||
bp acclient!COLLISIONINFO::set_sliding_normal "r $t3 = @$t3 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP3] set_sliding_normal hit#%d nx_h=0x%08X ny_h=0x%08X nz_h=0x%08X\\n\", @$t3, dwo(poi(@esp+4)+0), dwo(poi(@esp+4)+4), dwo(poi(@esp+4)+8); .if (@$t0 >= 30000) { qd } .else { gc }"
|
||||
|
||||
bp acclient!COLLISIONINFO::add_object "r $t4 = @$t4 + 1; r $t0 = @$t0 + 1; .if (@$t0 >= 30000) { qd } .else { gc }"
|
||||
|
||||
.printf "v2 trace armed: 4 BPs (COLLISIONINFO family). Walk now.\\n"
|
||||
|
||||
g
|
||||
43
tools/cdb/door-inside-out-v3.cdb
Normal file
43
tools/cdb/door-inside-out-v3.cdb
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
$$
|
||||
$$ Retail cdb trace v3 — wider breakpoint net to catch what retail does
|
||||
$$ when it blocks the sphere. v1 (SPHEREPATH::set_collide) and v2
|
||||
$$ (COLLISIONINFO::set_collision/sliding/add_object) all came back at 0.
|
||||
$$
|
||||
$$ Trying: anything in the BSP slide / step / find_collisions chain.
|
||||
$$ BP1: CPhysicsObj::FindObjCollisions (counter only)
|
||||
$$ BP2: BSPTREE::slide_sphere
|
||||
$$ BP3: CSphere::slide_sphere
|
||||
$$ BP4: CTransition::cliff_slide
|
||||
$$ BP5: SPHEREPATH::set_neg_poly_hit (alternate hit-recording)
|
||||
$$ BP6: CTransition::insert_into_cell (cell transit attempts)
|
||||
$$
|
||||
|
||||
.logopen C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\retail-door-v3.log
|
||||
|
||||
.sympath C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\refs
|
||||
.symopt+ 0x40
|
||||
.reload /f acclient.exe
|
||||
|
||||
r $t0 = 0
|
||||
r $t1 = 0
|
||||
r $t2 = 0
|
||||
r $t3 = 0
|
||||
r $t4 = 0
|
||||
r $t5 = 0
|
||||
r $t6 = 0
|
||||
|
||||
bp acclient!CPhysicsObj::FindObjCollisions "r $t1 = @$t1 + 1; r $t0 = @$t0 + 1; .if (@$t1 % 5000 == 0) { .printf /D \"[STATS] FindObj=%d bspSld=%d sphSld=%d cliffSld=%d negPoly=%d insertCell=%d\\n\", @$t1, @$t2, @$t3, @$t4, @$t5, @$t6 }; .if (@$t0 >= 40000) { .printf /D \"=== DETACH FindObj=%d bspSld=%d sphSld=%d cliffSld=%d negPoly=%d insertCell=%d ===\\n\", @$t1, @$t2, @$t3, @$t4, @$t5, @$t6; qd } .else { gc }"
|
||||
|
||||
bp acclient!BSPTREE::slide_sphere "r $t2 = @$t2 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP2] BSPTREE::slide_sphere hit#%d\\n\", @$t2; .if (@$t0 >= 40000) { qd } .else { gc }"
|
||||
|
||||
bp acclient!CSphere::slide_sphere "r $t3 = @$t3 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP3] CSphere::slide_sphere hit#%d\\n\", @$t3; .if (@$t0 >= 40000) { qd } .else { gc }"
|
||||
|
||||
bp acclient!CTransition::cliff_slide "r $t4 = @$t4 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP4] cliff_slide hit#%d\\n\", @$t4; .if (@$t0 >= 40000) { qd } .else { gc }"
|
||||
|
||||
bp acclient!SPHEREPATH::set_neg_poly_hit "r $t5 = @$t5 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP5] set_neg_poly_hit hit#%d\\n\", @$t5; .if (@$t0 >= 40000) { qd } .else { gc }"
|
||||
|
||||
bp acclient!CTransition::insert_into_cell "r $t6 = @$t6 + 1; r $t0 = @$t0 + 1; .if (@$t0 >= 40000) { qd } .else { gc }"
|
||||
|
||||
.printf "v3 trace armed: 6 BPs wide net. Walk into door now.\\n"
|
||||
|
||||
g
|
||||
39
tools/cdb/door-inside-out.cdb
Normal file
39
tools/cdb/door-inside-out.cdb
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
$$
|
||||
$$ Retail cdb trace — does the cottage door block sphere at off-center inside-out approach?
|
||||
$$ 2026-05-25
|
||||
$$
|
||||
$$ Three breakpoints with counters; auto-detach at 30K total events to avoid
|
||||
$$ retail-session-lag → ACE timeout. Pattern from a6-probe.cdb (proven).
|
||||
$$
|
||||
$$ Question: when player walks from inside cottage to outside, off-center ~50cm,
|
||||
$$ does retail's collision system FIRE (set_collide) at the corner where
|
||||
$$ alcove east wall meets cottage north exterior wall? Or does it walk through
|
||||
$$ silently like acdream does?
|
||||
$$
|
||||
$$ BP1: CPhysicsObj::FindObjCollisions — per-object collision test entry.
|
||||
$$ BP2: CCylSphere::collides_with_sphere — cylinder shape hit test.
|
||||
$$ BP3: SPHEREPATH::set_collide — collision RECORDED (the smoking gun).
|
||||
$$ If BP3 fires often during inside-out walk: retail blocks.
|
||||
$$ If BP3 silent: retail walks through too (= retail-faithful behavior).
|
||||
$$
|
||||
|
||||
.logopen C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\retail-door-inside-out.log
|
||||
|
||||
.sympath C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\refs
|
||||
.symopt+ 0x40
|
||||
.reload /f acclient.exe
|
||||
|
||||
r $t0 = 0
|
||||
r $t1 = 0
|
||||
r $t2 = 0
|
||||
r $t3 = 0
|
||||
|
||||
bp acclient!CPhysicsObj::FindObjCollisions "r $t1 = @$t1 + 1; r $t0 = @$t0 + 1; .if (@$t1 % 5000 == 0) { .printf /D \"[BP1] FindObjCollisions=%d cyl_collides=%d set_collide=%d\\n\", @$t1, @$t2, @$t3 }; .if (@$t0 >= 30000) { .printf /D \"=== DETACH total=%d FindObj=%d cyl=%d setCollide=%d ===\\n\", @$t0, @$t1, @$t2, @$t3; qd } .else { gc }"
|
||||
|
||||
bp acclient!CCylSphere::collides_with_sphere "r $t2 = @$t2 + 1; r $t0 = @$t0 + 1; .if (@$t0 >= 30000) { qd } .else { gc }"
|
||||
|
||||
bp acclient!SPHEREPATH::set_collide "r $t3 = @$t3 + 1; r $t0 = @$t0 + 1; .printf /D \"[BP3] set_collide hit#%d nx_h=0x%08X ny_h=0x%08X nz_h=0x%08X\\n\", @$t3, dwo(poi(@esp+4)+0), dwo(poi(@esp+4)+4), dwo(poi(@esp+4)+8); .if (@$t0 >= 30000) { qd } .else { gc }"
|
||||
|
||||
.printf "Door inside-out trace armed: 3 BPs, threshold 30K. Walk now.\\n"
|
||||
|
||||
g
|
||||
19
tools/cdb/symbol-probe.cdb
Normal file
19
tools/cdb/symbol-probe.cdb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
$$ Quick symbol probe: list what COLLISIONINFO / SPHEREPATH functions exist.
|
||||
.logopen C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\retail-sym-probe.log
|
||||
|
||||
.sympath C:\Users\erikn\source\repos\acdream\.claude\worktrees\strange-albattani-3fc83c\refs
|
||||
.symopt+ 0x40
|
||||
.reload /f acclient.exe
|
||||
|
||||
.printf "=== COLLISIONINFO symbols ===\n"
|
||||
x acclient!COLLISIONINFO::*
|
||||
|
||||
.printf "\n=== SPHEREPATH symbols ===\n"
|
||||
x acclient!SPHEREPATH::*
|
||||
|
||||
.printf "\n=== CTransition symbols (subset) ===\n"
|
||||
x acclient!CTransition::*collide*
|
||||
x acclient!CTransition::insert*
|
||||
x acclient!CTransition::makeTr*
|
||||
|
||||
qd
|
||||
Loading…
Add table
Add a link
Reference in a new issue