A reverse-engineering canon for Diablo II: Lord of Destruction 1.13c (32-bit). 1,134 records covering functions, globals, structs, hooks and findings — every one carrying an explicit trust level, because most of them are not independently verified.
trust: verified — and a few of those carry status: superseded (rigorously derived, later disproven), so trust alone is not enough. 396 are trusted, 384 are sourced (community corpus), 90 are untagged and 2 are plausible. Applying both filters below leaves 255. Many sourced records carry the note
"addresses may be 1.10f-era — rebase to 1.13c + verify before use." Treat an unverified record as
a lead, not a fact.| File | Size | Use it for |
|---|---|---|
| symbols.jsonl | 1.6 MB | Start here if you are a program or a model. Line-delimited JSON — one record per line, parse with a loop. The canonical form; everything else is derived from it. |
| GRIMOIRE.md | 1.3 MB | The same corpus as prose Markdown, grouped and cross-referenced. Better for reading and reasoning end-to-end; worse for lookup. |
| search.html | 3.0 MB | Human browsing — self-contained page with client-side search over every record. Not useful to a crawler: the search needs JavaScript, so fetch the two files above instead. |
Eight documents the records cite directly, published so those citations resolve. They are
lab notes, not essays — written to survive a hostile fact-check rather than
to be read for pleasure, and internal in register. Absolute paths like
C:\Diablo II\BH 1.5s2-1.13c\BH.dll appear throughout on purpose: they record
which binary was measured, which is the difference between a measurement and a claim.
| Document | Size | What it is |
|---|---|---|
| research/BH-CONFIG-HOTSWAP.md | 13 KB | Swapping a loot filter's config at runtime, including the version that logged success and changed nothing, and the fault guard the optimiser silently deleted. |
| research/LIFEBAR-COORDINATE-ORIGIN.md | 54 KB | Deriving a unit's screen position from its cached iso coordinates, with both camera corrections. The longest of these and the most worked-through. |
| research/WHIST-113c-COMPILATION-INDEX.md | 44 KB | An index over a community address compilation. See the note below. |
| kb/reference/d2-re-reference-1.13c.md | 26 KB | General 1.13c reverse-engineering reference. |
| research/HARDCODED-MONSTER-INDICES.md | 13 KB | Monster indices the engine hardcodes rather than reading from a table. |
| research/SOUND-VOLUME-EDITS.md | 7 KB | Every changed row of the sound-volume pass, with before and after values. |
| research/MODULE-BASE-MAP.md | 3 KB | Module load addresses, and which of them relocate. |
| tools/dc6/count_arrow_removals.py | 5 KB | Counts edited regions between two DC6 sprite sheets. Histogram-matches luminance first, because a global tone shift otherwise reports thousands of false differences. |
WHIST-113c-COMPILATION-INDEX.md is an index over an address
compilation assembled by whist. The compilation is whist's work, not
Doug's. What is his in that document is the verification pass — checking those
addresses against live binaries and recording which held. Nothing in it claims the underlying
compilation, and it should not be read as doing so.
Two shapes coexist. The older, dominant shape is keyed on desc; 419 newer records use title/body. Handle both.
{
"id": "D2Client.DrawGame", // unique key, referenced by refs[]
"kind": "function", // see distribution below
"module": "D2Client", // owning module (89% of records)
"rva": "0x44230", // offset from module base (17% of records)
"status": "verified", // sourced | verified | confirmed | open | testing | closed | noted
"trust": "verified", // verified | trusted | sourced <-- READ THIS FIELD
"desc": "main world render entry…",
"source": "['re:esoteric']", // provenance; 'discord:…' = community corpus
"note": "corpus-sourced; may be 1.10f-era — rebase + verify",
"locator": "…", "value": "…", "refs": ["other.record.id"], "fields": […]
}
function 296finding 286global 160note 151struct 131reference 75solution 16openquestion 11hook 4other 4
verified 262trusted 396 sourced 384untagged 90plausible 2
VA = module_base + rva. Bases are the stock load addresses; ASLR is not in play for these
DLLs on a normal install, but confirm against your own process before trusting a computed VA.
| Module | Base | Module | Base |
|---|---|---|---|
| D2Client.dll | 0x6FAB0000 | D2Common.dll | 0x6FD50000 |
| D2Game.dll | 0x6FC20000 | D2Win.dll | 0x6F8E0000 |
| D2Gfx.dll | 0x6FA80000 | D2Glide.dll | 0x6F850000 |
| Fog.dll | 0x6FF50000 | ||
Note: D2Win's 1.10f base is 0x6F8A0000
and its 1.13c base is 0x6F8E0000 — a frequent source of bogus cross-version conclusions.
trust == "verified" and status not in ("superseded","failed","decoy"). They are orthogonal and you need both — trust records how well-sourced a claim was, status records whether it survived. A rigorously-derived claim later falsified keeps trust: verified and gets status: superseded, with its desc opening in a bracketed [SUPERSEDED <date>: <why>] block naming what fell and what still stands. Filtering on trust alone will hand you disproven theories.refs[] to assemble context; kind:"finding" and kind:"note"
records carry the reasoning, not just the addresses.kind:"openquestion" (11 records) — those are the known-unknowns, and the most useful
place to contribute.sourced as a hypothesis to test against the binary.[SUPERSEDED …] prefix before reusing any address from one.