clankgame/AGENTS.md
Rob Colbert bf29fe4949 Add README.md and AGENTS.md documentation
- README: installation, dev server, gameplay controls, screens, sound
- AGENTS.md: project structure, stack, implementation patterns, git workflow
2026-05-30 03:03:20 -04:00

72 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Working in The Clanked Game
## Stack
- **React 19** — UI rendering
- **Vite 8** — Dev server and build tooling
- **WebAudio API** — All sound synthesis (no audio files)
- **pnpm** — Package manager
## Project Layout
```
src/
App.jsx — Root component, screen state (home/main-menu/game)
components/
Game.jsx — Core game loop: canvas rendering, state, collision, input
soundEffects.js — WebAudio sound synthesis functions
```
## Key Implementation Notes
- The game loop runs in `Game.jsx` via `requestAnimationFrame`. All game logic (`updateStars`, `updatePlayer`, `updateAliens`, `checkCollisions`, etc.) is defined inside the `useEffect` and operates on `gameStateRef.current`.
- Sound effects use the WebAudio API and are stateless helpers in `soundEffects.js`. Call `getAudioContext()` lazily on first use (browser autoplay policy).
- Shields are stored as 2D boolean grids (pixel-level destruction without canvas complexity).
- The canvas renders at **800×600** (`CANVAS_WIDTH`, `CANVAS_HEIGHT`).
## Adding Sound Effects
Functions in `soundEffects.js` follow the same pattern:
```js
export const playXSound = () => {
const ctx = getAudioContext();
const currentTime = ctx.currentTime;
const oscillator = ctx.createOscillator();
const gainNode = ctx.createGain();
oscillator.type = 'square'; // or 'sine', 'sawtooth', or white noise via AudioBuffer
// configure frequency...
// configure gain envelope...
oscillator.connect(gainNode);
gainNode.connect(ctx.destination);
oscillator.start(currentTime);
oscillator.stop(currentTime + duration);
};
```
For white noise, create an `AudioBuffer` filled with `Math.random() * 2 - 1` values and use a `BufferSourceNode`.
## Adding Gameplay Features
- New game state fields go in `gameStateRef.current` (line ~95).
- New per-frame update functions follow `updateStars`, `updatePlayer`, etc. pattern and are called in the game loop in order.
- New draw functions follow `drawStars`, `drawPlayer`, etc. pattern and are called in the render section of `gameLoop()`.
- Screen transitions happen via `setCurrentScreen()` in `App.jsx` — pass an `onExit` callback from `Game` to return to main menu.
## Git Workflow
- Branch: `develop`
- Push to `origin/develop` after meaningful changes.
## npm Scripts
| Command | Description |
|---------|-------------|
| `pnpm dev` | Start Vite dev server with HMR |
| `pnpm build` | Production build to `dist/` |
| `pnpm lint` | Run ESLint |
| `pnpm preview` | Preview production build locally |