research(motion): cdb live trace of retail walk-to-run transition
Live cdb trace of retail acclient.exe (v11.4186, PDB-matched) capturing the exact function call sequence for a direct walk-to-run motion transition where the user holds shift+W (walk) then releases SHIFT while still holding W (transition to run). Trace bps on: - CPhysicsObj::DoInterpretedMotion (0x0050EA70) - CPartArray::DoInterpretedMotion (0x00518750) - MotionTableManager::PerformMovement (0x0051C0B0) - MotionTableManager::add_to_queue (0x0051BFE0) - MotionTableManager::truncate_animation_list (0x0051BCA0) - CMotionTable::DoObjectMotion (0x00523E90) - CMotionTable::StopObjectMotion (0x00523EC0) Captured trace at tools/cdb-scripts/walk_run_motion_trace.log shows the precise walk-to-run sequence: [79] CPhysicsObj::DoInterpretedMotion: motion=45000005 walk start [82] CMotionTable::DoObjectMotion: motion=45000005 [83] MotionTableManager::add_to_queue: arg1=45000005 arg2=00000001 [89] CPhysicsObj::DoInterpretedMotion: motion=44000007 run start [92] CMotionTable::DoObjectMotion: motion=44000007 [93] MotionTableManager::add_to_queue: arg1=44000007 arg2=00000001 [104] CMotionTable::StopObjectMotion: motion=44000007 run end Critical structural finding for #L.4-walk-run: Retail does NOT call truncate_animation_list during the walk→run transition. truncate_animation_list never fires in the entire 200-hit trace. Retail also does NOT call StopObjectMotion(WalkForward) before add_to_queue(RunForward). Retail just appends the new motion to the queue and lets MotionTableManager (and its CheckForCompletedMotions / remove_redundant_links per-tick cleanup, not yet traced) handle the natural progression. acdream's AnimationSequencer.SetCycle aggressively calls ClearCyclicTail() at line 430 BEFORE enqueuing the new cycle, which destroys the in-flight walk cycle's frames. The new run cycle is enqueued but _currNode is left in a state that doesn't smoothly continue — visible to the user as "it just blips forward walking, AS SOON as press another key like turning, its starts running" (the next motion event re-fires SetCycle which finally aligns state). Fix is a structural refactor of SetCycle to mirror retail's "additive queue with auto-cleanup" semantics. Out of scope for this research commit; filed as #L.4 in the next ISSUES.md entry. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
a45c21ee51
commit
b1d8e122ed
3 changed files with 191 additions and 0 deletions
16
tools/cdb-scripts/run_walk_run_trace.ps1
Normal file
16
tools/cdb-scripts/run_walk_run_trace.ps1
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
$cdb = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe"
|
||||
$script = "C:\Users\erikn\source\repos\acdream\tools\cdb-scripts\walk_run_motion_trace.cdb"
|
||||
$log = "C:\Users\erikn\source\repos\acdream\tools\cdb-scripts\walk_run_motion_trace.log"
|
||||
|
||||
if (Test-Path $log) { Remove-Item $log }
|
||||
|
||||
Write-Host "Attaching cdb to acclient.exe..."
|
||||
Write-Host "Once attached, do this in retail:"
|
||||
Write-Host " 1. Stand still 2s"
|
||||
Write-Host " 2. Hold shift+W (walk) 4s"
|
||||
Write-Host " 3. Release SHIFT only, keep W, 4s (this is what we want to capture)"
|
||||
Write-Host " 4. Release W"
|
||||
Write-Host " 5. Wait for cdb to detach (or Ctrl+C this PS to detach manually)"
|
||||
Write-Host ""
|
||||
|
||||
& $cdb -pn acclient.exe -cf $script *>&1 | Tee-Object -FilePath "$log.console"
|
||||
175
tools/cdb-scripts/walk_run_motion_trace.log
Normal file
175
tools/cdb-scripts/walk_run_motion_trace.log
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
Opened log file 'C:\Users\erikn\source\repos\acdream\tools\cdb-scripts\walk_run_motion_trace.log'
|
||||
0:017> .sympath C:\Users\erikn\source\repos\acdream\refs
|
||||
Symbol search path is: C:\Users\erikn\source\repos\acdream\refs
|
||||
Expanded Symbol search path is: c:\users\erikn\source\repos\acdream\refs
|
||||
|
||||
************* Path validation summary **************
|
||||
Response Time (ms) Location
|
||||
OK C:\Users\erikn\source\repos\acdream\refs
|
||||
0:017> .symopt+ 0x40
|
||||
Symbol options are 0xB0367:
|
||||
0x00000001 - SYMOPT_CASE_INSENSITIVE
|
||||
0x00000002 - SYMOPT_UNDNAME
|
||||
0x00000004 - SYMOPT_DEFERRED_LOADS
|
||||
0x00000020 - SYMOPT_OMAP_FIND_NEAREST
|
||||
0x00000040 - SYMOPT_LOAD_ANYTHING
|
||||
0x00000100 - SYMOPT_NO_UNQUALIFIED_LOADS
|
||||
0x00000200 - SYMOPT_FAIL_CRITICAL_ERRORS
|
||||
0x00010000 - SYMOPT_AUTO_PUBLICS
|
||||
0x00020000 - SYMOPT_NO_IMAGE_SEARCH
|
||||
0x00080000 - SYMOPT_NO_PROMPTS
|
||||
0:017> .reload /f acclient.exe
|
||||
0:017>
|
||||
0:017> r $t0 = 0
|
||||
0:017>
|
||||
0:017> bp acclient!CPhysicsObj::DoInterpretedMotion ".printf \"\\n[%d] CPhysicsObj::DoInterpretedMotion: motion=%08x speedBits=%08x\", @$t0, poi(esp+4), poi(esp+8); r $t0 = @$t0 + 1; .if (@$t0 >= 200) { .detach } .else { gc }"
|
||||
0:017>
|
||||
breakpoint 0 redefined
|
||||
0:017> bp acclient!CPartArray::DoInterpretedMotion ".printf \"\\n[%d] CPartArray::DoInterpretedMotion: motion=%08x speedBits=%08x\", @$t0, poi(esp+4), poi(esp+8); r $t0 = @$t0 + 1; .if (@$t0 >= 200) { .detach } .else { gc }"
|
||||
0:017>
|
||||
breakpoint 1 redefined
|
||||
0:017> bp acclient!MotionTableManager::PerformMovement ".printf \"\\n[%d] MotionTableManager::PerformMovement: motion=%08x speedBits=%08x holdkey=%08x\", @$t0, poi(esp+4), poi(esp+8), poi(esp+0xc); r $t0 = @$t0 + 1; .if (@$t0 >= 200) { .detach } .else { gc }"
|
||||
0:017>
|
||||
breakpoint 2 redefined
|
||||
0:017> bp acclient!MotionTableManager::add_to_queue ".printf \"\\n[%d] MotionTableManager::add_to_queue: arg1=%08x arg2=%08x\", @$t0, poi(esp+4), poi(esp+8); r $t0 = @$t0 + 1; .if (@$t0 >= 200) { .detach } .else { gc }"
|
||||
0:017>
|
||||
breakpoint 3 redefined
|
||||
0:017> bp acclient!MotionTableManager::truncate_animation_list ".printf \"\\n[%d] MotionTableManager::truncate_animation_list\", @$t0; r $t0 = @$t0 + 1; .if (@$t0 >= 200) { .detach } .else { gc }"
|
||||
0:017>
|
||||
breakpoint 4 redefined
|
||||
0:017> bp acclient!CMotionTable::DoObjectMotion ".printf \"\\n[%d] CMotionTable::DoObjectMotion: motion=%08x\", @$t0, poi(esp+4); r $t0 = @$t0 + 1; .if (@$t0 >= 200) { .detach } .else { gc }"
|
||||
0:017>
|
||||
breakpoint 5 redefined
|
||||
0:017> bp acclient!CMotionTable::StopObjectMotion ".printf \"\\n[%d] CMotionTable::StopObjectMotion: motion=%08x\", @$t0, poi(esp+4); r $t0 = @$t0 + 1; .if (@$t0 >= 200) { .detach } .else { gc }"
|
||||
0:017>
|
||||
breakpoint 6 redefined
|
||||
0:017> g
|
||||
|
||||
[0] MotionTableManager::PerformMovement: motion=001afc60 speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[1] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[2] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[3] MotionTableManager::PerformMovement: motion=001afc2c speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[4] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[5] MotionTableManager::PerformMovement: motion=001afbe4 speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[6] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[7] CPhysicsObj::DoInterpretedMotion: motion=6500000d speedBits=001afcc0
|
||||
[8] CPartArray::DoInterpretedMotion: motion=6500000d speedBits=001afcc0
|
||||
[9] MotionTableManager::PerformMovement: motion=001afc14 speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[10] CMotionTable::DoObjectMotion: motion=6500000d
|
||||
[11] MotionTableManager::add_to_queue: arg1=6500000d arg2=00000000
|
||||
[12] CPhysicsObj::DoInterpretedMotion: motion=8000003d speedBits=001afcb4
|
||||
[13] CPartArray::DoInterpretedMotion: motion=8000003d speedBits=001afcb4
|
||||
[14] MotionTableManager::PerformMovement: motion=001afc24 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[15] CMotionTable::DoObjectMotion: motion=8000003d
|
||||
[16] MotionTableManager::add_to_queue: arg1=8000003d arg2=00000000
|
||||
[17] CPhysicsObj::DoInterpretedMotion: motion=10000054 speedBits=001afcb4
|
||||
[18] CPartArray::DoInterpretedMotion: motion=10000054 speedBits=001afcb4
|
||||
[19] MotionTableManager::PerformMovement: motion=001afc24 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[20] CMotionTable::DoObjectMotion: motion=10000054
|
||||
[21] MotionTableManager::add_to_queue: arg1=10000054 arg2=00000001
|
||||
[22] MotionTableManager::PerformMovement: motion=001afc24 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[23] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[24] MotionTableManager::PerformMovement: motion=001afc40 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[25] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[26] CPhysicsObj::DoInterpretedMotion: motion=8000003d speedBits=001afcb4
|
||||
[27] CPartArray::DoInterpretedMotion: motion=8000003d speedBits=001afcb4
|
||||
[28] MotionTableManager::PerformMovement: motion=001afc24 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[29] CMotionTable::DoObjectMotion: motion=8000003d
|
||||
[30] MotionTableManager::add_to_queue: arg1=8000003d arg2=00000000
|
||||
[31] CPhysicsObj::DoInterpretedMotion: motion=41000003 speedBits=001afcb4
|
||||
[32] CPartArray::DoInterpretedMotion: motion=41000003 speedBits=001afcb4
|
||||
[33] MotionTableManager::PerformMovement: motion=001afc24 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[34] CMotionTable::DoObjectMotion: motion=41000003
|
||||
[35] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[36] MotionTableManager::PerformMovement: motion=001afc24 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[37] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[38] MotionTableManager::PerformMovement: motion=001afc40 speedBits=16f5e4f8 holdkey=16fa5218
|
||||
[39] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[40] CPhysicsObj::DoInterpretedMotion: motion=8000003d speedBits=001af5e8
|
||||
[41] CPartArray::DoInterpretedMotion: motion=8000003d speedBits=001af5e8
|
||||
[42] MotionTableManager::PerformMovement: motion=001af558 speedBits=15f356a0 holdkey=13cf1420
|
||||
[43] CMotionTable::DoObjectMotion: motion=8000003d
|
||||
[44] MotionTableManager::add_to_queue: arg1=8000003d arg2=00000000
|
||||
[45] CPhysicsObj::DoInterpretedMotion: motion=41000003 speedBits=001af5e8
|
||||
[46] CPartArray::DoInterpretedMotion: motion=41000003 speedBits=001af5e8
|
||||
[47] MotionTableManager::PerformMovement: motion=001af558 speedBits=15f356a0 holdkey=13cf1420
|
||||
[48] CMotionTable::DoObjectMotion: motion=41000003
|
||||
[49] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[50] MotionTableManager::PerformMovement: motion=001af558 speedBits=15f356a0 holdkey=13cf1420
|
||||
[51] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[52] MotionTableManager::PerformMovement: motion=001af574 speedBits=15f356a0 holdkey=13cf1420
|
||||
[53] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[54] MotionTableManager::PerformMovement: motion=001afc60 speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[55] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[56] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[57] MotionTableManager::PerformMovement: motion=001afc2c speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[58] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[59] MotionTableManager::PerformMovement: motion=001afbe4 speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[60] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[61] CPhysicsObj::DoInterpretedMotion: motion=6500000d speedBits=001afcc0
|
||||
[62] CPartArray::DoInterpretedMotion: motion=6500000d speedBits=001afcc0
|
||||
[63] MotionTableManager::PerformMovement: motion=001afc14 speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[64] CMotionTable::DoObjectMotion: motion=6500000d
|
||||
[65] MotionTableManager::add_to_queue: arg1=6500000d arg2=00000000
|
||||
[66] MotionTableManager::PerformMovement: motion=001af408 speedBits=15f356a0 holdkey=13cf1420
|
||||
[67] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[68] CPhysicsObj::DoInterpretedMotion: motion=41000003 speedBits=001af33c
|
||||
[69] CPartArray::DoInterpretedMotion: motion=41000003 speedBits=001af33c
|
||||
[70] MotionTableManager::PerformMovement: motion=001af2a0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[71] CMotionTable::DoObjectMotion: motion=41000003
|
||||
[72] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[73] MotionTableManager::PerformMovement: motion=001af2a0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[74] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[75] MotionTableManager::PerformMovement: motion=001af2a0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[76] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[77] MotionTableManager::PerformMovement: motion=001af2a0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[78] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[79] CPhysicsObj::DoInterpretedMotion: motion=45000005 speedBits=001af348
|
||||
[80] CPartArray::DoInterpretedMotion: motion=45000005 speedBits=001af348
|
||||
[81] MotionTableManager::PerformMovement: motion=001af2ac speedBits=15f356a0 holdkey=13cf1420
|
||||
[82] CMotionTable::DoObjectMotion: motion=45000005
|
||||
[83] MotionTableManager::add_to_queue: arg1=45000005 arg2=00000001
|
||||
[84] CPhysicsObj::DoInterpretedMotion: motion=8000003d speedBits=001af5e0
|
||||
[85] CPartArray::DoInterpretedMotion: motion=8000003d speedBits=001af5e0
|
||||
[86] MotionTableManager::PerformMovement: motion=001af550 speedBits=15f356a0 holdkey=13cf1420
|
||||
[87] CMotionTable::DoObjectMotion: motion=8000003d
|
||||
[88] MotionTableManager::add_to_queue: arg1=8000003d arg2=00000000
|
||||
[89] CPhysicsObj::DoInterpretedMotion: motion=44000007 speedBits=001af5e0
|
||||
[90] CPartArray::DoInterpretedMotion: motion=44000007 speedBits=001af5e0
|
||||
[91] MotionTableManager::PerformMovement: motion=001af550 speedBits=15f356a0 holdkey=13cf1420
|
||||
[92] CMotionTable::DoObjectMotion: motion=44000007
|
||||
[93] MotionTableManager::add_to_queue: arg1=44000007 arg2=00000001
|
||||
[94] MotionTableManager::PerformMovement: motion=001af550 speedBits=15f356a0 holdkey=13cf1420
|
||||
[95] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[96] MotionTableManager::PerformMovement: motion=001af56c speedBits=15f356a0 holdkey=13cf1420
|
||||
[97] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[98] MotionTableManager::PerformMovement: motion=001afcfc speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[99] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[100] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[101] MotionTableManager::PerformMovement: motion=001afc84 speedBits=16f5e1f8 holdkey=16fa5c38
|
||||
[102] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[103] MotionTableManager::PerformMovement: motion=001af2c0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[104] CMotionTable::StopObjectMotion: motion=44000007
|
||||
[105] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000001
|
||||
[106] CPhysicsObj::DoInterpretedMotion: motion=41000003 speedBits=001af4bc
|
||||
[107] CPartArray::DoInterpretedMotion: motion=41000003 speedBits=001af4bc
|
||||
[108] MotionTableManager::PerformMovement: motion=001af420 speedBits=15f356a0 holdkey=13cf1420
|
||||
[109] CMotionTable::DoObjectMotion: motion=41000003
|
||||
[110] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[111] MotionTableManager::PerformMovement: motion=001af420 speedBits=15f356a0 holdkey=13cf1420
|
||||
[112] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[113] MotionTableManager::PerformMovement: motion=001af420 speedBits=15f356a0 holdkey=13cf1420
|
||||
[114] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[115] MotionTableManager::PerformMovement: motion=001af420 speedBits=15f356a0 holdkey=13cf1420
|
||||
[116] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[117] CPhysicsObj::DoInterpretedMotion: motion=41000003 speedBits=001af47c
|
||||
[118] CPartArray::DoInterpretedMotion: motion=41000003 speedBits=001af47c
|
||||
[119] MotionTableManager::PerformMovement: motion=001af3e0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[120] CMotionTable::DoObjectMotion: motion=41000003
|
||||
[121] MotionTableManager::add_to_queue: arg1=41000003 arg2=00000000
|
||||
[122] MotionTableManager::PerformMovement: motion=001af3e0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[123] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
[124] MotionTableManager::PerformMovement: motion=001af3e0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[125] CMotionTable::StopObjectMotion: motion=6500000d
|
||||
[126] MotionTableManager::PerformMovement: motion=001af3e0 speedBits=15f356a0 holdkey=13cf1420
|
||||
[127] CMotionTable::StopObjectMotion: motion=6500000f
|
||||
0
tools/cdb-scripts/walk_run_motion_trace.log.console
Normal file
0
tools/cdb-scripts/walk_run_motion_trace.log.console
Normal file
Loading…
Add table
Add a link
Reference in a new issue