diff --git a/CLAUDE.md b/CLAUDE.md index 328264c..75ff1fe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -164,10 +164,22 @@ The triangle-boundary Z bug cost 5 failed fix attempts from guessing. The animation frame-swap bug cost 4 failed attempts. Every time we checked the decompiled code first, we got it right on the first try. **Now we have named retail symbols too — Step 0 cuts most lookups -from 30 minutes to 5 seconds.** +from 30 minutes to 5 seconds. And as of 2026-04-30, when "what does +retail actually DO at runtime?" is the question and decomp alone +isn't enough, attach cdb to a live retail client (Step -1).** ### For each new feature or bug fix: +-1. **ATTACH cdb TO RETAIL (when behavior is the question, not code).** + For "what does retail actually DO frame-by-frame?" questions — + wedges, weird animation flicker, geometry-specific bugs, anything + where the decomp is correct but it's not clear how it produces the + visible behavior — **don't guess; attach the Windows debugger to + a live retail client and trace it.** See "Retail debugger toolchain" + below for setup. We discovered the steep-roof wedge had a 30Hz + physics-tick cause this way; would have taken weeks of guessing + without the trace. + 0. **GREP NAMED FIRST.** Before any decompilation work, search `docs/research/named-retail/acclient_2013_pseudo_c.txt` by `class::method` name. 99.6% of functions have real names from the @@ -249,6 +261,124 @@ Before marking any phase as done: - [ ] Roadmap updated - [ ] Memory updated if there's a durable lesson +## Retail debugger toolchain (live runtime trace) + +**When the question is "what does retail actually DO frame-by-frame?"** +the decomp alone is often not enough — code paths interact with state +(LastKnownContactPlane, transient flags, accumulated counters) in ways +that aren't obvious from reading. As of 2026-04-30 we have a working +toolchain to attach Windows' console debugger (cdb.exe) to a live +retail acclient.exe with full PDB symbols and capture state at any +breakpoint. **Use this when guessing has failed twice in a row.** + +### What we have + +- **Matching binary**: `C:\Turbine\Asheron's Call\acclient.exe` + v11.4186 (linker timestamp `2013-09-06 00:17:42 UTC`, + CodeView GUID `9e847e2f-777c-4bd9-886c-22256bb87f32`). Pairs + exactly with our `refs/acclient.pdb`. +- **Debugger**: `cdb.exe` (console WinDbg) at + `C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe`. + Install via Microsoft Store WinDbg (~50 MB). 32-bit version is + required for acclient.exe. +- **PDB**: `refs/acclient.pdb` (29 MB, Sept 2013 EoR build). + 18,366 named functions + 5,371 named struct types resolve. +- **Symbol verifier**: `tools/pdb-extract/check_exe_pdb.py ` + reads any acclient.exe and prints whether it pairs with our PDB + (`MATCH` / `MISMATCH (expected GUID = ...)`). Always run this on + a candidate binary BEFORE attaching. +- **PDB metadata dumper**: `tools/pdb-extract/dump_pdb_info.py refs/acclient.pdb` + prints the PDB's expected timestamp + GUID + age. Use to figure + out which build to look for if the chain ever breaks. + +### Workflow + +1. **Verify the binary matches the PDB:** + ```bash + py tools/pdb-extract/check_exe_pdb.py "C:/Turbine/Asheron's Call/acclient.exe" + ``` + Expect: `=== MATCH: this exe pairs with our acclient.pdb ===` + +2. **Have the user launch retail client** and connect to local ACE. + Retail must already be in-world before attaching. + +3. **Write a `.cdb` script** that arms breakpoints with non-blocking + actions (count + log + `gc`). Pattern: + ``` + .logopen + .sympath C:\Users\erikn\source\repos\acdream\refs + .symopt+ 0x40 + .reload /f acclient.exe + + r $t0 = 0 + bp acclient!CTransition::transitional_insert "r $t0 = @$t0 + 1; .if (@$t0 % 5000 == 0) { .printf \"...\" }; .if (@$t0 >= 30000) { qd } .else { gc }" + bp acclient!OBJECTINFO::kill_velocity "r $t1 = @$t1 + 1; gc" + ... + g + ``` + `gc` = "go conditional" (continue without breaking). Auto-detach + via `qd` after a hit-count threshold to avoid manual cleanup. + +4. **Launch cdb in the background** via a PowerShell wrapper: + ```powershell + & "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe" ` + -pn acclient.exe -cf