# AGENTS.md — Zelda Dungeon Quest ## Run Commands - **Browser dev**: `npm run dev` → `npx serve . -p 3000`, open `http://localhost:3000` - **Electron**: `npm start` (requires `--no-sandbox` on Linux, or `ELECTRON_DISABLE_SANDBOX=1`) - **Node tests**: `node test-full-node.js` (VM-based, simulates browser env) - **Regenerate bosses**: `node generate-bosses.js` (rewrites `src/data/bosses.js`) ## Module System — Critical This project uses a **custom browser polyfill** (`src/browser-polyfill.js`) that makes Node-style `module.exports` / `require()` work in the browser. Every source file must follow this pattern: 1. **Export via `module.exports`** at the end of each file: ```js if (typeof module !== 'undefined' && module.exports) { module.exports = { exportedName1, exportedName2 }; } ``` 2. **Symbols go to `window`** — the polyfill's `module.exports` setter mirrors all exported properties to `window`. Cross-module access reads from `window`. 3. **`moduleKeys` registry** — `src/browser-polyfill.js` maintains a `moduleKeys` map that tells `require()` which `window` keys belong to each module path. **When you add new exports to any module, you MUST add them to the matching entry in `moduleKeys`, or `require()` will not return them.** 4. **Script load order** — `index.html` loads scripts in a strict sequence. The polyfill loads first, then modules in dependency order. Adding a new script requires inserting it at the correct position in `index.html`. ## File Architecture ``` renderer.js ← Legacy prototype (3-room, standalone). NOT used by index.html. src/app.js ← Bootstrap: init, game loop, screen switching src/browser-polyfill.js ← CommonJS polyfill (moduleKeys registry) src/core/ ← Constants, RNG, utilities (loaded first) src/data/ ← Static definitions: themes, dungeons(100), enemies(22), weapons(12), bosses(100), items src/generator/ ← Procedural generation: dungeon layout, rooms, puzzles, placement src/game/ ← Engine: state, movement, combat, AI, items, transitions src/input/ ← Keyboard tracking, action bindings src/rendering/ ← Canvas rendering: tiles, entities, HUD, effects src/menu/ ← Title screen, dungeon select, inventory overlay, end screens src/save/ ← localStorage save/load ``` Grid: 32×24 tiles, 32px each. Canvas: 640×480. ## Known Bug `src/app.js:390` — The `init()` function's closing `}` appears before lines that should be inside it (screen setup, game loop start, debug logging). Lines 392-406 are outside the function scope. Move the closing brace to after line 406 to fix. ## Conventions - All source files start with `'use strict'` - Constants live in `src/core/constants.js`; other modules import via `require` - `gameState` and `inputSystem` are module-level globals exposed to `window` by `app.js` - `ctx`, `debugCtx`, `menuOverlay` are exposed to `window` by `app.js` for cross-module rendering - Screen states use string constants: `SCREEN_TITLE`, `SCREEN_DUNGEON_SELECT`, etc. - Debug mode: append `?debug=1` to URL; `F1` toggles overlay in-game - Console API (browser): `_genDungeon(id)`, `spawnEnemy(type)`, `giveWeapon(name)`, `teleportToRoom(idx)`, `dumpState()`