v2 dry-run produced correct hit counts but all %f field values
printed as 0.000000 — including BP6 threshold which the decomp says
must be 0.0871556997f (cos 85°). Root cause: cdb's MASM evaluator
returns dwo(addr) as a 32-bit integer; .printf %f expects a 64-bit
double; passing the integer to %f produces formatted-zero garbage.
Fix: switch all float-reading expressions to @@c++(*(float*)addr).
The C++ evaluator dereferences memory as a float pointer, returning
a proper float that .printf %f formats correctly. Integer reads (%d)
still use MASM dwo() — that works.
For double-indirect (pointer args), the form is
@@c++(*(float*)(*(unsigned int*)(@esp+N)+offset))
which reads the pointer at [esp+N], adds the offset, and treats the
result as a float pointer.
v2 capture preserved as retail-v2-zero-floats.log audit trail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces v1's broken-offset BP actions with PDB-authoritative field
reads. All offsets extracted from `dt acclient!TYPENAME` against the
loaded PDB (output preserved at tools/cdb/a6-types-dump.txt).
Key offsets:
Plane.N at +0x00, .d at +0x0c
CSphere.center at +0x00, .radius at +0x0c
CPolygon.plane at +0x20
SPHEREPATH.collide +0x104, .walkable_allowance +0x1b8, .walk_interp +0x1bc
CTransition.sphere_path +0x020 (so e.g. CTransition+0x174 = insert_type)
Per-BP arg-read fixes (all use __thiscall: ecx=this, args at [esp+N]):
BP1: substeps from [esp+4], insertType from this+0x174
BP2: walkable_allowance from this+0x1d8, normal.z from *(arg+8)
BP3: normal.x/y/z from *arg
BP4: collide+insertType via *(arg2+0x124/0x174), walkAllow from arg3
BP5 (the over-correction suspect): full plane + sphere + walk_interp +
movement vector. 12 fields, all double-indirect for pointer args.
BP6 SYMBOL FIXED: CTransition::check_walkable (v1 had
validate_walkable which doesn't exist; check_walkable confirmed
in symbols.json and at decomp line 272811).
BP7: plane + isWater from *arg.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dry-run of scenario 1 (retail-v1-broken-offsets.log preserved as
audit trail) surfaced three issues with the v1 cdb script:
1. STACK-ARG OFFSETS WRONG: BP actions used arbitrary registers
(@edx, @edi) to read function args, but __thiscall puts non-this
args on the stack ([esp+N] after the return address). All 12 BP5
"adjust_sphere" hits printed Nx=0.0 Ny=0.0 ... — fields not read.
Fixed by writing a type dumper (a6-types-dump.cdb + runner) that
uses cdb's `dt` command against the loaded PDB to get authoritative
struct offsets. v2 probe script (to be written next) will use
double-indirect reads (dwo(poi(@esp+N)+offset)) with correct
offsets from the dump.
2. TEE-OBJECT UTF-16 ENCODING: PowerShell's default Tee-Object writes
UTF-16 LE with BOM, making logs unparseable by grep without
conversion. Runner now uses Out-File -Encoding ASCII. Sacrifices
live console echo; use `Get-Content -Tail 50 -Wait` in a separate
shell if live monitoring is needed.
3. BP6 SYMBOL NOT FOUND: `acclient!CTransition::validate_walkable`
doesn't exist in the PDB. Decomp at line 272811 has
`CTransition::check_walkable` — likely the actual name. To be
verified + fixed in v2.
The BP hit-count distribution from v1 is still meaningful diagnostic
data (14,318 transitional_insert + 16,558 find_collisions + 40
set_contact_plane + 12 adjust_sphere + 1 step_up + 1 set_collide in
a 2-second walk through the inn doorway). Preserved as a baseline
sanity-check the v2 distribution can be diffed against.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Documents prerequisites (PDB match, cdb install, retail+ACE
running), per-scenario invocation, the 9-scenario tag table, and
the parallel acdream capture command. Includes the CLAUDE.md cdb
watchouts inline so probe operators don't have to chase them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wrapper that attaches cdb to a live retail acclient.exe with a
scenario-tagged log path. Per-scenario invocation:
.\tools\cdb\a6-probe-runner.ps1 -ScenarioTag "scen1_inn_doorway"
Output: docs\research\2026-05-21-a6-captures\<ScenarioTag>\retail.log
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sets non-blocking breakpoints on transitional_insert, step_up,
set_collide, find_collisions, adjust_sphere_to_plane,
validate_walkable, set_contact_plane. Each BP increments a counter
and emits a single printf line. Auto-detach via qd at 50K total
hits to avoid retail lag (CLAUDE.md gotcha — high BP rates trigger
ACE timeout).
Also adds !tools/cdb/*.cdb negation to .gitignore so committed
reference scripts in tools/cdb/ are tracked despite the blanket
*.cdb scratch-file rule.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>