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

2.5 KiB
Raw Blame History

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:

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