diff --git a/.gitignore b/.gitignore index af968b25..acdabd2c 100644 --- a/.gitignore +++ b/.gitignore @@ -41,26 +41,3 @@ tmp/ # Git worktrees for isolated feature work .worktrees/ - -# Per-session retail-debugger scratch — cdb scripts, logs, analysis helpers. -# The committed reference workflow lives in CLAUDE.md "Retail debugger toolchain"; -# session-specific traces should not pollute the repo. -*.cdb -launch_*.log -launch_*.err -launch_*.ps1 -launch[0-9]*.log -analyze_*.ps1 -peek_*.ps1 -run_cdb_*.ps1 -find_cdb.ps1 -find_acclient.ps1 -kill_cdb.ps1 -append_memory.ps1 -sky_*.log -smoke_test* -steep_roof_trace* -substep_trace* -sg_built.txt -# Stray bash-mangled path artifacts from PowerShell-via-bash escaping -C[€-￿]* diff --git a/CLAUDE.md b/CLAUDE.md index 75ff1fe1..2ec702dc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -112,51 +112,6 @@ a phase just landed, and move to the next todo item. always yes — keep going.** The single exception is visual verification; otherwise, act. -## Communication style - -The user is a strong systems / C# / network programmer but **less -practiced at 3D math, physics, graphics, and animation**. They want -to learn — they're not asking for dumbed-down content, but for -explanations that build understanding alongside the work. - -When discussing 3D / physics / graphics / animation / dat-format / -protocol-internals topics: - -- **Name the concept in plain language first**, then introduce the - term of art. "The angle of a slope (we call its straight-up - component `Normal.Z`)" rather than dropping `normal.Z = cos θ` - with no anchor. -- **Give units**: degrees, meters, cm — NOT raw floats. "FloorZ ≈ - 0.66 means slopes up to about 49° are walkable" rather than - "FloorZ = 0.66417414f". Floats are for the code; English is for - the conversation. -- **Use analogies for spatial concepts** when they fit. A BSP tree - is "a way of slicing space into nested rooms"; a contact plane is - "the imaginary floor under the player's feet"; a sphere sweep is - "rolling a ball forward through space and stopping it on contact"; - a cross product is "the direction perpendicular to two arrows"; - a dot product is "how aligned two arrows are (1 = same, 0 = - perpendicular, -1 = opposite)". -- **Don't pile on multiple new concepts in one paragraph.** If a - problem touches step-up AND step-down AND edge-slide AND - walkable-polygon tracking, walk through them one at a time, each - with what it does and why it exists. -- **Show the math when it matters, but explain it.** Don't just - drop a formula and move on; tag it with "what this means - geometrically". -- **Use frame-by-frame walk-throughs** for control-flow-heavy - physics: "frame N: player here, lands. Frame N+1: state checks…" - beats a function-call trace for understanding what's happening - in motion. -- **Flag terms of art** the first time they appear in a session, - even if they're sprinkled through code comments. "Broadphase", - "BSP", "step-up", "ContactPlane", "ValidateWalkable" — they - earn their meaning the first time you spell it out. - -The goal is collaborative learning. Don't simplify the content; just -make sure every term and number is grounded so the user can keep up -and build intuition over time. - ## Development workflow: grep named → decompile → verify → port **This is the mandatory workflow for implementing ANY AC-specific behavior.** @@ -164,22 +119,10 @@ 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. 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).** +from 30 minutes to 5 seconds.** ### 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 @@ -261,124 +204,6 @@ 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