Research Notes
Deadlock ships as compiled Source 2 assets. Nothing here is documented by Valve, so everything we know is reverse-engineered against a specific game build and goes stale when the game patches.
This directory is the pattern for keeping that knowledge durable: one question per note, every claim stamped with the build it was verified against, and every claim reproducible by running a command.
The loop
ASK ──▶ VERIFY ──▶ WRITE ──▶ STAMP ──▶ RE-VERIFY (next patch)
│ │
└──────────────────────────────────────────┘
- Ask — Frame one answerable question. "Where do purchasable item stats live?" is a note. "How does Deadlock work?" is not.
- Verify — Answer it by running something against the real install. Never write down a claim sourced only from a forum post, a wiki, or a model's recollection. If a claim came from outside, re-derive it locally before it goes in a note.
- Write — Copy TEMPLATE.md to
NNNN-kebab-title.md. Paste the actual commands and their actual output. Trimmed output is fine; invented output is not. - Stamp — Fill
verified_againstwith the game build frompython tools/find_game.py. A note without a build stamp is a rumour. - Re-verify — After a patch, re-run the Reproduce block. Update or mark
stale.
Note status
| status | meaning |
|---|---|
draft | Being written. Claims not yet all verified. |
verified | Every claim reproduced against verified_against build. |
stale | Game has patched since; claims may no longer hold. Re-verify before trusting. |
superseded | Replaced. Points at the replacement in superseded_by. |
Rules that keep this useful
- One question per note. Notes that sprawl get skimmed and then trusted wrongly.
- Show the command. Every Findings section needs a matching Reproduce block. If you cannot write the command, you have not verified the claim.
- Record what you did not check. Open Questions is not optional filler — an unmarked gap reads as "covered", which is how bad data spreads.
- Prefer raw evidence over prose. A 5-line output excerpt beats a paragraph describing it.
- Separate observation from inference. "277 entries have
m_eAbilityType = "EAbilityType_Item"" is an observation. "There are 277 purchasable items" is an inference — flag it as one. - Codenames, not display names. Internal identifiers (
hero_inferno) are the stable key. Display names change and are localized.
Checking for staleness
python tools/find_game.py
Prints the installed build. Compare it against the verified_against field of the notes you are about to rely on. If they differ, treat those notes as stale until re-run.
Index
| # | Note | Status | Verified against |
|---|---|---|---|
| 0001 | VPK archive layout and inventory | verified | 6679 |
| 0002 | Gameplay data in vdata files | verified | 6679 |
| 0003 | Decompilation toolchain | verified | 6679 |
| 0004 | Localization and codename mapping | verified | 6679 |
| 0005 | Prior art and ecosystem | draft | 6679 |
| 0006 | Identifying file formats from headers | verified | 6679 |
| 0007 | KV3 text grammar and its traps | verified | 6679 |
| 0008 | KeyValues v1, and telling it apart from KV3 | verified | 6679 |
| 0009 | Machine-readable interaction and effect signals | verified | 6679 |
| 0010 | Programmatic match data and hero leaderboards | verified | 6679 |
| 0011 | The full programmatic API surface around Deadlock | verified | 6679 |
| 0012 | Shop filters and item build chains | verified | 6679 |
Keep this table in sync when adding a note. It is the only index; there is no generator.
Layout
docs/research/
README.md this file — the pattern
TEMPLATE.md copy this to start a note
NNNN-*.md the notes (Markdown only; the rendered site lives in site/)
tools/
find_game.py locate install, print build stamp
vpkdb.py searchable SQLite index of every archive
vpk_list.py enumerate VPK contents (stdlib only)
Tools here are deliberately dependency-free Python so any contributor — or any coding agent — can run them without a setup step. See AGENTS.md for how automated contributors should use this directory.