Delve: Between Descents
Context
Delve is a browser roguelike. Ashes of the Pale Flame is its deckbuilder spin-off. Between Descents is the third game in the same world, this time asking a different question: what’s it like to be the town above the dungeon? You never go down. You manage the operation that sends people who do.
The constraint that made it interesting: the game had to share lore, art, classes, and flavor text with the other two games — any inconsistency would be visible immediately to anyone who had played them.
Problem
Town management sims tend to grow into sprawling systems. The goal here was the opposite — a tight loop that resolves in a session, feels consequential on each decision, and doesn’t require a feature roadmap to be worth playing.
The challenge was keeping the loop meaningful without a real-time simulation. Delvers go out; they come back (or they don’t). Every decision — which depth to send them to, whether to press on at a checkpoint, what to equip — needs to feel like it matters even though the resolution is a single instant roll-up.
Approach
1. The town loop
The core is simple: recruit → equip → send → recover. Loot that comes back lands in a shared Stash rather than auto-equipping — you choose who gets it or sell it for gold. Shops have three investment levels that unlock deeper stock and, with it, deeper expedition options. Buying a replacement item auto-trades the old piece in at half price rather than discarding it.
2. Mid-delve checkpoints
Shallow expeditions resolve in one go. Anything deeper splits into up to three checkpoints: the delver returns with their log and current gold, and you choose to press on or bank what they have. Dying mid-phase ends immediately. The checkpoint system is what turns a simulation into a game — each pause is a real decision, not just flavor.
3. Expedition log
Each expedition generates a beat-by-beat narrative: faction lore lines, named enemy epithets, and depth flavor pulled from the same tables as the roguelike. The log makes the abstract simulation legible — you’re not watching a number go up, you’re reading what happened. The same lore voice that shows up as in-dungeon graffiti in the roguelike appears here as faction beats from the Order of the Pale Flame and the Thornwatch.
4. Hall of Winners and burial ceremony
Cross-run persistence happens through the Hall of Winners: every delver who falls or retires is recorded with their name, class, deepest depth, times delved, and fate. A “Reset run” wipes the current town but keeps the Hall — so there’s a sense of accumulation even when you start fresh.
When a delver falls, the game doesn’t skip past it. The expedition log reports the death, then a burial ceremony gives them a procedurally-picked epitaph in the same dry, unsentimental tone as the roguelike’s in-dungeon inscriptions, before the roster slot opens up.
5. Shared world without shared code
The three games share data files (classes.ts, items.ts, flavor.ts, epitaphs.ts) and character portrait assets, copied rather than pulled from a monorepo — intentionally loose coupling so each game can diverge without a dependency chain. The shared world is a constraint on content, not on code.
6. Save integrity
Same SHA-256 signing scheme as the deckbuilder: the full save state is serialized, a hash is computed with a known salt, and on load the hash is verified before the state is applied. Hand-edited saves are rejected. The implementation uses Web Crypto (crypto.subtle.digest) — no library required.
What’s missing
- Shop investment unlocks deeper stock but doesn’t discount prices, despite the button’s wording.
- Checkpoint decisions are always press-on or retreat — no branching paths yet, and every phase draws from the same enemy and flavor pools regardless of choice.
- The Hall of Winners has no scoring formula beyond deepest depth reached.
Stack
| Layer | Tech |
|---|---|
| Client | Vite + React + TypeScript |
| Styling | Plain CSS — dark/gold palette and Cinzel/JetBrains Mono shared with the other Delve games |
| Persistence | localStorage, SHA-256 signed via Web Crypto |
| Deploy | Docker (static nginx), built and pushed by Gitea Actions |