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:
@@ -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.
|
||||
|
||||
  
|
||||
|
||||
---
|
||||
|
||||
## 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 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://`), 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.
|
||||
Reference in New Issue
Block a user