$$ ============================================================================ $$ find-cell-list-capture-aligned.cdb — P1 ALIGNED retail golden capture $$ ---------------------------------------------------------------------------- $$ SUPERSEDES find-cell-list-capture.cdb for the P1 gate. The original logged $$ this->m_position AT the change_cell breakpoint. But CPhysicsObj::SetPositionInternal $$ (acclient_2013_pseudo_c.txt) calls: $$ change_cell(this, curr_cell) @ line 283456 <- breakpoint fired here $$ set_frame(this, &curr_pos.frame) @ line 283458 <- m_position updated HERE, AFTER $$ so the original paired THIS frame's NEW cell with the PREVIOUS frame's position $$ — a deterministic one-frame offset (proven: golden_picked[i] == geom(golden_position[i+1]) $$ for all 22 rows of the original capture; see $$ docs/research/2026-06-03-p1-membership-swept-advance-handoff.md follow-up). $$ $$ This script reads the NEW (committed) position from the set_frame call that $$ IMMEDIATELY follows change_cell within the same SetPositionInternal, so the cell $$ and position are from the SAME instant. The resulting golden lets the P1 gate be a $$ true integration test (no position/cell skew). $$ $$ Why the correlation is safe: $$ - Physics is single-threaded; SetPositionInternal(obj) runs change_cell(obj) then $$ set_frame(obj) back-to-back for the SAME object (no reentrancy). $$ - enter_cell (called by change_cell) does NOT call set_frame (verified $$ acclient_2013_pseudo_c.txt:278928). So the FIRST set_frame after a change_cell $$ is that object's committed frame. $$ - $t3 is the pending flag: change_cell arms it, the next set_frame consumes it. $$ $$ Offsets (verified live via discover-types.cdb; reused from the original script): $$ change_cell: this=@ecx ; seed = this->cell->id = poi(poi(@ecx+0x90)+0x58) $$ new_cell = poi(@esp+4) ; new_cell->id = poi(poi(@esp+4)+0x58) $$ set_frame: arg2 (Frame*) = poi(@esp+4) ; Frame.m_fOrigin @ +0x34 $$ new px/py/pz = poi(poi(@esp+4)+0x34 / +0x38 / +0x3c) (raw IEEE hex) $$ $$ Emits the golden format read by RetailTrace.ParseFindCellList; decode the hex with $$ tools/cdb/decode_fcl_capture.py (then filter to the doorway cells 0031/0170/0171): $$ [fcl] seed=0x px=0x py=0x pz=0x picked=0x $$ $$ Capture in a spot with NO other moving objects (NPCs crossing cells would also be $$ logged); the user paces the PLAYER alone in/out of the doorway. Stray rows are $$ filtered post-hoc to seed/picked in {0xA9B40031, 0xA9B40170, 0xA9B40171}. $$ ============================================================================ .logopen C:\Users\erikn\source\repos\acdream\.claude\worktrees\thirsty-goldberg-51bb9b\find-cell-list-capture-aligned.log .sympath C:\Users\erikn\source\repos\acdream\refs .symopt+ 0x40 .reload /f acclient.exe r $t0 = 0 r $t3 = 0 r $t4 = 0 r $t2 = 0 $$ BP1: change_cell — capture seed (old cell) + picked (new cell), arm pending. $$ Do NOT read position here: m_position is still the PREVIOUS frame's value. bp acclient!CPhysicsObj::change_cell "r $t4 = 0; .if (poi(@ecx+0x90) != 0) { r $t4 = poi(poi(@ecx+0x90)+0x58) }; r $t2 = poi(poi(@esp+4)+0x58); r $t3 = 1; gc" $$ BP2: set_frame — the FIRST set_frame after a change_cell carries the NEW $$ (committed, aligned) position. arg2 = &curr_pos.frame ; m_fOrigin @ +0x34. bp acclient!CPhysicsObj::set_frame ".if (@$t3 == 1) { r $t0 = @$t0 + 1; .printf /D \"[fcl] seed=0x%08x px=0x%08x py=0x%08x pz=0x%08x picked=0x%08x\\n\", @$t4, poi(poi(@esp+4)+0x34), poi(poi(@esp+4)+0x38), poi(poi(@esp+4)+0x3c), @$t2; r $t3 = 0; .if (@$t0 >= 16) { .printf /D \"=== DETACH after %d aligned cell changes ===\\n\", @$t0; qd } }; gc" .printf \"aligned find-cell-list capture armed (change_cell + set_frame). Walk SLOWLY in/out of the doorway now.\\n\" g