🎮 Game Dev Origin
HOLLOWDEEP — The Keep Remembers
A story-driven, turn-based dungeon RPG in the browser. Shattered-Pixel-Dungeon depth, Hades-style death-advances-the-story structure. Every turn is a decision, and death is progress.
Overview
HOLLOWDEEP is a story-driven, turn-based dungeon RPG that runs in the browser. It aims for Shattered-Pixel-Dungeon depth with a Hades-style spine where death advances the story — you wake at camp with Memory Shards, people talk, and the tale moves forward. It’s phone-first but mouse/keyboard-complete, built on four pillars: every turn is a decision, the dungeon tells the story, your inventory is your character, and death is progress rather than a game-over.
How it works
The whole engine is turn-based with all information visible — no reflexes, just decisions. Under the hood the gameplay is strictly deterministic: a seeded RNG (mulberry32) drives everything from dungeon generation to combat, and Math.random() is banned from game logic so runs are reproducible and testable. The world renders on a canvas while the UI chrome lives in the DOM — a clean split that keeps every game-logic module (dungeon, FOV, combat, items, inventory, turn queue, effects, save) DOM-free and unit-testable in Node.
Architecture
flowchart TD
SEED["Seeded RNG<br/>mulberry32 — no Math.random"]
subgraph LOGIC["DOM-free game logic (node-testable)"]
GEN["Dungeon gen"]
TURN["Turn queue"]
RES["Resolve<br/>combat · FOV · items · effects"]
end
subgraph VIEW["Presentation"]
CANVAS["Canvas world<br/>tileset atlas"]
DOM["DOM chrome<br/>inventory · dialogue"]
end
DEATH["Death → Camp<br/>Memory Shards · NPCs · story advances"]
SEED --> GEN --> TURN --> RES
RES --> CANVAS
RES --> DOM
RES -->|player falls| DEATH -->|descend again| GEN
What makes it interesting
- Death is progress — you don’t lose a run, you advance one: Memory Shards, camp dialogue, and story beats accrue across deaths, Hades-style.
- Every turn is a decision — fully turn-based with all information visible; the challenge is judgment, never reflexes.
- Determinism as a design tool — one seeded RNG drives all gameplay, so runs are reproducible and the logic is genuinely unit-testable.
- Clean logic/view split — game modules are DOM-free and importable in Node; the canvas and DOM chrome only render what the logic decides.
Highlights
- Vanilla JS ES modules — no build step, no dependencies, no framework, no CDN
- Seeded mulberry32 RNG across generation, combat, and loot;
Math.random()forbidden in game logic - DOM-free, node-testable core (dungeon, FOV, combat, items, inventory, turn queue, save) behind a canvas + DOM presentation layer