225 lines
10 KiB
Markdown
225 lines
10 KiB
Markdown
# Zelda Dungeon Expansion — Plan Document
|
|
|
|
## Goal
|
|
Expand from 3-room prototype to **100 procedurally-generated dungeons**, each with **20-100 rooms**, **20+ enemy types**, **12 weapons**, **100 unique bosses**, dungeon selection menu, save system, and sequential progression.
|
|
|
|
## Target: Browser-First
|
|
- Runs in a standard web browser (no Electron dependency for testing)
|
|
- Electron wrapper added later via existing `main.js` / `preload.js`
|
|
- Playtesting via `npx serve` or simple HTTP server
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### File Structure
|
|
```
|
|
zelda-dungeon/
|
|
├── index.html ← Main entry point (browser), loads all scripts
|
|
├── main.js ← Electron main process (untouched for now)
|
|
├── preload.js ← Electron IPC bridge (updated for save data)
|
|
├── package.json ← Add "dev" script for browser testing
|
|
│
|
|
├── src/
|
|
│ ├── core/
|
|
│ │ ├── constants.js ← TILE, COLS, ROWS, tile types, timing, COLORS
|
|
│ │ ├── rng.js ← Seeded RNG (mulberry32) for reproducibility
|
|
│ │ └── utils.js ← Helper functions (createBorderLayout, drawHeart, etc.)
|
|
│ │
|
|
│ ├── data/
|
|
│ │ ├── themes.js ← Dungeon themes (Forest, Desert, Mountain, etc.) with colors
|
|
│ │ ├── dungeons.js ← 100 dungeon definitions (name, theme, difficulty, seed, room count)
|
|
│ │ ├── enemies.js ← 22 enemy type definitions (stats, AI, draw functions)
|
|
│ │ ├── bosses.js ← 100 boss definitions (one per dungeon)
|
|
│ │ ├── weapons.js ← 12 weapon definitions (damage, range, effects, draw functions)
|
|
│ │ └── items.js ← Consumables (potions, heart pieces, arrows, bombs, keys)
|
|
│ │
|
|
│ ├── generator/
|
|
│ │ ├── dungeon.js ← Generates full dungeon from definition (rooms + connections)
|
|
│ │ ├── rooms.js ← Generates individual rooms (layout, enemies, items, puzzles)
|
|
│ │ ├── puzzles.js ← Puzzle generation (rock-push, levers, keys, switches)
|
|
│ │ └── placement.js ← Placement logic (enemy/item density by difficulty tier)
|
|
│ │
|
|
│ ├── game/
|
|
│ │ ├── state.js ← Game state management (player, room, dungeon, menus)
|
|
│ │ ├── combat.js ← Attack resolution, damage, effects
|
|
│ │ ├── movement.js ← Player movement, rock pushing, exit handling
|
|
│ │ ├── ai.js ← Enemy AI (chase, patrol, shoot, special behaviors)
|
|
│ │ ├── items.js ← Item pickup, chest opening, inventory management
|
|
│ │ └── transitions.js ← Room transitions, screen fades
|
|
│ │
|
|
│ ├── rendering/
|
|
│ │ ├── renderer.js ← Canvas drawing (floor, walls, torches, entities)
|
|
│ │ ├── draw-enemies.js ← Per-enemy-type draw functions
|
|
│ │ ├── draw-bosses.js ← Boss draw functions (larger, multi-phase visuals)
|
|
│ │ ├── draw-weapons.js ← Weapon draw functions
|
|
│ │ ├── hud.js ← HUD rendering (hearts, weapon, ammo, room info)
|
|
│ │ └── effects.js ← Particles, hit flashes, screen transitions
|
|
│ │
|
|
│ ├── input/
|
|
│ │ ├── keyboard.js ← Key state tracking, action binding
|
|
│ │ └── actions.js ← Action definitions (move, attack, use item, select)
|
|
│ │
|
|
│ ├── menu/
|
|
│ │ ├── title-screen.js ← Title screen rendering + interaction
|
|
│ │ ├── dungeon-select.js ← Dungeon grid, filtering, info panel
|
|
│ │ ├── hud-overlay.js ← In-game menu (inventory, weapon switch)
|
|
│ │ └── screens.js ← Death/win/completion screens
|
|
│ │
|
|
│ ├── save/
|
|
│ │ └── save.js ← localStorage save/load, progress tracking
|
|
│ │
|
|
│ └── app.js ← Main bootstrap (init, game loop, screen switching)
|
|
```
|
|
|
|
---
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1: Core Infrastructure
|
|
- [ ] Create directory structure
|
|
- [ ] `constants.js` — All shared constants (TILE, COLS, ROWS, COLORS, timing)
|
|
- [ ] `rng.js` — Seeded PRNG (mulberry32)
|
|
- [ ] `utils.js` — Reusable helpers (createBorderLayout, drawHeart, DIRS, etc.)
|
|
- [ ] `index.html` — New HTML that loads all scripts, canvas, menu div
|
|
- [ ] `app.js` — Bootstrap: init → title screen → game loop
|
|
- [ ] Validate: Open in browser, see title screen
|
|
|
|
### Phase 2: Data Definitions
|
|
- [ ] `themes.js` — 8 themes (Forest, Desert, Mountain, Underground, Ocean, Sky, Shadow, Final) with color palettes
|
|
- [ ] `dungeons.js` — 100 dungeon definitions (generated procedurally from themes)
|
|
- [ ] `enemies.js` — 22 enemy types with stats, behaviors, colors, draw functions
|
|
- [ ] `weapons.js` — 12 weapons with damage, range, cooldown, effects
|
|
- [ ] `bosses.js` — 100 bosses (one per dungeon), template-based with variations
|
|
- [ ] `items.js` — Consumables definitions
|
|
- [ ] Validate: Data files load without errors, can inspect in console
|
|
|
|
### Phase 3: Procedural Generation
|
|
- [ ] `generator/dungeon.js` — BSP/DFS room layout generation from seed
|
|
- [ ] `generator/rooms.js` — Room type assignment, layout generation
|
|
- [ ] `generator/puzzles.js` — Puzzle generation (rock-push, levers, keys)
|
|
- [ ] `generator/placement.js` — Enemy/item placement by difficulty tier
|
|
- [ ] Validate: Generate dungeon #1, inspect rooms, verify connectivity
|
|
|
|
### Phase 4: Game Engine
|
|
- [ ] `game/state.js` — Game state (player, current room, inventory, progress)
|
|
- [ ] `game/movement.js` — Player movement, rock pushing, collision
|
|
- [ ] `game/combat.js` — Attack resolution, weapon effects, damage
|
|
- [ ] `game/ai.js` — Enemy AI (chase, patrol, ranged, special)
|
|
- [ ] `game/items.js` — Chest opening, item pickup, inventory
|
|
- [ ] `game/transitions.js` — Room transitions, screen fades
|
|
- [ ] `input/keyboard.js` — Key tracking, action dispatch
|
|
- [ ] `input/actions.js` — Action definitions
|
|
- [ ] Validate: Play through generated dungeon #1 in browser
|
|
|
|
### Phase 5: Rendering
|
|
- [ ] `rendering/renderer.js` — Floor, walls, torches (theme-colored)
|
|
- [ ] `rendering/draw-enemies.js` — All 22 enemy draw functions
|
|
- [ ] `rendering/draw-bosses.js` — Boss draw functions
|
|
- [ ] `rendering/draw-weapons.js` — Weapon visual indicators
|
|
- [ ] `rendering/hud.js` — Hearts, weapon icon, ammo, room counter
|
|
- [ ] `rendering/effects.js` — Particles, hit flash, screen transitions
|
|
- [ ] Validate: Visual rendering looks correct for all entity types
|
|
|
|
### Phase 6: Menu System
|
|
- [ ] `menu/title-screen.js` — Title, start button, controls
|
|
- [ ] `menu/dungeon-select.js` — 10x10 grid, theme filter, difficulty, lock status
|
|
- [ ] `menu/screens.js` — Death, win, dungeon completion screens
|
|
- [ ] Validate: Navigate menus, select dungeon, enter game
|
|
|
|
### Phase 7: Save System
|
|
- [ ] `save/save.js` — localStorage persistence
|
|
- [ ] Save format: `{ completedDungeons: [], weapons: [], heartPieces: N, totalRooms: N }`
|
|
- [ ] Auto-save on dungeon completion
|
|
- [ ] Resume functionality
|
|
- [ ] Validate: Complete dungeon → close browser → reopen → progress saved
|
|
|
|
### Phase 8: Integration & Polish
|
|
- [ ] Connect all systems end-to-end
|
|
- [ ] Playtest first 10 dungeons
|
|
- [ ] Balance difficulty curve
|
|
- [ ] Screen transition effects
|
|
- [ ] Error handling, edge cases
|
|
- [ ] Validate: Full playthrough dungeon #1 → #10
|
|
|
|
### Phase 9: Electron Integration (Later)
|
|
- [ ] Update `preload.js` — expose save/load IPC
|
|
- [ ] Update `main.js` — if needed
|
|
- [ ] Validate: `npm start` works in Electron
|
|
|
|
---
|
|
|
|
## Technical Decisions
|
|
|
|
### Seeded RNG
|
|
- Mulberry32 algorithm: fast, deterministic, good quality for game generation
|
|
- Same seed → same dungeon every time
|
|
- Seeds stored in `dungeons.js` definitions
|
|
|
|
### Room Generation Algorithm
|
|
- Randomized DFS (depth-first search) for organic-feeling dungeons
|
|
- Room sizes: 5x5 to 12x12 tiles
|
|
- Corridors connect rooms (1-tile wide, L-shaped)
|
|
- Room types assigned by dungeon phase (early/mid/late)
|
|
|
|
### Difficulty Scaling
|
|
- Dungeon difficulty: 1-10 (based on index)
|
|
- Room count: 20 (difficulty 1-2) → 100 (difficulty 10)
|
|
- Enemy density: 0-1 per room (easy) → 2-4 per room (hard)
|
|
- Enemy types unlocked by difficulty tier
|
|
- Boss HP scales with dungeon difficulty
|
|
|
|
### State Management
|
|
- Single `game` object with nested state
|
|
- Screen states: `TITLE`, `DUNGEON_SELECT`, `PLAYING`, `DEAD`, `DUNGEON_COMPLETE`, `GAME_COMPLETE`
|
|
- Room data regenerated from seed on entry (no permanent room state)
|
|
- Player state persists across rooms within a dungeon
|
|
- Inventory persists across dungeons
|
|
|
|
### Combat System
|
|
- Weapon-based damage (varies by weapon type)
|
|
- Attack cooldowns per weapon
|
|
- Ranged weapons (bow, slingshot, rods) have projectile system
|
|
- Special effects: fire (AoE), ice (freeze), boomerang (return), bombs (destroy walls)
|
|
- Enemy HP, defense, attack damage, attack cooldown
|
|
|
|
### Enemy AI Behaviors
|
|
- `chase`: Pathfind toward player (existing behavior)
|
|
- `patrol`: Wander predefined path
|
|
- `ranged`: Shoot projectiles at player
|
|
- `stationary`: Activate on proximity
|
|
- `charge`: Rush at player in straight line
|
|
- `teleport`: Random teleportation
|
|
- `explode`: Explode on contact or timer
|
|
|
|
---
|
|
|
|
## Playtesting Hooks
|
|
|
|
### Debug Mode
|
|
- `?debug=1` URL parameter enables debug overlay
|
|
- Shows: room grid, collision boxes, AI state, generation seed
|
|
- `F1` toggles debug overlay during gameplay
|
|
- `F2` forces next room (skip puzzles)
|
|
- `F3` god mode (invincible)
|
|
- `F4` spawn debug enemy at player position
|
|
|
|
### Console API
|
|
- `generateDungeon(id)` — Generate and inspect any dungeon
|
|
- `spawnEnemy(type)` — Spawn enemy at player position
|
|
- `giveWeapon(name)` — Add weapon to inventory
|
|
- `teleportToRoom(idx)` — Jump to room by index
|
|
- `dumpState()` — Print full game state to console
|
|
|
|
### Performance
|
|
- Room rendering only draws visible tiles + buffer
|
|
- Enemy AI updates throttled by type
|
|
- Particle system capped at 100 particles
|
|
|
|
---
|
|
|
|
## Browser Testing
|
|
|
|
- `npm run dev` → `npx serve .` for local HTTP server
|
|
- Open `http://localhost:3000` in browser
|
|
- `npm start` → Electron app (for later) |