Case study: Delve roguelike
Context
I wanted to see if Claude could design and balance a roguelike from scratch, figuring out features and systems iteratively without following a design doc. Also wanted a quick-run roguelike that respected my timeâ10 floors, 30â60 minute runs, replayability from modifiers and class variety rather than grinding for unlocks.
Roguelikes are a great test bed for systems design: procedural generation, combat balancing, progression curves, item variety, risk/reward decisions. Every run needs to feel different, but fair. Too easy and itâs boring. Too hard and itâs frustrating. Getting that balance right requires playtesting and iteration.
Problem
Build a roguelike that:
- Feels classic: ASCII rendering, turn-based combat, permadeath, procedural dungeons
- Runs quick: 30â60 minutes to completion, not 40-hour epics
- Has variety: different classes, run modifiers, item builds, enemy types
- Stays fair: RNG can be cruel, but never unfair. Deaths should feel deserved (even when you blame the game)
- Works in a browser: no install, keyboard-driven, mobile-friendly
Constraints
- Balancing without a design doc: I didnât spec out the entire game upfrontâClaude proposed systems, I playtested them, we iterated
- Browser performance: pathfinding for 20+ enemies per turn, FOV calculations, dungeon generationâall need to feel instant
- Mobile support: touch controls for movement, inventory, abilities (but keyboard remains primary)
- Fair RNG: random generation canât create unwinnable situations (no unavoidable damage, no mandatory items locked behind RNG)
Approach
1) Start with the core loop
Standard roguelike flow:
- Create character (class + background + run modifier)
- Descend through procedural dungeons
- Fight enemies, collect loot, level up
- Die or win
- Start over with knowledge gained
The key design question: what makes each run feel different?
Answer: class abilities + run modifiers + procedural dungeons + item variety.
2) Build systems incrementally
Rather than building everything up front, we added systems one at a time and playtested:
Iteration 1: MVP (1 week)
- Single class (Warrior)
- Basic combat (bump-to-attack)
- 5 floors, simple procedural generation (rectangular rooms + corridors)
- 5 enemy types (rat, bat, goblin, orc, skeleton)
- 3 item types (health potion, weapon, armor)
Iteration 2: Class variety (1 week)
- Added Rogue, Mage, Ranger, Necromancer
- Unique abilities per class (Cleave, Smoke Bomb, Arcane Bolt, Volley, Animate Dead)
- Passive class traits (Warrior regen, Rogue backstab, Mage potion mastery, Ranger eagle eye, Necromancer corpse pact)
- Level-up perk trees
Iteration 3: Run modifiers (1 week)
- 19 modifiers system (curses, blessings, mixed)
- Rerollable at character creation
- Each modifier changes the run significantly (Forsaken = no shop, Haunted = +3 enemies per floor, Glass Cannon = half HP + double ATK)
Iteration 4: Enemy variety (2 weeks)
- Expanded to 30+ enemy types across 3 biomes
- Special enemies: mimics (item/chest/door variants), pack leaders, named uniques
- Boss fights for floors 3, 6, 9, 10
- Enemy behaviors: fleeing, pack alerting, ranged attacks, regeneration, draining
Iteration 5: Item depth (1 week)
- 12 potion types (unidentified each run)
- Special weapons (Thornwhip, Soulstealer, Void Edge)
- Special armors (Thornplate, Shadowweave, Wraithskin)
- Rings, amulets, scrolls, wands, throwables
Iteration 6: Dungeon features (1 week)
- Special rooms (shrines, libraries, vaults, challenge rooms, NPC encounters, mirror rooms, transmutation altars)
- Floor events (65% chance: Hunting Pack, Blood Bounty, Silent Floor, Gold Rush, Undying, etc.)
- Traps (spike, poison dart, confusion gas, teleport, alarm bell)
- Gravestones from past runs
Iteration 7: Polish (ongoing)
- Daily Challenge mode (shared seed, same dungeon for all players)
- Kill streak system (Ă3 = XP bonus, Ă5 = ATK buff, Ă7+ = massive XP)
- Status effects (poison, confusion, slow, strengthen, invisible, berserk)
- Mobile touch controls
- Balance tuning (this never ends)
3) Balance through playtesting
The hardest part: making the game challenging but fair.
Early problems:
- Floor 1 was too deadly: Cave rats killed you before you found a weapon. Fixed by giving starting weapons.
- Mage was overpowered: Infinite Arcane Bolts trivialize combat. Added mana system, then removed it (too fiddly). Final solution: cooldown + limited casts per floor.
- Boss fights were trivial: Just stack health potions and tank. Fixed by adding boss abilities (Brood Mother spawns minions, Warlord has cleave, Pale King has phases).
- Run modifiers unbalanced: Blessed gave too much free stuff, Haunted was unplayable. Tuned values through 20+ test runs.
- Lategame scaling broken: Enemies hit too hard, armor didnât matter. Fixed by adjusting DEF scaling and adding armor-bypassing enemies (so stacking DEF isnât always optimal).
Testing approach:
- Play 5â10 runs after each major change
- Track win rate per class (should be 20â40% for skilled players)
- Watch for âfeels badâ moments (unavoidable deaths, impossible situations)
- Ask: âDid I deserve that death?â If no, investigate.
4) Procedural generation that stays fair
Dungeon generation algorithm:
- Place rooms (rectangles of varying sizes)
- Connect rooms with corridors (A* pathfinding)
- Add special rooms (shrines, libraries, vaults) based on floor depth
- Spawn enemies (density increases with depth, biome-specific types)
- Place items (weapons, armor, potions, scrolls)
- Add stairs to next floor
Fairness constraints:
- Every floor must have a valid path from entrance to exit
- Starting room never has enemies
- No enemy spawns within 3 tiles of player start position
- At least 1 health potion guaranteed per floor
- Shop always accessible (unless Forsaken modifier)
Biome variety:
- The Warren (floors 1â3): Cave rats, bats, goblins, spiders. Tight corridors, small rooms.
- The Ruins (floors 4â6): Orcs, skeletons, archers, cultists. Larger rooms, more loot.
- The Crypt (floors 7â10): Trolls, vampires, wraiths, shades. Dark, dangerous, lots of traps.
5) Performance optimizations
Browser games need to feel instant. ROT.js (the ASCII rendering library) does most of the heavy lifting, but some things needed optimization:
Pathfinding:
- A* for enemy movement (20+ enemies per turn)
- Cached paths for static enemies (recalculate only when player moves)
- Early exit if player unreachable
FOV calculations:
- Computed once per player move (not per frame)
- Cached explored tiles (donât recalculate what player has already seen)
Rendering:
- Only redraw visible tiles (not the entire map)
- Batch DOM updates (one paint per turn, not per enemy move)
Result: 60fps even with 30+ enemies on screen.
6) Daily Challenge mode
Shared-seed runs for competitive play:
- Seed based on UTC date (same dungeon layout for all players worldwide)
- Fixed run modifier (no rerolls)
- Same item spawns, same enemy positions
- Leaderboard for each dayâs challenge
Implementation: seed = hash of YYYY-MM-DD string â deterministic RNG â reproducible dungeons.
Tradeoffs
Chose simplicity over complexity:
- No hunger system (adds tedium without depth)
- No equipment durability (except Brittle modifier)
- No item identification minigame (potions are unidentified, but drinking is the only way to learn)
- No multi-floor backtracking (descent is one-way)
Chose browser delivery over native:
- Easier to iterate (no app store reviews)
- Instant access (no install friction)
- Cross-platform by default
- Tradeoff: canât use native features (gamepad rumble, notifications, file system)
Chose turn-based over real-time:
- More tactical, less stressful
- Works better on mobile (no twitch reflexes required)
- Easier to balance (no framerate-dependent behavior)
What I learned
Balancing is 90% of game development. The code was done in 2 weeks. The next 2 months were tuning numbers and fixing edge cases.
Roguelikes are unforgiving teachers. Every unfair death reveals a design flaw. Players will find every edge case you didnât plan for.
Procedural generation is hard to get right. Itâs easy to generate random dungeons. Itâs hard to generate interesting random dungeons that feel hand-crafted.
Claude is surprisingly good at game design. It proposed smart systems (kill streaks, pack leaders, run modifiers) that I hadnât thought of. The iterative process worked well.
Players remember unfair deaths forever. A single âbullshitâ death will overshadow 10 great runs. Fairness is more important than difficulty.
Results
Current state (v2.41.0):
- 5 classes with full progression trees (3 milestones each, ~8 perks per class)
- 19 run modifiers (6 curses, 4 blessings, 9 mixed)
- 30+ enemy types across 3 biomes
- 10 floors with 3 distinct biomes
- 4 boss fights (floors 3, 6, 9, 10)
- 50+ item types (potions, weapons, armor, rings, amulets, scrolls, wands, throwables)
- 65% floor event rate (16 different event types)
- Daily Challenge mode with shared seed and leaderboard
- Persistent gravestones from past runs
- Mobile-friendly touch controls
Player outcomes (from my own playtesting):
- Average run time: 45 minutes
- Win rate (skilled): ~35%
- Win rate (first-time): ~5%
- Most common cause of death: âgot surrounded by orcsâ (classic)
What Iâd do next
- More classes: Bard (buffs), Paladin (healing + tank), Druid (shapeshifting)
- Meta-progression: unlock new starting items, perks, or modifiers after completing runs
- Achievements: track silly stats (âdie to a cave rat 10 timesâ, âwin with every classâ)
- More biomes: add 5 floors (The Depths, The Void) for extended runs
- Multiplayer Daily Challenge leaderboard: show rankings, replay other playersâ runs
- Better mobile UX: larger touch targets, swipe gestures for movement
- Mod support: let players create custom classes, enemies, items