# Implementation Plan — Dungeon Crawler ## Overview Transform the existing ray-casting maze game into a turn-based first-person dungeon crawler with infinite depth, resource management (HP / Sanity / Weakness), psychedelic horror effects, and an inventory system. See `CONTEXT.md` for the canonical glossary of domain terms. --- ## Phase 0 — Turn-Based Game Loop Refactor the real-time loop into a turn-based model with smooth animations. ### 0.1 — Game state machine Introduce a `GameState` enum: - `WaitingForInput` — player can press keys - `AnimatingPlayer` — player walk/turn animation playing - `AnimatingEnemies` — enemy movement animations playing (simultaneous, 100ms) - `ResolvingTurn` — apply damage, weakness, sanity, pickups - `GameOver` — fade-out and exit ### 0.2 — Input gating - Only accept input in `WaitingForInput`. - On valid input → `AnimatingPlayer` (or `AnimatingEnemies` if skipping via C). - After all animations → `ResolvingTurn` → back to `WaitingForInput`. - C key skips turn (passes) — enemies still act. ### 0.3 — Key bindings | Key | Action | |-----|--------| | W | Move forward | | S | Move backward | | A | Strafe left | | D | Strafe right | | Q | Turn 90° left | | E | Turn 90° right | | Space | Attack cell ahead | | Z | Use selected inventory item | | X | Discard selected inventory item | | C | Skip turn | | 1-4 | Select inventory slot | | Esc | Quit | --- ## Phase 1 — Rooms-and-Corridors Maze Generation Replace the recursive-backtracker (1-tile-wide corridors) with a rooms-and-corridors generator. ### 1.1 — Generation algorithm 1. Place random rectangular rooms (3×3 to 6×6) on the grid, non-overlapping. 2. Connect rooms with 1–2 tile wide corridors using a minimum spanning tree or BFS carving. 3. Ensure all rooms are reachable. 4. Place the player start in a room near top-left. 5. Place the exit staircase in a room far from start. 6. Maze size scales with depth (16×16 rooms → 33×33 cells at depth 1, up to 28×28 rooms → 57×57 cells at depth 13+). ### 1.2 — Exit cell - Exit is a passage cell with a special floor texture (tile with a hole). - Walking onto it shows "Press Space to descend..." - Pressing Space generates a new depth, places player in a different room facing east. --- ## Phase 2 — Entity System Pre-place entities (enemies, hallucinations, pickups) in maze cells at generation time. ### 2.1 — Entity types ```rust enum Entity { Enemy { hp: u32, max_hp: u32, damage: u32 }, Hallucination { persistent: bool }, Pickup(PickupType), HallucinatedPickup(PickupType), } ``` ### 2.2 — Generation - **One entity per cell** — a cell is either empty or contains one entity. - Real enemies: 3–5 at depth 1, +2 per depth. - Hallucinations: 1–2 per level (regardless of depth). Their *behavior* scales with sanity, not their quantity. - Real pickups: 2–3 at depth 1, +1 per 2 depths. Mixed types (food, pill, bandage, weapon). - Hallucinated pickups: 0–1 at depth 1, +1 per 2 depths. - Weapons: 0–1, guaranteed at depths 2, 4, 6, etc. ### 2.3 — Enemy stat scaling | Depth tier | Enemy HP range | Enemy damage | |------------|---------------|-------------| | 1 | 1 | 1 | | 2–3 | 2–3 | 1 | | 4–6 | 3–5 | 1–2 | | 7–9 | 5–8 | 2 | | 10+ | 8+ | 2+ | --- ## Phase 3 — Combat System ### 3.1 — Attack action (Space) - Checks the cell directly ahead (based on facing direction). - If an enemy/hallucination is present in that cell → apply attack. - If nothing → "You swing at the air." No effect. ### 3.2 — Hitting an enemy - Deal `base_damage + bonus_damage` to the enemy. - Bonus damage: 30% chance for +1, repeat on success (infinite chain, geometric distribution). - If enemy HP ≤ 0 → enemy dies (removed from cell). - Enemy retaliates if still alive: deals its damage to player HP. - Screen flash: red tint. ### 3.3 — Hitting a hallucination - Non-persistent hallucination: vanishes, player loses sanity. - Persistent hallucination (sanity < ~20%): does NOT vanish; player loses sanity. May take multiple attacks to dissipate. - Screen flash: purple tint. ### 3.4 — Moving onto a cell with an entity - **Real enemy:** blocked. "Something is blocking your way." Player loses their turn; enemy attacks. - **Hallucination (non-persistent):** vanishes harmlessly — no sanity cost. - **Persistent hallucination:** blocked. "You are frightened to death just by thinking about doing this." Turn wasted. - **Pickup:** auto-collected into inventory. - **Hallucinated pickup:** auto-collected into inventory (deception discovered on use). ### 3.5 — Weapon system - Player always has an equipped weapon (starts with fists: base damage 1). - Picking up a weapon (`!`) auto-equips if its base damage is higher. - If base damage ≤ current weapon, display message and discard it. - Weapons cannot be manually discarded. - Hallucinated weapon: nothing happens on pickup, sanity drops slightly. - HUD displays `WPN:{base_damage}`. --- ## Phase 4 — Resource System ### 4.1 — Resources | Resource | Start | Max | At 0 | |----------|-------|-----|------| | HP | 5 | 5 | Death | | Sanity | 100 | 100 | Severe distortion, persistent hallucinations | | Weakness | 0 | 100 | HP starts draining | ### 4.2 — Per-turn effects - Weakness +1 every turn (passive hunger). - If weakness hits 100, HP drains at 1/turn. - Heartbeat counter increments by 1 each turn. ### 4.3 — Pickup effects | Type | Char | Real effect | Hallucinated effect | |------|------|------------|-------------------| | Food | `F` | -20 weakness | No effect. Sanity -5. "It was never there..." | | Pill | `0` | -15 weakness, +20 sanity | No effect. Sanity -5. | | Bandage | `+` | -15 weakness, +1 HP (if HP < max) | No effect. Sanity -5. | ### 4.4 — Healing feedback - Screen flash: green tint on successful heal. --- ## Phase 5 — Inventory System ### 5.1 — Slots - 4 inventory slots. - Pickups auto-collect into the first empty slot. - If full, message "Inventory full" — pickup stays on the ground. ### 5.2 — Controls - `1`–`4`: select slot. - `Z`: use selected item (consumes a turn). - `X`: discard selected item (does NOT consume a turn). Item disappears forever. ### 5.3 — Hallucinated pickups in inventory - Look identical to real pickups. - Using one: no effect, sanity -5, message "It was never there..." - The item is consumed (removed from inventory) on use. --- ## Phase 6 — Psychedelic Horror Effects ### 6.1 — Sanity thresholds (smooth interpolation) | Sanity | Visual effects | Semi-physical effects | |--------|---------------|---------------------| | 100–80% | Clean | None | | 79–60% | Mild color drift, wall breathing | 5% phantom wall/passage | | 59–40% | Stronger distortion, flickering textures | 10% phantom, maze shifts 5%/turn | | 39–20% | Heavy warping, false `@` flickers | 15% phantom, shifting 10%/turn, hallucinations patrol | | 19–0% | Severe distortion | 20% phantom, shifting 15%/turn, persistent hallucinations | ### 6.2 — Phantom walls (A) - Render a wall where a passage exists. - Player can walk through it — discovers it was fake. - Randomly placed each frame; frequency scales with sanity threshold. ### 6.3 — Phantom passages (B) - Render a passage where a wall exists. - Player tries to move forward → blocked (invisible wall). - Disorienting but doesn't trap the player. ### 6.4 — Shifting maze (D) - On turn resolution, sanity-based % chance that 1–3 wall cells outside player FOV flip (wall ↔ passage). - Constraint: never block the exit, never fully enclose the player. - Chance: 0% at depth 1–3, 5%/turn at 59–40% sanity, 10%/turn at 39–20%, 15%/turn at 19–0%. ### 6.5 — Hallucination behavior scaling - Depth 1–3: hallucinations static, easy to distinguish. - Depth 4–6 + medium sanity: hallucinations start patrolling randomly (every 3 turns). - Depth 7+ + low sanity: hallucinations move toward player, indistinguishable from real enemies. ### 6.6 — Screen darkness - Two factors multiplied: 1. **Weakness dimming:** 0% (fresh) to ~80% (max weakness). 2. **Depth dimming:** 0% (depth 1) to 80% (depth 15+). - At depth 10 with high weakness, vision is severely restricted. --- ## Phase 7 — Enemy AI ### 7.1 — Real enemy behavior (per turn) 1. If adjacent to player → attack (deal damage). 2. If line-of-sight to player → move one tile toward player (reduce Manhattan distance). 3. If no LOS → patrol (every 3 turns): pick random adjacent passage and move there. 4. Hallucinations at low sanity follow the same behavior. ### 7.2 — Enemy animation - All enemies animate simultaneously (100ms duration). - Smooth tile-walk animation matching player's style. --- ## Phase 8 — HUD ### 8.1 — Bottom bar (Doom-style) ``` [♥ 3/5] [♦ SAN: 72%] [⌂ Weak: 45%] ♥♥ 42 WPN:2 [F][0][ ][+] DEPTH:7 ``` - Hearts for HP, diamond for sanity, house for weakness. - Heartbeat counter with heart symbol. - Weapon display. - 4 inventory slots showing item chars (empty = blank). - Current depth number. ### 8.2 — Message log - Single line above or within the HUD bar. - Displays the most recent message for 2–3 turns, then fades. - Messages: attack results, item usage, blocked movement, hallucination encounters. ### 8.3 — Entity sprites (ASCII) | Entity | Char | Color | |--------|------|-------| | Enemy / Hallucination | `@` | Red | | Food | `F` | Green | | Pill | `0` | Cyan | | Bandage | `+` | White | | Weapon | `!` | Yellow | | Exit | Floor texture (hole) | — | Rendered as scaled pixel-font sprites in the 3D view, line-of-sight only. --- ## Phase 9 — Score & Death ### 9.1 — Score formula ``` Score = (Kills × 100) + (Final Depth² × 50) + (Weapon Base Damage × 500) ``` - Calculated on death. Output to terminal. - Values subject to tuning after playtesting. ### 9.2 — Death sequence 1. HP hits 0. 2. Screen fades to black over ~2 seconds. 3. Message: "You had become yet another legend of this dungeon." 4. Score printed to terminal. 5. Game exits. --- ## Phase 10 — Screen Flashes & Feedback | Event | Feedback | |-------|----------| | Player hits enemy | Red flash | | Player hits hallucination | Purple flash | | Player takes damage | Red flash + camera jolt | | Successful heal | Green flash | | Hallucination vanishes (walk-through) | Brief warp/distortion effect | | Enemy dies | White flash, entity removed | --- ## Implementation Strategy Build incrementally — one feature at a time: 1. **Phase 0** — Turn-based loop (foundation for everything) 2. **Phase 1** — Rooms-and-corridors generation 3. **Phase 2 + 3 + 4** — Entities, combat, and resources (tightly coupled) 4. **Phase 5** — Inventory 5. **Phase 8** — HUD 6. **Phase 7** — Enemy AI + animations 7. **Phase 6** — Psychedelic effects 8. **Phase 9 + 10** — Score, death, polish Each phase must be testable independently before moving to the next.