The indoor GREY flap at a top-floor connecting room. The render portal side-cull reconstructed each doorway's "interior side" (PortalClipPlane.InsideSide) from the cell's AABB CENTROID. For a THIN connector cell (0xF6820118, 5 render polys), the bounding-box center falls on the WRONG side of the 0118->0116 doorway, so the eye read as a back-portal and the forward room 0116 was culled -> the aperture showed the fog clear color = grey. Retail's PView::InitCell (0x005a4b70) and acdream's own PHYSICS path (CellTransit.cs:190) both read the explicit dat PortalSide bit ((Flags&2)==0) instead of guessing from geometry. Port the render path (GameWindow.BuildLoadedCell) to the same bit. Proven by a live retail cdb trace (retail draws 0116 from the 0118 root at the grey pose; tools/cdb/issue186-connector-decider.cdb) + an offline dat diagnostic (Issue186...PortalSide_CentroidVsDatBit_AtGreyEye): the dat bit matches the old centroid on every portal of these cells EXCEPT the one #186 breaks, so the switch is surgical. Full regression green (App 741 / Core 2631); the CornerFlood + Issue113 dat-loading helpers updated to the same bit confirm every real Holtburg/tower/hall cell floods identically. Touches neither PortalSideEpsilon nor the deleted EyeInsidePortalOpening rescue (the two DO-NOT-RETRY traps). Live-gated: user-confirmed no grey at any camera angle; probe shows 216 root=0118 frames, 0 still grey (0118->0116 now TRV, vis=4). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
37 lines
2.3 KiB
Text
37 lines
2.3 KiB
Text
* #186 connector GREY flap - PICK-vs-FLOOD decider (2026-07-08)
|
|
* Attach to a LIVE retail acclient.exe HELD in the connecting-room grey pose.
|
|
* Binary MUST pair with refs/acclient.pdb (check_exe_pdb.py -> MATCH).
|
|
*
|
|
* Two breakpoints, both sampled at a low rate to avoid lagging retail -> ACE timeout:
|
|
* bp1 SmartBox::update_viewer (0x453ce0) -> viewer.objcell_id = the render ROOT (viewer_cell)
|
|
* player m_position = confirms we are at the pose (expect 0116)
|
|
* bp2 PView::DrawCells (0x5a4840) -> cell_draw_num + cell_draw_list ids = the DRAWN cell set
|
|
* + eye viewpoint
|
|
*
|
|
* DECISION (handoff 2026-07-08-186 section 3):
|
|
* retail viewerCell == 0116 -> PICK fix (acdream over-switches root to connector 0118)
|
|
* retail viewerCell == 0118 AND draw list has 0116 -> FLOOD fix (retail keeps the back-portal room drawn)
|
|
*
|
|
* update_viewer sets viewer_cell at EXIT, so at bp ENTRY viewer.objcell_id is the PRIOR frame value.
|
|
* For a HELD (stationary) pose prior==current, so this is exact - HOLD the grey pose.
|
|
*
|
|
* Auto-detach via .detach after a hit threshold (qd does NOT fire inside a conditional bp action - it
|
|
* strands cdb and kills retail). NEVER put a semicolon inside a comment line (it splits into a command).
|
|
|
|
.logopen C:\Users\erikn\source\repos\acdream\.claude\worktrees\vigorous-joliot-f0c3ad\issue186-connector-decider.log
|
|
.sympath C:\Users\erikn\source\repos\acdream\refs
|
|
.symopt+ 0x40
|
|
.reload /f acclient.exe
|
|
|
|
.echo ===SYMBOLS===
|
|
x acclient!SmartBox::update_viewer
|
|
x acclient!PView::DrawCells
|
|
|
|
r $t0 = 0
|
|
r $t1 = 0
|
|
|
|
bp acclient!SmartBox::update_viewer "r $t0 = @$t0 + 1; .if (@$t0 % 15 == 1) { .printf \"[root] hit=%d viewerCell=%04x playerCell=%04x\\n\", @$t0, @@c++(((acclient!SmartBox*)@ecx)->viewer.objcell_id) & 0xffff, @@c++(((acclient!SmartBox*)@ecx)->player->m_position.objcell_id) & 0xffff }; gc"
|
|
|
|
bp acclient!PView::DrawCells "r $t1 = @$t1 + 1; .if (@$t1 % 15 == 1) { r $t2 = @@c++(((acclient!PView*)@ecx)->cell_draw_num); .printf \"[draw] hit=%d num=%d:\", @$t1, @$t2; .for (r $t3 = 0; @$t3 < @$t2; r $t3 = @$t3 + 1) { .printf \" %04x\", @@c++(((acclient!PView*)@ecx)->cell_draw_list.data[@$t3]->m_DID.id) & 0xffff }; .printf \" || eye \"; dx acclient!Render::FrameCurrent->viewer.viewpoint }; .if (@$t1 >= 3000) { .detach } .else { gc }"
|
|
|
|
g
|