RepoPilotOpen in app →

diasurgical/devilution

Diablo devolved - magic behind the 1996 computer game

Mixed

Slowing — last commit 8mo ago

worst of 4 axes
Use as dependencyConcerns

non-standard license (Other); no tests detected

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 8mo ago
  • 14 active contributors
  • Distributed ownership (top contributor 36% of recent commits)
Show 5 more →
  • Other licensed
  • CI configured
  • Slowing — last commit 8mo ago
  • Non-standard license (Other) — review terms
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/diasurgical/devilution?axis=fork)](https://repopilot.app/r/diasurgical/devilution)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/diasurgical/devilution on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: diasurgical/devilution

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/diasurgical/devilution shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Slowing — last commit 8mo ago

  • Last commit 8mo ago
  • 14 active contributors
  • Distributed ownership (top contributor 36% of recent commits)
  • Other licensed
  • CI configured
  • ⚠ Slowing — last commit 8mo ago
  • ⚠ Non-standard license (Other) — review terms
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live diasurgical/devilution repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/diasurgical/devilution.

What it runs against: a local clone of diasurgical/devilution — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in diasurgical/devilution | Confirms the artifact applies here, not a fork | | 2 | License is still Other | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 267 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>diasurgical/devilution</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of diasurgical/devilution. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/diasurgical/devilution.git
#   cd devilution
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of diasurgical/devilution and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "diasurgical/devilution(\\.git)?\\b" \\
  && ok "origin remote is diasurgical/devilution" \\
  || miss "origin remote is not diasurgical/devilution (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "Source/diablo.cpp" \\
  && ok "Source/diablo.cpp" \\
  || miss "missing critical file: Source/diablo.cpp"
test -f "Source/all.h" \\
  && ok "Source/all.h" \\
  || miss "missing critical file: Source/all.h"
test -f "Source/control.cpp" \\
  && ok "Source/control.cpp" \\
  || miss "missing critical file: Source/control.cpp"
test -f "Source/_render.cpp" \\
  && ok "Source/_render.cpp" \\
  || miss "missing critical file: Source/_render.cpp"
test -f "3rdParty/Storm/Source/storm.cpp" \\
  && ok "3rdParty/Storm/Source/storm.cpp" \\
  || miss "missing critical file: 3rdParty/Storm/Source/storm.cpp"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 267 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~237d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/diasurgical/devilution"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Devilution is a reconstructed source code for Diablo (1996) built by reverse-engineering the original game using debug symbols accidentally left on a PlayStation port and a special debug build hidden in the PC release. It allows the classic dungeon crawler to run on modern hardware with full source-level modifiability, replacing the abandoned 2001-era codebase that was never updated beyond patch 1.09. Mixed C/C++ monorepo: Source game logic split between DiabloUI/ (menu/UI layer using custom UI framework), 3rdParty/Storm (custom networking/file I/O abstraction), 3rdParty/PKWare (MPQ decompression), and core game engine in the root Source/ directory (inferred). Legacy Visual Studio projects (Diablo.sln, .dsp files) coexist with Makefiles for cross-platform builds.

👥Who it's for

Retro gaming enthusiasts, modders, and maintainers who want to fix bugs in Diablo, port it to new platforms (currently supports Windows, macOS, Linux), and understand or extend the 1996 game engine without reverse-engineering memory or using binary patches. Also valuable for game developers studying 1990s dungeon crawler architecture.

🌱Maturity & risk

Actively developed with significant community interest (evidenced by CircleCI, Travis CI, and AppVeyor multi-platform CI setup). The codebase is substantial (~3.3MB C++, ~236KB C) and has been reconstructed from debug symbols, making it production-ready for gameplay. However, it remains a reverse-engineered reconstruction rather than official source, and requires an original copy of diabdat.mpq from GoG to legally run.

Reverse-engineered codebases carry legal/licensing ambiguity despite being community-driven and openly hosted on GitHub. The project depends on legacy Storm library (custom in 3rdParty/Storm/) and PKWare compression (3rdParty/PKWare/), both embedded but potentially outdated. Single-maintainer risk is mitigated by active Discord community, but commit recency and open issue volume are not visible from provided data.

Active areas of work

Repo is actively maintained with multi-platform CI/CD (CircleCI, Travis CI, AppVeyor) and ongoing porting efforts. The '3rdParty' architecture suggests recent work on isolating platform-specific code. Without recent commit log, visible effort includes maintaining builds across Windows (.vcxproj), macOS (build_mac.yml), and Linux (Makefile infrastructure).

🚀Get running

Clone and build using the Makefile infrastructure present in root and 3rdParty/ subdirectories: git clone https://github.com/diasurgical/devilution.git && cd devilution && make (Linux/macOS) or open Diablo.sln in Visual Studio (Windows). Obtain diabdat.mpq from GoG's Diablo 1 release and place in the working directory.

Daily commands: After building with make (or Visual Studio on Windows), run ./diablo (or Diablo.exe on Windows). Requires diabdat.mpq in the working directory or configured path. Multi-platform CI suggests cross-compilation is supported; see .circleci/config.yml and .github/workflows/build_mac.yml for exact build matrix.

🗺️Map of the codebase

  • Source/diablo.cpp — Primary entry point and main game loop; all developers must understand the core initialization and frame update flow.
  • Source/all.h — Master header file that aggregates all includes; essential for understanding the global dependencies and module organization.
  • Source/control.cpp — Input handling and player command processing; critical path for game responsiveness and player interaction.
  • Source/_render.cpp — Core rendering pipeline for the game world; foundational for visual output and performance-critical code.
  • 3rdParty/Storm/Source/storm.cpp — Storm library implementation providing core file/archive I/O and game data loading; load-bearing dependency for game asset management.
  • Source/codec.cpp — Compression/decompression for game assets; required for understanding data format handling and asset pipeline.
  • DiabloUI/diabloui.cpp — UI framework and menu system initialization; gateway to all user-facing interface logic and state management.

🧩Components & responsibilities

  • Game Loop & Initialization (C++, Win32/SDL for platform abstraction) — Bootstraps all systems, manages frame pacing, and coordinates update/render cycle
    • Failure mode: If loop crashes or frame skips, entire game becomes unplayable; data corruption or infinite loops
  • Dungeon Generation (DRLG) (Deterministic random number generation, constraint-solving algorithms) — Procedurally generates level layouts, tile placements, and monster/item spawns
    • Failure mode: Invalid layouts cause wall overlaps, unreachable areas, or softlocks; crashes on generation failure
  • Storm Archive System (PKWare IMPLODE, custom encryption (simplified 1996 security)) — Decrypts and decompresses .mpq archives; provides virtual filesystem for all game assets
    • Failure mode: Corrupted .mpq

🛠️How to make changes

Add a new dungeon level generator

  1. Create new dungeon layout file following drlg_l1.cpp pattern (e.g., drlg_l2.cpp for level 2) (Source/drlg_l2.cpp)
  2. Define level generation function and data structures in corresponding header (Source/drlg_l2.h)
  3. Integrate level loading into main game initialization logic (Source/diablo.cpp)
  4. Register level assets with Storm library file system (3rdParty/Storm/Source/storm.cpp)

Add a new menu screen or dialog

  1. Create new UI file in DiabloUI following naming convention (e.g., selnewdialog.cpp) (DiabloUI/selnewdialog.cpp)
  2. Define dialog structure and event handlers matching existing patterns (DiabloUI/selnewdialog.cpp)
  3. Register the new dialog/menu in the UI framework initialization (DiabloUI/diabloui.cpp)
  4. Add font resources and art references if needed (DiabloUI/artfont.cpp)

Extend rendering with a new visual element

  1. Define rendering function or sprite management in render system (Source/_render.cpp)
  2. Add coordinate and viewport calculations (Source/capture.cpp)
  3. Integrate into main frame update loop to ensure consistent draw order (Source/diablo.cpp)

🔧Why these technologies

  • C++ with ASM optimizations — Matches original 1996 Diablo codebase; enables low-level rendering and performance-critical paths with inline assembly
  • Storm library (custom archive system) — Handles proprietary .mpq (MoPaQ) archives from original game; provides efficient asset streaming and caching
  • PKWare IMPLODE/EXPLODE compression — Maintains compatibility with original Diablo 1 asset compression format for game data
  • Software rendering with direct framebuffer access — Replicates 1996 hardware constraints; enables pixel-perfect compatibility with original rendering pipeline
  • Procedural dungeon generation — Recreates Diablo's random level layouts using mathematical algorithms rather than pre-baked data

⚖️Trade-offs already made

  • Requires original diabdat.mpq from GoG or retail Diablo 1

    • Why: Legal/licensing constraint to avoid redistributing proprietary assets
    • Consequence: Raises friction for new players but ensures copyright compliance
  • Direct framebuffer manipulation instead of graphics API abstraction

    • Why: Achieves pixel-perfect compatibility with 1996 rendering behavior
    • Consequence: Harder to port to modern graphics APIs; tightly coupled to CPU-based rendering
  • Monolithic codebase (not modular plugin system)

    • Why: Simplifies understanding and maintains architectural clarity of original game
    • Consequence: Harder to extend without modifying core files; all features must integrate into main loop

🚫Non-goals (don't propose these)

  • Does not attempt to modernize graphics to 3D or apply filters
  • Does not include multiplayer networking (single-player recreation only)
  • Does not distribute or provide Diablo game assets (requires external diabdat.mpq)
  • Not compatible with Diablo 1.09+ multiplayer save formats or online play

🪤Traps & gotchas

Requires external diabdat.mpq file from GoG (not included) — build will complete but game won't run without it. Legacy .dsp and .vcxproj files suggest Visual Studio project format drift; ensure correct project loaded. 3rdParty/Storm library is a custom shim replacing original Blizzard Storm.dll — any platform-specific issues likely originate there. Reverse-engineered code may have symbol mismatches or reconstructed function signatures differing subtly from original behavior.

🏗️Architecture

💡Concepts to learn

  • MPQ (MoPaQ) Archive Format — Core file format for storing Diablo assets (diabdat.mpq); understanding compression, hash tables, and sector-based storage is essential for modding and asset extraction
  • Debug Symbols and STABS Format — Devilution was reconstructed from accidentally-left STABS debug symbols in the PlayStation port; understanding symbol tables, type info, and function signatures explains how reverse-engineering succeeded
  • Binary Reverse Engineering and Symbol Recovery — The project's foundation relies on recovering function names, structs, and logic flow from compiled binaries and debug metadata; essential context for understanding code reliability and gaps
  • Cross-Platform Game Engine Abstraction — Storm library (3rdParty/Storm/) abstracts platform-specific I/O, networking, and memory to support Windows/Linux/macOS from a single codebase; key pattern for maintaining retro ports
  • PKWARE Deflate Compression (IMPLODE/EXPLODE) — PKWare codec in 3rdParty/PKWare/ handles asset compression inside MPQ archives; understanding DEFLATE and PKWare's extensions is needed for asset modding
  • Isometric Projection Rendering — Diablo's signature visual style uses isometric perspective; understanding tile-based rendering, depth sorting, and sprite layering is crucial for graphics modifications
  • diasurgical/devilutionX — Active fork of Devilution with gameplay improvements, bug fixes, and extended platform support (switch, consoles); de facto maintained version used by most players
  • diasurgical/diamonds — Companion project providing asset extraction and modding tools for Diablo 1, allowing creation of custom spritesheets and map data
  • Blizzard/Diablo2 — Official Diablo 2 source code (released by Blizzard 2024); represents evolution of the engine from Diablo 1 and useful for understanding architectural progression
  • OpenDiablo2/OpenDiablo2 — Similar reverse-engineering + modernization project for Diablo 2 in Go/TypeScript; demonstrates alternative approaches to legacy game reconstruction
  • OpenGameTools/storm — Independent reimplementation of Blizzard's Storm library format; relevant for understanding MPQ compression and file I/O abstractions used by Devilution

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add GitHub Actions workflow for Linux/GCC builds (complementing existing CI)

The repo has CircleCI, Travis CI, and AppVeyor configs, but no dedicated GitHub Actions workflow for Linux builds. Given the Makefile presence in 3rdParty/Storm and 3rdParty/PKWare, a GitHub Actions workflow would modernize CI/CD, reduce external service dependencies, and provide native GitHub integration for status checks on PRs. This is especially valuable for a cross-platform C++ project.

  • [ ] Create .github/workflows/build_linux.yml targeting gcc with 3rdParty/Storm/Makefile and 3rdParty/PKWare/Makefile
  • [ ] Add build steps for both Debug and Release configurations
  • [ ] Integrate with existing .clang-format for code style validation
  • [ ] Test against the Diablo.vcxproj structure to ensure compatibility with the build system

Refactor DiabloUI into feature-based modules with a shared component system

DiabloUI contains 40+ .cpp files with unclear separation of concerns (e.g., sellist.cpp, selhero.cpp, seldial.cpp, selconn.cpp, selload.cpp appear to be selection screens). Extracting common UI patterns into a reusable component system (buttons, dialogs, lists) and organizing files by feature (e.g., DiabloUI/menus/, DiabloUI/dialogs/, DiabloUI/components/) would reduce code duplication, improve maintainability, and make the codebase more accessible to new contributors.

  • [ ] Analyze sellist.cpp, selhero.cpp, selload.cpp, seldial.cpp to identify common UI patterns and state management
  • [ ] Create DiabloUI/components/ directory with shared UI primitives (base list widget, dialog wrapper, button handler)
  • [ ] Reorganize files into DiabloUI/menus/ (mainmenu.cpp, credits.cpp), DiabloUI/dialogs/, and DiabloUI/components/
  • [ ] Update build files (Makefile, .vcxproj, .dsp) to reflect new structure and add documentation via comments in refactored files

Add comprehensive build system documentation and cross-platform build tests

The repo supports multiple build systems (Visual Studio .sln/.vcxproj, Makefile, .dsp files from older MSVC versions) but lacks documented build instructions for Linux/macOS contributors. The build_mac.yml workflow exists but is not documented. A BUILD.md file with specific instructions for each platform, plus validation of the Makefile against the project structure, would lower the barrier to entry for contributors.

  • [ ] Create BUILD.md documenting: (1) Windows build via Diablo.sln, (2) Linux build via 3rdParty Makefiles, (3) macOS via build_mac.yml, (4) dependency setup for each platform
  • [ ] Verify 3rdParty/Storm/Makefile and 3rdParty/PKWare/Makefile compile all necessary sources and link correctly
  • [ ] Add platform-specific sections noting diabdat.mpq requirement (already in README snippet)
  • [ ] Reference .editorconfig and .clang-format in BUILD.md for contribution guidelines

🌿Good first issues

  • Add unit tests for PKWare compression/decompression (3rdParty/PKWare/pkware.h and .cpp) — currently no test files visible; critical utility code lacks coverage
  • Document DiabloUI screen flow and add missing comments to DiabloUI/*.cpp files (cr8game.cpp, creadung.cpp, etc.) — UI layer is sparsely documented for new contributors
  • Create a platform abstraction guide for Storm library (3rdParty/Storm/) to clarify which functions must be implemented per-platform; will help future ports

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 9f01757 — Remove dead link (AJenbo)
  • 14a9620 — lighting: add BUGFIX for MakeLightTable (StephenCWills)
  • e30328b — missiles: add BUGFIX for flame wave light radius (StephenCWills)
  • 6b7135c — objects: add BUGFIX for OperateBook (mewmew)
  • 4fad670 — player: add BUGFIX for CreatePlayer (mewmew)
  • bbda8dd — Remove global optimizations for SHA1ProcessMessageBlock() (StephenCWills)
  • 27e6ef5 — Add Diablo Version 1.08-Specific Behavior with Preprocessor Directives (#2292) (kphoenix137)
  • 2aa3919 — fix typos (#2291) (qndel)
  • a982e4c — monster: add BUGFIX for mVar2 (#2290) (NiteKat)
  • 3c92fec — multi: add BUGFIX for multi_mon_seeds (mewmew)

🔒Security observations

The Devilution codebase is a reverse-engineering project of the 1996 Diablo game written in legacy C/C++. Primary security concerns stem from the use of obsolete third-party libraries (PKWare, Storm), which lack modern security hardening and maintenance. The legacy codebase is inherently susceptible to common C vulnerabilities (buffer overflows, integer overflows, format strings) typical of 1990s code. No critical secrets or injection vectors are evident from the file structure. Recommended actions: (1) Conduct static analysis of legacy code using modern tools, (2) Apply compiler hardening flags, (3) Replace deprecated libraries where possible, (4) Implement input validation for external game assets, (5) Add security documentation. Overall, for a reverse-engineering/hobbyist project, the security posture is acceptable with noted legacy risks.

  • Medium · Use of Deprecated/Obsolete PKWare Library — 3rdParty/PKWare/. The codebase includes 3rdParty/PKWare library for compression (explode.cpp, implode.cpp). PKWare's PKWARE DCL (Data Compression Library) is an obsolete compression format. While not inherently vulnerable, it may lack modern security hardening and updates. The implode/explode algorithms are legacy compression techniques. Fix: Evaluate if modern compression libraries (zlib, zstd, brotli) can replace PKWare functionality. If PKWare must be retained, conduct a security audit of the implementation and ensure bounds checking is properly implemented.
  • Medium · Potential Integer Overflow in Legacy Storm Library — 3rdParty/Storm/Source/. The Storm library (3rdParty/Storm/) is a legacy third-party component originally from Blizzard. Legacy C/C++ code frequently suffers from integer overflows, buffer overflows, and format string vulnerabilities. The age and origin of this library increases risk. Fix: Conduct a thorough static analysis (using tools like Clang Static Analyzer, Coverity) of the Storm library code. Apply modern compiler hardening flags (-fstack-protector-strong, -D_FORTIFY_SOURCE=2). Consider replacing with modern alternatives if feasible.
  • Low · Missing Security Policy Documentation — Repository root. No SECURITY.md or security policy file found in the repository root. This makes it unclear how security vulnerabilities should be reported responsibly. Fix: Create a SECURITY.md file documenting responsible disclosure procedures and security contact information.
  • Low · Potential Use of Unsafe C Functions — Source/ (all C/C++ source files). The codebase is a C/C++ project from the 1996 era reverse-engineering effort. Legacy C code frequently uses unsafe functions like strcpy, sprintf, gets, etc. While the file list doesn't show obvious patterns, the age and nature of the codebase suggests risk. Fix: Conduct a comprehensive audit for unsafe function usage (strcpy, strcat, sprintf, scanf, gets). Replace with safe alternatives (strncpy, strncat, snprintf, fgets). Use compiler warnings (-Wall -Wextra -Wformat -Wformat-security).
  • Low · Game Asset Dependency Not Version-Controlled — README.md. The README notes that diabdat.mpq (Diablo game assets) must be provided separately. This external dependency is not tracked or versioned, potentially leading to supply chain risks if sources are compromised. Fix: Document expected hashes/signatures for diabdat.mpq. Provide instructions for asset verification. Consider cryptographic verification of external game files on load.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · diasurgical/devilution — RepoPilot