html5-canvas-game-development

/home/avalon/.hermes/skills/software-development/html5-canvas-game-development/SKILL.md · raw

HTML5 Canvas Game Development

Overview

Use this for the common class of work where an existing browser Canvas game must gain major new capabilities without a full engine rewrite. The reliable strategy is adaptation-by-injection: preserve the game loop and state model, then bridge new inputs, layouts, and networking into it.

When to Use

1. Mobile/touch adaptation

Key pattern: inject touch state into the same heldKeys / pressedKeys structures the game already reads.

Important lessons: - adapt camera width/viewport first; do not rewrite game logic - keep SCENE_HEIGHT unchanged when narrowing mobile view, or portrait letterboxing gets ugly - use HTML controls for touch input instead of Canvas hit-testing - prevent browser scroll/zoom aggressively on the game/control surfaces

HUD/layout lesson: - many games call setTransform(...) internally, which clobbers parent scale wrappers - scale HUD coordinates directly instead of relying on one outer context.scale() wrapper

2. Online multiplayer

Preferred architecture for existing browser games: - P1 host runs the full simulation - P2 sends inputs via WebSocket relay - P1 injects remote inputs, simulates, and broadcasts state back - server stays a dumb relay, not a full game server

This avoids a huge rewrite while still giving usable real-time multiplayer.

3. HTML overlays beat Canvas UI

For lobbies, room codes, buttons, and actionable text: - use HTML overlays, not canvas-drawn controls - Canvas text becomes fragile under CSS scaling and mobile layouts - HTML is easier for copying links, accessibility, touch handling, and responsive styling

4. Performance and sync

For multiplayer sync: - send state every second frame when possible - shorten JSON keys / use delta compression - send remote inputs only on change - interpolate positions client-side while snapping discrete animation/state fields

Common Pitfalls

  1. setTransform() silently wiping out outer scaling assumptions
  2. Canvas-drawn UI becoming unusable under object-fit / viewport scaling
  3. Using fixed-position HTML controls that overlap mobile touch controls
  4. Attempting a headless authoritative server rewrite when P1-host relay would suffice
  5. Forgetting to handle Blob/ArrayBuffer WebSocket payloads in browsers

Verification Checklist