acdream/tools/cdb/issue98-runner.ps1
Erik 6f666c14da tools(cdb): A6.P3 #98 Step 4 — retail find_walkable capture script
Step 4 of the apparatus plan. Adds the cdb script + runner that pairs
with Issue98CellarUpReplayTests to compare retail's walkable-query
behavior against acdream's during the Holtburg cottage cellar ascent.

Breakpoints (all symbols verified against refs/acclient.pdb via grep
docs/research/named-retail/symbols.json):
- BPA: BSPLEAF::find_walkable          — leaf-level walkable query
- BPB: CPolygon::walkable_hits_sphere  — per-polygon overlap test
- BPC: CPolygon::find_crossed_edge     — per-polygon edge containment
- BPD: CTransition::check_other_cells  — outer dispatcher
- BPE: COLLISIONINFO::set_contact_plane — GOLD signal: retail accepted
                                          this plane
- BPF: CPolygon::adjust_sphere_to_plane — per-polygon projection

Output format: 32-bit hex bits for all floats via dwo() + %08X (cdb's
%f handling is broken for dwo reads; see a6-probe.cdb v3→v4 history).
Decoder: tools/cdb/decode_retail_hex.py already handles _h=0x... fields.

Auto-detach threshold: 50000 hits across BPA/B/C/D/F. BPE is unbounded
(contact plane writes are rare, ~18 per ascent per slice 5 capture).

Runner: tools/cdb/issue98-runner.ps1
  .\tools\cdb\issue98-runner.ps1 -ScenarioTag "cellar_up_attempt_1"

Prereqs (per CLAUDE.md retail debugger toolchain section):
- Retail acclient.exe v11.4186 running and in-world
- ACE running on 127.0.0.1:9000
- Character at the BOTTOM of a Holtburg cottage cellar stair
- cdb.exe present at the Windows Kits 10 path

Output:
  docs\research\2026-05-23-a6-captures\<ScenarioTag>\retail.log

Reading the log:
- [BPE] lines tell you which plane retail accepted (the answer we need).
- Cross-reference [BPE]'s normal/d against the cell fixtures in
  tests/AcDream.Core.Tests/Fixtures/issue98/*.json to identify which
  cell + polyId retail picked.
- The divergence between retail's accepted polygon and our replay test's
  "no walkable accepted" result IS the fix target.

The capture itself is a user action (cdb requires a live retail
process); this commit only ships the protocol. Step 5 (comparison doc)
follows after the capture lands.
2026-05-23 15:29:02 +02:00

80 lines
3.2 KiB
PowerShell

# A6.P3 issue #98 cdb capture runner — 2026-05-23
#
# Attaches cdb to a live retail acclient.exe with
# issue98-cellar-up-find-walkable.cdb. Pairs with
# tests/AcDream.Core.Tests/Physics/Issue98CellarUpReplayTests.cs to
# answer: which polygon does retail accept during cellar ascent, in
# which cell, at what sphere position?
#
# Per-capture usage:
# .\tools\cdb\issue98-runner.ps1 -ScenarioTag "cellar_up_attempt_1"
#
# Prerequisites:
# 1. Retail acclient.exe v11.4186 running and in-world (matches
# refs/acclient.pdb). Verify with:
# py tools\pdb-extract\check_exe_pdb.py "C:\Turbine\Asheron's Call\acclient.exe"
# 2. ACE running locally on 127.0.0.1:9000.
# 3. Retail character at the BOTTOM of a Holtburg cottage cellar
# stair. Take a long breath; the next walk-forward is the capture
# window. cdb auto-detaches at 50,000 BP hits (~5-20s of motion).
#
# Output:
# docs\research\2026-05-23-a6-captures\<ScenarioTag>\retail.log
#
# Reading the log:
# The relevant signal is [BPE] set_contact_plane lines — these tell
# you which plane retail accepted. Then trace back through [BPA]
# find_walkable + [BPF] adjust_sphere entries to see the sphere
# position + polygon when that acceptance happened. Cross-reference
# the polygon plane normal/d against the cell fixtures in
# tests/AcDream.Core.Tests/Fixtures/issue98/0x*.json to identify which
# cell + polyId retail picked.
param(
[Parameter(Mandatory=$true)]
[string]$ScenarioTag
)
$cdbExe = "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe"
if (-not (Test-Path $cdbExe)) {
Write-Error "cdb.exe not found at $cdbExe. Install Microsoft Store WinDbg (~50 MB)."
exit 1
}
$scriptPath = Join-Path $PSScriptRoot "issue98-cellar-up-find-walkable.cdb"
if (-not (Test-Path $scriptPath)) {
Write-Error "issue98-cellar-up-find-walkable.cdb not found at $scriptPath."
exit 1
}
$captureDir = Join-Path $PSScriptRoot "..\..\docs\research\2026-05-23-a6-captures\$ScenarioTag"
if (-not (Test-Path $captureDir)) {
New-Item -ItemType Directory -Path $captureDir -Force | Out-Null
}
$logPath = Join-Path $captureDir "retail.log"
# Substitute ${ARG_LOG_TAG} in the .cdb script.
$scriptContent = Get-Content $scriptPath -Raw
$patchedScript = $scriptContent -replace '\$\{ARG_LOG_TAG\}', $ScenarioTag
$tempScript = Join-Path $env:TEMP "issue98-$ScenarioTag.cdb"
Set-Content -Path $tempScript -Value $patchedScript -Encoding ASCII
Write-Host "Attaching cdb to acclient.exe with scenario tag '$ScenarioTag'..."
Write-Host "Log: $logPath"
Write-Host "Script: $tempScript"
Write-Host "(cdb auto-detaches at 50K total hits across BPA/B/C/D/F; BPE unbounded.)"
Write-Host ""
Write-Host "TRIGGER: walk forward from the bottom of the cellar stair NOW."
Write-Host ""
# ASCII output so subsequent grep does not have to deal with UTF-16 BOM.
& $cdbExe -pn acclient.exe -cf $tempScript 2>&1 | Out-File -FilePath $logPath -Encoding ASCII
Remove-Item $tempScript -ErrorAction SilentlyContinue
Write-Host ""
Write-Host "Capture complete. Log saved to $logPath"
Write-Host "Decode floats: dwo() hex bits → struct.unpack('<f', bytes.fromhex(...))"
Write-Host "Decode helper: tools/cdb/decode_retail_hex.py"