About crabsmadethis/d2r-horadric-tools
crabsmadethis/d2r-horadric-tools is an MCP server in the Blockchain category: backed mod build/deploy pipeline (overlays, JSON string patches, dataversionbuild). Linux / Steam Deck (Proton).
Install
git clone https://github.com/crabsmadethis/d2r-horadric-toolsThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about crabsmadethis/d2r-horadric-tools
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
d2r-tools
D2R modding toolkit for Linux and Steam Deck (Proton). YAML-driven character builder, data modding pipeline, and an MCP server that exposes the tools to agentic clients (Claude Code, Codex, Cursor, etc.).
Features
- YAML character builder - declare characters in YAML, build
.d2ssave files - Data mod pipeline - YAML overlays applied to game tables, built and deployed
- JSON string patches - rename or add item / UI strings via YAML, no string-table surgery
- CASC read/write - pure Python, no external tools needed
- Integrated validation - scanner catches structural problems before loading the game
- Reign of the Warlock expansion support (8 classes including Warlock)
Quickstart
git clone <repo-url>
cd d2r-tools
pip3 install -e .
d2r-mod extract # extracts + generates data from your D2R install
d2r-chargen build MyChar
(or pip install -e . if pip points to Python 3 on your system)
Three commands from clone to working. The extract step generates Python data modules from your D2R installation (required for legal reasons - no game data is distributed).
# If D2R is not auto-detected:
d2r-mod extract --game-dir /path/to/Diablo\ II\ Resurrected
# Or set the environment variable:
export D2R_GAME_DIR="/path/to/Diablo II Resurrected"
An example character YAML is included in chars/ExamplePaladin.yaml.
Create your own characters in the chars/ directory.
D2R install path is auto-detected on Linux/Steam Deck and Windows. Use --game-dir to override.
Character Definition (YAML)
Characters are defined in YAML files placed in a chars/ directory. Here's a complete example:
schema_version: 1
name: MyPaladin
class: paladin
level: 85
stats:
strength: 156
dexterity: 100
vitality: 250
energy: 15
skills:
Holy Shield: 20
Smite: 20
Fanaticism: 20
Charge: 1
Salvation: 1
Cleansing: 1
equipment:
# Unique items - resolved automatically from game data
- slot: helm
unique: Guillaume's Face
# Runeword items - specify runeword name and base item code
- slot: body
runeword: Fortitude
base: utp # Archon Plate
# Rare/crafted items with explicit properties
- slot: hands
rare: true
base: uvg # Vampirebone Gloves
ilvl: 90
properties:
fire_res: 30
cold_res: 30
light_res: 30
life: 20
- slot: weapon
unique: Grief
base: 7cr # Phase Blade
- slot: shield
unique: Herald of Zakarum
- slot: belt
unique: Verdungo's Hearty Cord
- slot: feet
unique: Gore Rider
- slot: neck
rare: true
ilvl: 90
properties:
class_skills: [2, paladin]
fcr: 10
fire_res: 30
light_res: 25
- slot: ring_right
unique: Bul Katho's Wedding Band
- slot: ring_left
unique: Ravenfrost
inventory:
charms:
# Unique charms
- unique: Annihilus
properties:
all_skills: 1
strength: 20
dexterity: 20
fire_res: 20
cold_res: 20
light_res: 20
poison_res: 20
add_exp: 10
# Repeatable magic charms
- magic_grand_charm:
count: 8
properties:
skill_tab: [1, 15] # Combat skills (paladin)
life: 40
- magic_small_charm:
count: 5
properties:
life: 20
light_res: 11
merc:
equipment:
- slot: weapon
unique: The Reaper's Toll
ethereal: true
Slot Names
helm, body, weapon, shield, hands, belt, feet, neck, ring_right, ring_left, weapon_switch, shield_switch
Item Types
| Field | Description |
|---|---|
unique: "Name" |
Unique item - stats auto-resolved from game data |
set_item: "Name" |
Set item |
runeword: "Name" |
Runeword - requires base code |
rare: true |
Rare item - requires base and properties |
magic_grand_charm |
Magic grand charm with count and properties |
magic_small_charm |
Magic small charm with count and properties |
Classes
amazon, sorceress, necromancer, paladin, barbarian, druid, assassin, warlock
CLI Reference
d2r-chargen
d2r-chargen build <name> [--phase N] [--force] # Build character (phases 1-4)
d2r-chargen validate <name> [--yaml-only] # Validate YAML definition
d2r-chargen list # List defined characters
d2r-chargen scan <name> # Run scanner diagnostics
d2r-chargen import <name> [--force] # Import .d2s -> YAML
d2r-chargen diff <file1> <file2> # Compare .d2s files
d2r-mod
d2r-mod extract [--game-dir PATH] # Extract game data + generate Python modules
d2r-mod build [--no-regen] # Build mod from vanilla + overlays
d2r-mod deploy [--force] [--no-casc] # Deploy mod to game directory
d2r-mod undeploy # Remove mod from game
d2r-mod diff [--summary] # Compare vanilla vs modded tables
d2r-mod inject [--from-dir PATH] # Inject files into CASC archive
d2r-mod audit [--skills] [--items] # Audit game data
d2r-mod clean # Remove build/ and reset data
d2r-mod update # Re-extract after game update
Data Mod Overlays
Overlays modify D2R data tables declaratively using YAML. Place overlay files in an overlays/ directory and run d2r-mod build.
Create an overlays/ directory in your project root to add custom overlays.
If no overlays directory exists, d2r-mod build will proceed with vanilla data only.
target: data/global/excel/UniqueItems.txt
changes:
- row: {index: "The Gnasher"}
set:
prop4: "dmg%"
min4: "50"
max4: "50"
comment: "Buff The Gnasher with +50% Enhanced Damage"
Each overlay targets a specific game table (TSV file) and specifies row matches and column changes. See examples/sample_overlay.yaml for a complete example.
JSON String Patches
D2R reads item names, mercenary names, and most UI strings from JSON files in data/local/lng/strings/ (not from the older .tbl files). To add a new string or override a vanilla one, drop a YAML spec into patches/json_strings/ and rebuild.
# patches/json_strings/my_renames.yaml
description: "Rename a few potions"
target: item-names.json
entries:
- key: "vps" # vanilla string key (super healing potion)
value: "Wild Rice Cake" # what D2R should display instead
- key: "MyCustomItem" # new key — auto-allocated string ID
value: "Heart of the Mountain"
If the key already exists in the target JSON, its enUS value is overridden. If it doesn't, a new entry is appended with the next free string ID (read from data/local/lng/next_string_id.txt). Targets currently used: item-names.json, mercenaries.json, ui.json.
After d2r-mod build, the patched JSONs land in build/data/local/lng/strings/; d2r-mod deploy injects them into CASC. D2R caches strings at startup, so fully exit and relaunch to see changes.
If no patches/json_strings/ directory exists, the build skips this step.
Architecture
d2r_chargen/ YAML character builder
build_lib.py Binary item encoder (Huffman, stat encoding, checksums)
character.py Build orchestrator (YAML -> items -> .d2s)
resolve.py Name-to-ID resolution (uniques, runewords, stats, skills)
save.py Save file operations (stats, skills, waypoints, items)
scanner.py Diagnostic validator
data/ Game data (generated via extract, not distributed)
d2r_mod/ Data modding pipeline
casc.py Pure Python CASC reader (TBL, TXT, JSON)
casc_write.py CASC archive builder + ekey-hijack injection
overlay.py YAML overlay loader and applier
build.py Build orchestrator (vanilla + overlays -> build/)
build_steps/ Specialized build steps:
register_custom_uniques.py Auto-register custom unique names in TBL
build_string_registry.py Diff built TBLs vs vanilla into a registry
patch_json_strings.py Apply patches/json_strings/*.yaml to JSON
deploy.py Deploy/undeploy mod files
regen.py Generate chargen data from extracted tables
tools/ Standalone diagnostics
audit_string_registry.py Categorize string_registry entries vs JSON
Platform Support
| Platform | Status |
|---|---|
| Linux / Steam Deck (Proton) | Supported, tested |
| Windows | Untested — path detection included, contributions welcome |
| macOS | Unsupported |
Requirements
- Python 3.10+
- PyYAML
- Diablo II: Resurrected (for data extraction)
mcpSDK (installed automatically with the package)
License
MIT
MCP Server (Claude Code, Codex, Cursor, …)
d2r-tools ships an MCP server that exposes
game-data lookups, save inspection, the chargen pipeline, and the mod pipeline
as typed tools to any MCP-compatible agent. See d2r_mcp/README.md for the
full tool catalog (23 tools across lookup / save / chargen / mod).
Install
pip install -e . # `mcp` SDK is included as a base dependency
Launch
python3 -m d2r_mcp # stdio transport
Client configuration
Claude Code (user-scoped):
claude mcp add d2r-tools --transport stdio --scope user -- python3 -m d2r_mcp
Codex / Cursor / any other MCP client — add to the client's MCP config:
{
"mcpServers": {
"d2r-tools": {
"command": "python3",
"args": ["-m", "d2r_mcp"],
"env": {}
}
}
}
Mutation tools (d2r_chargen_build, d2r_mod_deploy) enforce the project's
safety rules structurally: they back up the live save, build to a staging
file, run the scanner on the staging, and only promote to the live save if
the scanner passes.
Claude Code Plugin (optional)
The plugin/ directory is a Claude Code plugin that adds slash commands and
skills on top of the MCP server. Point Claude Code at the repo or symlink
plugin/ into your Claude Code plugins directory.
Slash commands
| Command | Description |
|---|---|
/d2r-build <name> |
Safe build cycle (backup → build → scan → verify) |
/d2r-validate <name> |
Validate character YAML without building |
/d2r-scan <name> |
Run diagnostic scanner |
/d2r-lookup <query> |
Look up items, stats, skills from game data |
Skills
- d2r-safe-edit — enforces backup→edit→scan→verify on every save file change
- d2r-parallel-agents — guides parallel-agent dispatch for multi-character work
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.