Diablo2D — Shadows of Tristram: complete browser ARPG

- 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
This commit is contained in:
2026-08-23 06:59:36 +00:00
commit fc1fa2d51e
42 changed files with 11784 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
# 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.
![class](https://img.shields.io/badge/classes-3-gold) ![acts](https://img.shields.io/badge/acts-4-red) ![offline](https://img.shields.io/badge/offline-100%25-green)
---
## Play
**Instant:** serve the folder with any static file server and open it.
```bash
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 `localStorage` every 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 IX 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, 13** | 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://`), global
`window.D2` namespace, ~10k lines across `js/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 `localStorage`
under `d2d.*`, 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
```bash
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)
```bash
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
1. `node tools/build_zip.mjs``diablo2d-itch.zip`
2. Create a new project → kind of project: **HTML** → upload the zip.
3. 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.