summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-07-11 01:41:50 +0200
committersalmonik <raisersoft@proton.me>2026-07-11 01:41:50 +0200
commitabec3946be10bfa79af3300b4876afefb34b0451 (patch)
treed1d817930a64614ea3dca69f6d3d476c7b02ff4e
parentswitch to rust 2024 (diff)
downloaddungeon-abec3946be10bfa79af3300b4876afefb34b0451.tar.gz
dungeon-abec3946be10bfa79af3300b4876afefb34b0451.zip
we have plans
-rw-r--r--CONTEXT.md30
-rw-r--r--docs/PLAN.md308
2 files changed, 338 insertions, 0 deletions
diff --git a/CONTEXT.md b/CONTEXT.md
new file mode 100644
index 0000000..c942ce0
--- /dev/null
+++ b/CONTEXT.md
@@ -0,0 +1,30 @@
1# CONTEXT
2
3## Canonical terms
4
5| Term | Definition |
6|------|------------|
7| **HP** | Physical health. Drops when a real Enemy attacks the Player. 0 = death. |
8| **Sanity** | Mental clarity (0–100%). Drops when the Player attacks a Hallucination or discovers a Hallucinated Pickup. Low sanity causes visual/auditory distortions and makes Hallucinations indistinguishable from real Enemies. |
9| **Weakness** | Hunger / exhaustion meter. Increases every Turn. At maximum, drains HP. Reduced by consuming Pickups (Food, Bandage, Pill). Drives hallucination frequency and screen darkness. |
10| **Heartbeat** | Monotonically increasing counter of Turns elapsed. Displayed in the HUD. Drives the rate at which Weakness accumulates. |
11| **Player** | The character controlled by the user. Moves tile-by-tile, attacks adjacent cells, manages an Inventory of Pickups. |
12| **Turn** | One discrete game step triggered by a Player action (move, turn, attack, use item). All Enemies act, and Weakness advances, on every Turn. |
13| **Enemy** | A real hostile entity pre-placed in the Maze. Moves toward the Player on its Turn and deals HP damage when adjacent. Blocked movement into an Enemy wastes the Player's turn and triggers an attack. |
14| **Hallucination** | A fake entity that looks like an Enemy. Walking onto a non-persistent Hallucination makes it vanish harmlessly. Attacking one drains Sanity and vanishes it. At critically low Sanity, Hallucinations become Persistent and do not vanish on attack. At greater Depth / lower Sanity, Hallucinations behave identically to real Enemies (patrol, chase). |
15| **Pickup** | An item placed in the Maze that the Player collects by walking onto its cell. Types: Food (`F`), Pill (`0`), Bandage (`+`), Weapon (`!`). |
16| **Hallucinated Pickup** | A Pickup that is not real. Appears in the Inventory normally but has no effect when used. Discovering one drains Sanity. |
17| **Weapon** | An equipped item that determines base damage when attacking. Has a continuous dice-roll for bonus damage (30% chance for +1, repeat on success). Auto-equips the best found Weapon. |
18| **Inventory** | A limited set of carried Pickups (4 slots). Displayed in the bottom-bar HUD. Items are used explicitly via a "use" key. |
19| **Maze** | The procedural grid of Walls, Passages, and an Exit staircase. A new Maze is generated for each Depth. |
20| **Depth** | The current dungeon floor number (infinite, increases by 1 on descending the Exit). Higher Depth means tougher Enemies, more Hallucinations, and darker visuals. |
21| **Exit** | The staircase cell that descends the Player to the next Depth. |
22| **Phantom Wall** | A Wall rendered by the engine where a Passage actually exists. The Player can walk through it. Frequency increases with low Sanity. |
23| **Phantom Passage** | A Passage rendered where a Wall actually exists. The Player cannot walk through it. Frequency increases with low Sanity. |
24| **Shifting Maze** | Cells of the actual Maze data that rearrange when the Player is not looking. Triggered at low Sanity. |
25| **Persistent Hallucination** | A Hallucination that does not vanish when walked onto or attacked. Occurs only at critically low Sanity (~<20%). The Player is blocked from moving onto its cell and must attack it repeatedly to dissipate it. |
26| **Attack** | The Player action (Space key) that strikes the adjacent cell ahead. Deals Weapon damage to whatever occupies that cell. |
27| **Room** | A rectangular open area (3×3 to 6×6 cells) in the Maze, generated by the rooms-and-corridors algorithm. Rooms provide space for combat maneuvering. |
28| **Corridor** | A 1–2 tile wide passageway connecting Rooms. |
29| **Message Log** | A single line in the HUD that displays the most recent game event (attack result, item use, blocked movement) for 2–3 Turns before fading. |
30| **Score** | Calculated on death: (Kills × 100) + (Depth² × 50) + (Weapon base damage × 500). Output to terminal. |
diff --git a/docs/PLAN.md b/docs/PLAN.md
new file mode 100644
index 0000000..a071efe
--- /dev/null
+++ b/docs/PLAN.md
@@ -0,0 +1,308 @@
1# Implementation Plan — Dungeon Crawler
2
3## Overview
4
5Transform 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.
6
7See `CONTEXT.md` for the canonical glossary of domain terms.
8
9---
10
11## Phase 0 — Turn-Based Game Loop
12
13Refactor the real-time loop into a turn-based model with smooth animations.
14
15### 0.1 — Game state machine
16Introduce a `GameState` enum:
17- `WaitingForInput` — player can press keys
18- `AnimatingPlayer` — player walk/turn animation playing
19- `AnimatingEnemies` — enemy movement animations playing (simultaneous, 100ms)
20- `ResolvingTurn` — apply damage, weakness, sanity, pickups
21- `GameOver` — fade-out and exit
22
23### 0.2 — Input gating
24- Only accept input in `WaitingForInput`.
25- On valid input → `AnimatingPlayer` (or `AnimatingEnemies` if skipping via C).
26- After all animations → `ResolvingTurn` → back to `WaitingForInput`.
27- C key skips turn (passes) — enemies still act.
28
29### 0.3 — Key bindings
30| Key | Action |
31|-----|--------|
32| W | Move forward |
33| S | Move backward |
34| A | Strafe left |
35| D | Strafe right |
36| Q | Turn 90° left |
37| E | Turn 90° right |
38| Space | Attack cell ahead |
39| Z | Use selected inventory item |
40| X | Discard selected inventory item |
41| C | Skip turn |
42| 1-4 | Select inventory slot |
43| Esc | Quit |
44
45---
46
47## Phase 1 — Rooms-and-Corridors Maze Generation
48
49Replace the recursive-backtracker (1-tile-wide corridors) with a rooms-and-corridors generator.
50
51### 1.1 — Generation algorithm
521. Place random rectangular rooms (3×3 to 6×6) on the grid, non-overlapping.
532. Connect rooms with 1–2 tile wide corridors using a minimum spanning tree or BFS carving.
543. Ensure all rooms are reachable.
554. Place the player start in a room near top-left.
565. Place the exit staircase in a room far from start.
576. 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+).
58
59### 1.2 — Exit cell
60- Exit is a passage cell with a special floor texture (tile with a hole).
61- Walking onto it shows "Press Space to descend..."
62- Pressing Space generates a new depth, places player in a different room facing east.
63
64---
65
66## Phase 2 — Entity System
67
68Pre-place entities (enemies, hallucinations, pickups) in maze cells at generation time.
69
70### 2.1 — Entity types
71```rust
72enum Entity {
73 Enemy { hp: u32, max_hp: u32, damage: u32 },
74 Hallucination { persistent: bool },
75 Pickup(PickupType),
76 HallucinatedPickup(PickupType),
77}
78```
79
80### 2.2 — Generation
81- **One entity per cell** — a cell is either empty or contains one entity.
82- Real enemies: 3–5 at depth 1, +2 per depth.
83- Hallucinations: 1–2 per level (regardless of depth). Their *behavior* scales with sanity, not their quantity.
84- Real pickups: 2–3 at depth 1, +1 per 2 depths. Mixed types (food, pill, bandage, weapon).
85- Hallucinated pickups: 0–1 at depth 1, +1 per 2 depths.
86- Weapons: 0–1, guaranteed at depths 2, 4, 6, etc.
87
88### 2.3 — Enemy stat scaling
89| Depth tier | Enemy HP range | Enemy damage |
90|------------|---------------|-------------|
91| 1 | 1 | 1 |
92| 2–3 | 2–3 | 1 |
93| 4–6 | 3–5 | 1–2 |
94| 7–9 | 5–8 | 2 |
95| 10+ | 8+ | 2+ |
96
97---
98
99## Phase 3 — Combat System
100
101### 3.1 — Attack action (Space)
102- Checks the cell directly ahead (based on facing direction).
103- If an enemy/hallucination is present in that cell → apply attack.
104- If nothing → "You swing at the air." No effect.
105
106### 3.2 — Hitting an enemy
107- Deal `base_damage + bonus_damage` to the enemy.
108- Bonus damage: 30% chance for +1, repeat on success (infinite chain, geometric distribution).
109- If enemy HP ≤ 0 → enemy dies (removed from cell).
110- Enemy retaliates if still alive: deals its damage to player HP.
111- Screen flash: red tint.
112
113### 3.3 — Hitting a hallucination
114- Non-persistent hallucination: vanishes, player loses sanity.
115- Persistent hallucination (sanity < ~20%): does NOT vanish; player loses sanity. May take multiple attacks to dissipate.
116- Screen flash: purple tint.
117
118### 3.4 — Moving onto a cell with an entity
119- **Real enemy:** blocked. "Something is blocking your way." Player loses their turn; enemy attacks.
120- **Hallucination (non-persistent):** vanishes harmlessly — no sanity cost.
121- **Persistent hallucination:** blocked. "You are frightened to death just by thinking about doing this." Turn wasted.
122- **Pickup:** auto-collected into inventory.
123- **Hallucinated pickup:** auto-collected into inventory (deception discovered on use).
124
125### 3.5 — Weapon system
126- Player always has an equipped weapon (starts with fists: base damage 1).
127- Picking up a weapon (`!`) auto-equips if its base damage is higher.
128- If base damage ≤ current weapon, display message and discard it.
129- Weapons cannot be manually discarded.
130- Hallucinated weapon: nothing happens on pickup, sanity drops slightly.
131- HUD displays `WPN:{base_damage}`.
132
133---
134
135## Phase 4 — Resource System
136
137### 4.1 — Resources
138| Resource | Start | Max | At 0 |
139|----------|-------|-----|------|
140| HP | 5 | 5 | Death |
141| Sanity | 100 | 100 | Severe distortion, persistent hallucinations |
142| Weakness | 0 | 100 | HP starts draining |
143
144### 4.2 — Per-turn effects
145- Weakness +1 every turn (passive hunger).
146- If weakness hits 100, HP drains at 1/turn.
147- Heartbeat counter increments by 1 each turn.
148
149### 4.3 — Pickup effects
150| Type | Char | Real effect | Hallucinated effect |
151|------|------|------------|-------------------|
152| Food | `F` | -20 weakness | No effect. Sanity -5. "It was never there..." |
153| Pill | `0` | -15 weakness, +20 sanity | No effect. Sanity -5. |
154| Bandage | `+` | -15 weakness, +1 HP (if HP < max) | No effect. Sanity -5. |
155
156### 4.4 — Healing feedback
157- Screen flash: green tint on successful heal.
158
159---
160
161## Phase 5 — Inventory System
162
163### 5.1 — Slots
164- 4 inventory slots.
165- Pickups auto-collect into the first empty slot.
166- If full, message "Inventory full" — pickup stays on the ground.
167
168### 5.2 — Controls
169- `1`–`4`: select slot.
170- `Z`: use selected item (consumes a turn).
171- `X`: discard selected item (does NOT consume a turn). Item disappears forever.
172
173### 5.3 — Hallucinated pickups in inventory
174- Look identical to real pickups.
175- Using one: no effect, sanity -5, message "It was never there..."
176- The item is consumed (removed from inventory) on use.
177
178---
179
180## Phase 6 — Psychedelic Horror Effects
181
182### 6.1 — Sanity thresholds (smooth interpolation)
183| Sanity | Visual effects | Semi-physical effects |
184|--------|---------------|---------------------|
185| 100–80% | Clean | None |
186| 79–60% | Mild color drift, wall breathing | 5% phantom wall/passage |
187| 59–40% | Stronger distortion, flickering textures | 10% phantom, maze shifts 5%/turn |
188| 39–20% | Heavy warping, false `@` flickers | 15% phantom, shifting 10%/turn, hallucinations patrol |
189| 19–0% | Severe distortion | 20% phantom, shifting 15%/turn, persistent hallucinations |
190
191### 6.2 — Phantom walls (A)
192- Render a wall where a passage exists.
193- Player can walk through it — discovers it was fake.
194- Randomly placed each frame; frequency scales with sanity threshold.
195
196### 6.3 — Phantom passages (B)
197- Render a passage where a wall exists.
198- Player tries to move forward → blocked (invisible wall).
199- Disorienting but doesn't trap the player.
200
201### 6.4 — Shifting maze (D)
202- On turn resolution, sanity-based % chance that 1–3 wall cells outside player FOV flip (wall ↔ passage).
203- Constraint: never block the exit, never fully enclose the player.
204- Chance: 0% at depth 1–3, 5%/turn at 59–40% sanity, 10%/turn at 39–20%, 15%/turn at 19–0%.
205
206### 6.5 — Hallucination behavior scaling
207- Depth 1–3: hallucinations static, easy to distinguish.
208- Depth 4–6 + medium sanity: hallucinations start patrolling randomly (every 3 turns).
209- Depth 7+ + low sanity: hallucinations move toward player, indistinguishable from real enemies.
210
211### 6.6 — Screen darkness
212- Two factors multiplied:
213 1. **Weakness dimming:** 0% (fresh) to ~80% (max weakness).
214 2. **Depth dimming:** 0% (depth 1) to 80% (depth 15+).
215- At depth 10 with high weakness, vision is severely restricted.
216
217---
218
219## Phase 7 — Enemy AI
220
221### 7.1 — Real enemy behavior (per turn)
2221. If adjacent to player → attack (deal damage).
2232. If line-of-sight to player → move one tile toward player (reduce Manhattan distance).
2243. If no LOS → patrol (every 3 turns): pick random adjacent passage and move there.
2254. Hallucinations at low sanity follow the same behavior.
226
227### 7.2 — Enemy animation
228- All enemies animate simultaneously (100ms duration).
229- Smooth tile-walk animation matching player's style.
230
231---
232
233## Phase 8 — HUD
234
235### 8.1 — Bottom bar (Doom-style)
236```
237[♥ 3/5] [♦ SAN: 72%] [⌂ Weak: 45%] ♥♥ 42 WPN:2 [F][0][ ][+] DEPTH:7
238```
239- Hearts for HP, diamond for sanity, house for weakness.
240- Heartbeat counter with heart symbol.
241- Weapon display.
242- 4 inventory slots showing item chars (empty = blank).
243- Current depth number.
244
245### 8.2 — Message log
246- Single line above or within the HUD bar.
247- Displays the most recent message for 2–3 turns, then fades.
248- Messages: attack results, item usage, blocked movement, hallucination encounters.
249
250### 8.3 — Entity sprites (ASCII)
251| Entity | Char | Color |
252|--------|------|-------|
253| Enemy / Hallucination | `@` | Red |
254| Food | `F` | Green |
255| Pill | `0` | Cyan |
256| Bandage | `+` | White |
257| Weapon | `!` | Yellow |
258| Exit | Floor texture (hole) | — |
259
260Rendered as scaled pixel-font sprites in the 3D view, line-of-sight only.
261
262---
263
264## Phase 9 — Score & Death
265
266### 9.1 — Score formula
267```
268Score = (Kills × 100) + (Final Depth² × 50) + (Weapon Base Damage × 500)
269```
270- Calculated on death. Output to terminal.
271- Values subject to tuning after playtesting.
272
273### 9.2 — Death sequence
2741. HP hits 0.
2752. Screen fades to black over ~2 seconds.
2763. Message: "You had become yet another legend of this dungeon."
2774. Score printed to terminal.
2785. Game exits.
279
280---
281
282## Phase 10 — Screen Flashes & Feedback
283
284| Event | Feedback |
285|-------|----------|
286| Player hits enemy | Red flash |
287| Player hits hallucination | Purple flash |
288| Player takes damage | Red flash + camera jolt |
289| Successful heal | Green flash |
290| Hallucination vanishes (walk-through) | Brief warp/distortion effect |
291| Enemy dies | White flash, entity removed |
292
293---
294
295## Implementation Strategy
296
297Build incrementally — one feature at a time:
298
2991. **Phase 0** — Turn-based loop (foundation for everything)
3002. **Phase 1** — Rooms-and-corridors generation
3013. **Phase 2 + 3 + 4** — Entities, combat, and resources (tightly coupled)
3024. **Phase 5** — Inventory
3035. **Phase 8** — HUD
3046. **Phase 7** — Enemy AI + animations
3057. **Phase 6** — Psychedelic effects
3068. **Phase 9 + 10** — Score, death, polish
307
308Each phase must be testable independently before moving to the next.