Source-backed Darktide build intelligence. Maps community names to canonical game entities, audits builds against decompiled source, computes damage breakpoints via a 13-stage calculator, and scores builds across 7 dimensions.
Stable v1 commands:
- Resolve — map a community-facing name ("Warp Rider", "Blaze Away") to a canonical entity ID backed by decompiled source with evidence
- Audit — verify a build JSON: classify each field as resolved, ambiguous, unresolved, or known non-canonical
For covered shared weapons, resolve also accepts internal template ids and
BetterBots-style full content item paths such as
content/items/weapons/player/ranged/bot_lasgun_killshot.
Provisional surface:
- Canonicalize — convert a scraped/raw build JSON into the canonical build shape used by this repo
- Re-resolve — batch refresh unresolved or non-canonical selections in canonical build files when resolver coverage expands
- Score — 7-dimension build scoring (2 mechanical + 5 qualitative)
- Calc — 13-stage damage breakpoint calculator with per-weapon per-enemy per-difficulty hits-to-kill matrix
Not yet part of the public CLI contract:
- Inspect — implemented as
npm run inspect -- --id <canonical-entity-id>, but not part of the stable v1 contract - Coverage — implemented as
npm run coverage, but not part of the stable v1 contract
All stable output is machine-readable JSON with optional --text human-readable mode.
Commands that use the ground-truth resolver currently require a pinned, clean
checkout of Aussiemon/Darktide-Source-Code:
git clone --depth 1 https://github.com/Aussiemon/Darktide-Source-Code.git ../Darktide-Source-CodePass the path via GROUND_TRUTH_SOURCE_ROOT:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run resolve -- --query "Warp Rider" --context '{"kind":"talent","class":"psyker"}'
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run audit -- data/builds/08-gandalf-melee-wizard.json
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm test
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code make checkCurrent command requirements:
resolve— requiresGROUND_TRUTH_SOURCE_ROOTaudit— requiresGROUND_TRUTH_SOURCE_ROOTcanonicalize— requiresGROUND_TRUTH_SOURCE_ROOTreresolve— requiresGROUND_TRUTH_SOURCE_ROOTindex:build/index:check/test/check— requireGROUND_TRUTH_SOURCE_ROOTtrees:build/breeds:build/profiles:build— requireGROUND_TRUTH_SOURCE_ROOTcalc— requiresGROUND_TRUTH_SOURCE_ROOT(reads generated data frombreeds:build+profiles:build)score— does not requireGROUND_TRUTH_SOURCE_ROOT(but includes breakpoint scoring when calc data available)
If GROUND_TRUTH_SOURCE_ROOT is missing or points at the wrong pinned revision,
resolver/index/test commands fail deliberately with explicit setup guidance.
Generated artifacts under data/ground-truth/generated/ are build outputs and
remain gitignored.
Install dependencies:
npm installResolve one query:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run resolve -- --query "Warp Rider" --context '{"kind":"talent","class":"psyker"}'Resolve a BetterBots profile weapon path:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run resolve -- --query "content/items/weapons/player/ranged/bot_lasgun_killshot" --context '{"kind":"weapon","slot":"ranged"}'Audit a build file:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run audit -- data/builds/08-zealot-chorus-swiss-knife.jsonCanonicalize a scraped/raw build file:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run canonicalize -- data/sample-build.jsonRe-resolve canonical build files in place:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run reresolve -- --write data/buildsBuild the generated index:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run index:buildRun the full verification flow:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code make checkWebsite browser smoke flow:
# terminal 1: serve static preview
make website-preview
# terminal 2: open compare page in named Playwright session
make website-smoke ARGS='open-compare 09-psyker-2026 01-veteran-havoc40-2026'
# terminal 2: inspect current page
make website-smoke ARGS='snapshot'
make website-smoke ARGS='screenshot'
# terminal 2: close browser session
make website-smoke ARGS='close'Notes:
scripts/website-smoke.shdefaults toPLAYWRIGHT_CLI_SESSION=hb-website,HB_WEBSITE_HOST=127.0.0.1,HB_WEBSITE_PORT=4173- the Playwright CLI wrapper must exist and be executable at
~/.codex/skills/playwright/scripts/playwright_cli.sh - under Codex, browser launch and local port binding usually require sandbox escape; run these commands outside sandbox if you hit Chromium or
listen EPERMerrors
Build scoring on canonical build fixtures:
npm run score -- data/builds/08-zealot-chorus-swiss-knife.json --json
npm run score -- data/builds/08-zealot-chorus-swiss-knife.json --textDamage breakpoint calculator:
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run calc -- data/builds/08-zealot-chorus-swiss-knife.json
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run calc -- data/builds/08-zealot-chorus-swiss-knife.json --json
GROUND_TRUTH_SOURCE_ROOT=../Darktide-Source-Code npm run calc -- data/builds/ --json # batchRegenerate tree edges from Lua source (requires source root):
npm run edges:buildBuild talent-tree DAGs from Lua source (requires source root):
npm run trees:buildMirror website-facing art assets:
npm run icons:build
npm run weapons:buildRead-only coverage summary:
npm run coverageRead-only canonical entity inspection:
npm run inspect -- --id psyker.talent.psyker_damage_based_on_warp_chargeCurrent entity coverage (1376 total: 768 non-tree + 608 tree_node):
| Domain | Entities | Tree Nodes | Aliases | Edges | Notes |
|---|---|---|---|---|---|
| Shared | 200 | — | 134 | 76 | weapons, weapon perks, curio perks, blessing families, stat nodes, classes, buffs |
| Psyker | 89 | 111 | 76 | 255 | full tree DAG with exclusive_with edges |
| Ogryn | 85 | 108 | 85 | 240 | tree DAG (9 edges skipped — missing talent entities) |
| Arbites | 82 | 110 | — | 259 | tree DAG (5 edges skipped) |
| Hive Scum | 103 | 83 | — | 236 | tree DAG (5 edges skipped) |
| Zealot | 57 | 89 | 57 | 210 | tree DAG (24 edges skipped) |
| Veteran | 43 | 107 | 44 | 211 | tree DAG (40 edges skipped) |
Tree edges are generated from Lua source via npm run edges:build. Skipped edges reference
talent entities not yet in ground-truth — they appear automatically as entity coverage grows.
All 24 build fixtures (all 6 classes) are stored in canonical build shape, re-extracted from live Games Lantern pages with full talent trees.
Audit totals across all 24 fixtures: 1275 resolved / 0 unresolved / 72
non_canonical / 0 ambiguous. The non_canonical bucket in the fixtures is
the four curio cosmetic base labels whose concrete runtime variants are
collapsed by the Games Lantern scrape; the live dump helper in
tools/darktide-mods/curio_dump/ confirms 21 such ambiguous base labels in
the full curio catalog.
#1TypeScript migration#2Human-readable audit/report layer#3Build-oriented CLI (browse, compare)(resolved)#4BetterBots integration contract(resolved)#5Calculator and dataflow layer#6Website (SvelteKit + Svelte Flow talent tree)
MIT