docs(research): commit named retail decomp + spells.csv (foundation)
Move the high-value retail RE artifacts from refs/ (per-developer
download cache, gitignored) into committed paths so subagents +
post-compaction sessions inherit them without round-tripping:
- docs/research/named-retail/acclient_2013_pseudo_c.txt (62 MB,
Binary Ninja named pseudo-C, 99.6% function-name recovery —
18,366 named functions out of 18,598 public symbols)
- docs/research/named-retail/acclient.h (1.7 MB / 70,719 lines,
IDA-decompiled retail struct definitions verbatim — Attribute,
SecondaryAttribute, AttributeCache, Attribute2ndTable, SkillFormula,
Enchantment, CEnchantmentRegistry with _mult_list/_add_list/_vitae,
CSpellBook, MotionState, RawMotionState, MoveToStatePack, CACQualities,
CPhysicsObj — every retail object-model layout we'd otherwise have
to guess at)
- docs/research/named-retail/acclient.c (46 MB, secondary named
decomp — IDA full-binary export with mixed FUN_/named functions
plus named struct fields the chunked Ghidra output lacks)
- docs/research/data/spells.csv (3,956 spells × 35 cols including
Family for buff stacking — issue #6 unblocked)
actestclient-master vendored at references/actestclient/ (extracted
from refs/actestclient-master-2019-01-10.zip; contains the canonical
machine-readable wire-schema messages.xml). Covered by existing
references/ gitignore — per-developer reference, not committed.
Repo precedent for committing decompiled retail content was set at
commit 4d36756 (18 MB Ghidra chunks). This adds ~110 MB more of the
same qualitative content. Ripgrep handles it in <1s.
Foundation for the named-retail workflow change in CLAUDE.md (next
commit). Plan at C:/Users/erikn/.claude/plans/ticklish-conjuring-cake.md
Phase A.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7da2a027d4
commit
a9a01d8ba2
7 changed files with 2839946 additions and 0 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -31,3 +31,7 @@ imgui.ini
|
||||||
|
|
||||||
# User-only download cache (per-developer, not source)
|
# User-only download cache (per-developer, not source)
|
||||||
refs/
|
refs/
|
||||||
|
|
||||||
|
# Python tooling (under tools/) — bytecode caches
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
|
||||||
29
docs/research/data/README.md
Normal file
29
docs/research/data/README.md
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Game-data tables
|
||||||
|
|
||||||
|
Reference data tables loaded by acdream at runtime or used as research
|
||||||
|
input. Tracked in git so subagents + post-compaction sessions inherit
|
||||||
|
them without round-tripping through `refs/`.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
| File | Loader | Notes |
|
||||||
|
|------|--------|-------|
|
||||||
|
| `spells.csv` | `src/AcDream.Core/Spells/SpellTable.cs` (load via `SpellTable.LoadFromCsv` at `GameWindow.OnLoad`). Copied to `bin/<config>/net10.0/data/spells.csv` via `<None Update>` in `AcDream.App.csproj`. | 3,956 retail spells × 35 columns. Key fields: `Spell ID`, `Name`, `School`, `Family` (buff stacking bucket — issue #6 needs this), `IconId [Hex]`, `Mana`, `Duration`, `IsDebuff`, `IsFellowship`, `Description`. |
|
||||||
|
|
||||||
|
## Format note — `spells.csv`
|
||||||
|
|
||||||
|
RFC 4180 with header row. The `Description` column is quoted with embedded
|
||||||
|
commas; everything else is plain. See `SpellTable` parser for the canonical
|
||||||
|
column ordering.
|
||||||
|
|
||||||
|
## Provenance
|
||||||
|
|
||||||
|
`spells.csv` came from a server-side database export of the retail
|
||||||
|
spell table (likely a community-shared dump from circa 2017-2019 with
|
||||||
|
~99% field coverage). Spell IDs match the wire opcodes used by ACE.
|
||||||
|
The `Family` column is the AC retail spell-family enum used for buff
|
||||||
|
stacking.
|
||||||
|
|
||||||
|
If the file ever needs updating from a fresher source, replace
|
||||||
|
`spells.csv` in this directory; the `<None Update PreserveNewest>`
|
||||||
|
copy will sync it to bin output on next build.
|
||||||
3957
docs/research/data/spells.csv
Normal file
3957
docs/research/data/spells.csv
Normal file
File diff suppressed because it is too large
Load diff
70
docs/research/named-retail/README.md
Normal file
70
docs/research/named-retail/README.md
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
# Named-retail decompilation reference
|
||||||
|
|
||||||
|
**This is the primary reference for any AC-specific algorithm, formula,
|
||||||
|
constant, wire format, or coordinate convention.** Every retail symbol
|
||||||
|
question goes here first — _before_ touching `docs/research/decompiled/`
|
||||||
|
(the older Ghidra `FUN_xxx` chunks, which remain a fallback for
|
||||||
|
chunk-by-chunk address-range navigation).
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
| File | Source | Use for |
|
||||||
|
|------|--------|---------|
|
||||||
|
| `acclient_2013_pseudo_c.txt` | Binary Ninja pseudo-C export of the Sept 2013 EoR `acclient.exe` build. 1,437,645 lines. **99.6% function-name recovery** (54,873 named, 232 still `sub_*`). Class names + method names + many struct field names recovered. | **Primary symbol lookup.** Grep by `class::method` to find function bodies. Address-prefixed lines: `00<address> <return-type> __<conv> Class::Method(args)`. |
|
||||||
|
| `acclient.h` | IDA-decompiled retail headers. 70,719 lines / 1.7 MB. Full struct + class definitions for the entire AC client object model: `Attribute`, `SecondaryAttribute`, `AttributeCache`, `Attribute2ndTable`, `SkillFormula`, `Enchantment`, `CEnchantmentRegistry` (with `_mult_list` / `_add_list` / `_vitae`), `CSpellBook`, `MotionState`, `RawMotionState`, `MoveToStatePack`, `CACQualities`, `CPhysicsObj`. | **Struct field names + offsets.** When you need to know what a field is actually called, grep this file. |
|
||||||
|
| `acclient.c` | Ghidra (or IDA) full-binary decomp export. 1,327,522 lines / 46 MB. Mixed naming: ~5,100 named methods + ~8,553 still `FUN_xxx`. Has named struct types like `_max_health`, `_add_list` that the chunked Ghidra export under `decompiled/` lacks. | **Secondary cross-reference.** Useful when pseudo-C body is corrupt / packed and you need a different decompiler's view. |
|
||||||
|
| `symbols.json` | Generated by `tools/pdb-extract/` from `refs/acclient.pdb`. 18,366 entries: `{"address", "name", "obj_module"}`. | **Programmatic symbol lookup.** `jq '.[] | select(.name == "...")'` returns the start address. |
|
||||||
|
| `types.json` | Generated by `tools/pdb-extract/`. 3,172 named struct/class type records with field offsets + sizes. | **Programmatic type-layout queries.** |
|
||||||
|
|
||||||
|
## Workflow — grep first, decompile second
|
||||||
|
|
||||||
|
The `CLAUDE.md` "Development workflow" mandates **Step 0: GREP NAMED FIRST**
|
||||||
|
before any decompilation work. Concretely:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Find a function by class::method:
|
||||||
|
grep -n "CEnchantmentRegistry::EnchantAttribute" docs/research/named-retail/acclient_2013_pseudo_c.txt
|
||||||
|
|
||||||
|
# Find a struct definition:
|
||||||
|
grep -n "^struct.*CEnchantmentRegistry" docs/research/named-retail/acclient.h
|
||||||
|
|
||||||
|
# Find by raw address (PDB and pseudo-C addresses match):
|
||||||
|
grep -n "^00594570" docs/research/named-retail/acclient_2013_pseudo_c.txt
|
||||||
|
|
||||||
|
# Programmatic symbol lookup:
|
||||||
|
cat docs/research/named-retail/symbols.json | jq '.[] | select(.name == "CEnchantmentRegistry::EnchantAttribute")'
|
||||||
|
```
|
||||||
|
|
||||||
|
Only fall back to `docs/research/decompiled/chunk_*.c` (Ghidra `FUN_xxx`
|
||||||
|
chunks) when the named pseudo-C lacks a function — rare; covers only the
|
||||||
|
obfuscated/packed minority.
|
||||||
|
|
||||||
|
## Origin
|
||||||
|
|
||||||
|
- **PDB**: `refs/acclient.pdb` — Sept 2013 End-of-Retail (EoR) build, MSVC
|
||||||
|
7.00 program database, 29 MB. Build root: `d:\ac1_sep13\`.
|
||||||
|
- **pseudo-C**: Binary Ninja export of the `acclient_2013-2024-09-11.bndb`
|
||||||
|
database (also in `refs/`). 99.6% naming via PDB-overlay analysis.
|
||||||
|
- **acclient.h**: IDA-decompiled headers from a parallel RE effort.
|
||||||
|
- **acclient.c**: full-binary IDA/Ghidra decomp export (different from our
|
||||||
|
Ghidra chunks under `decompiled/`).
|
||||||
|
|
||||||
|
The `refs/` directory is gitignored (per-developer download cache); these
|
||||||
|
extracts are committed so subagents and post-compaction sessions inherit
|
||||||
|
them automatically.
|
||||||
|
|
||||||
|
## Address mapping caveat
|
||||||
|
|
||||||
|
The PDB is from a slightly different build run than the binary that
|
||||||
|
produced our Ghidra chunks (~0xC00 byte delta on some functions). When
|
||||||
|
correcting addresses in `docs/research/acclient_function_map.md`, **match
|
||||||
|
by name, not by raw address.**
|
||||||
|
|
||||||
|
## Regenerating `symbols.json` / `types.json`
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
py tools\pdb-extract\pdb_extract.py refs\acclient.pdb
|
||||||
|
```
|
||||||
|
|
||||||
|
Outputs land in `docs/research/named-retail/symbols.json` and
|
||||||
|
`docs/research/named-retail/types.json`. See `tools/pdb-extract/README.md`.
|
||||||
1327522
docs/research/named-retail/acclient.c
Normal file
1327522
docs/research/named-retail/acclient.c
Normal file
File diff suppressed because it is too large
Load diff
70719
docs/research/named-retail/acclient.h
Normal file
70719
docs/research/named-retail/acclient.h
Normal file
File diff suppressed because it is too large
Load diff
1437645
docs/research/named-retail/acclient_2013_pseudo_c.txt
Normal file
1437645
docs/research/named-retail/acclient_2013_pseudo_c.txt
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue