- Isometric canvas renderer (depth-sorted, FOV/fog, additive lighting) - 3 classes x 20 skills, 4 acts x 4 floors + boss lairs, torment I-X - Diablo-style loot: rarities, affix tiers, 14 legendaries, vendor, stash - Rogue camp with 6 NPCs: Charsi/Akara/Kashya/Cain/Gheed/storage - NPC quest chain (accept -> hunt -> turn in) with rewards & gating - Procedural WebAudio SFX + generative music, EN/VI localization - Saves, settings, waypoints, hardcore mode, PWA manifest - 93-assertion headless suite + browser E2E via CDP
Diablo2D — Shadows of Tristram
A dark, isometric action-RPG that runs entirely in your browser — no build step, no server, no assets to download. Every tile, creature, spell effect, sound and music track is generated procedurally in code. Inspired by classic Diablo and modern browser ARPGs like Sephiria.
Play
Instant: serve the folder with any static file server and open it.
cd diablo2d
python3 -m http.server 8080 # or: node server.js 8080
# open http://localhost:8080
It also runs straight from file:// (double-click index.html) and can be
zipped as-is for itch.io (see Publishing below).
Progress autosaves to
localStorageevery 90 seconds, on floor change, and when the tab closes. Export/import your hero as a code from Settings.
Features
- 3 classes — Crusader, Ranger, Sorceress — 20 hand-tuned skills across 3 talent branches each (actives + passives, 6-slot action bar).
- 4 acts × 4 floors of procedurally generated dungeons: room-and-corridor crypts, cellular cave systems, and a boss lair per act (The Flesh Butcher, The Bone King, Aranea the Spider Queen, Malgor the Lord of Terror) with multi-phase scripted attacks.
- Diablo-style loot: 40+ item bases, 4 rarities, ~30 affixes with item-level tiers, 14 build-defining legendaries (Cleave Echo, Corpse Boom, Voidstep…), vendor with rerolling stock, gamble-free sell/buy economy, and a shared stash.
- Elite monsters with 10 random affixes (Frozen, Jailer, Necrotic…), champion packs, and torment levels I–X for endless scaling after victory.
- Full RPG systems: strength/dex/vit/energy allocation, crit & crit damage, elemental damage & resists, cooldown reduction, magic/gold find, shrines, destructibles, health/mana potions on a potion belt.
- Waypoint network between acts, quest tracker, NPC dialogs (blacksmith, healer, stash keeper), death penalty & hardcore mode.
- Procedural audio: WebAudio-synthesised SFX for every action and a generative music sequencer with per-theme moods (town, crypt, cave, hell, boss).
- English + Tiếng Việt, damage numbers, screen shake, and label options.
Controls
| Input | Action |
|---|---|
| LMB (hold) | Move / attack-move onto enemies / interact |
| RMB, 1–3 | Cast bound skills |
| Q / E | Health / mana potion |
| F or Space | Interact — stairs, chests, shrines, NPCs |
| Alt | Toggle item labels |
| I / C / T / J / M | Inventory · Character · Skills · Quests · Map |
| Esc | Close panels / pause |
Tech notes
- Pure vanilla ES3-style classic scripts (works from
file://), globalwindow.D2namespace, ~10k lines acrossjs/core,js/data,js/game,js/render,js/ui. - HTML5 Canvas isometric renderer (64×32 diamond tiles, painter's-algorithm depth sort, raycast FOV + fog, additive lighting with torch flicker, screen-space damage numbers).
- A* pathfinding with per-frame budget, spatial-hash collision queries, Bresenham line-of-sight, cellular-automata + room generator with connectivity guarantees (stairs are never sealed off).
- WebAudio: zero audio files — every sound is a recipe of oscillators, noise buffers and envelopes; music is a live sequencer per mood.
- i18n dictionary (EN/VI), settings + save slots in
localStorageunderd2d.*, export/import via base64 code.
Repository layout
index.html shell + HUD DOM + script load order
css/style.css full gothic UI theme
js/core/ util, i18n, save, input, audio
js/data/ balance, items, monsters, skills (all data-driven)
js/game/ world gen, entities, ai, combat, loot, player, orchestrator
js/render/ procedural sprites, isometric renderer, minimap
js/ui/ hud, panels, screens
js/main.js bootstrap + game loop
tools/ headless_test.js (81 assertions), browser E2E driver,
CDP runner, icon generator, zip packer
Development
node tools/headless_test.js # 81-assertion simulation suite (no browser)
node tools/make_icons.mjs # regenerate PWA icons
node tools/build_zip.mjs # produce diablo2d-itch.zip
The headless suite boots the entire game in Node (stubbed DOM/canvas), generates every floor, casts every skill of every class, kills every boss, exercises economy/save-load, and soaks 3 600 combat frames.
Browser smoke test (optional, needs the Playwright chromium shell)
python3 -m http.server 8942 &
chromium-headless-shell --no-sandbox --remote-debugging-port=9344 \
"http://127.0.0.1:8942/tools/browser_drive.html?phase=full&mute=1" &
node tools/cdp_run.mjs 9344 150 # polls the E2E log to completion
Publishing
itch.io
node tools/build_zip.mjs→diablo2d-itch.zip- Create a new project → kind of project: HTML → upload the zip.
- Tick This file will be played in the browser, set viewport 1280×720 or larger, enable fullscreen button. Done.
Any static host (GitHub Pages, Netlify, S3…)
Upload the folder as-is. No build, no server code, no CORS issues — everything is relative-path static files.
License
Code and generated art: MIT (see LICENSE).
"Diablo" is a trademark of Blizzard Entertainment — this is an unaffiliated
fan-style homage; no Blizzard assets are used.