mirror of
https://github.com/tiennm99/try-claudekit.git
synced 2026-04-17 17:21:50 +00:00
Add CLAUDE.md with architecture overview and dev commands for future Claude Code sessions. Update README with tech stack, project structure, and how-to-play instructions. Add spec for fixing collision physics tuning issues.
2.4 KiB
2.4 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
npm run dev # Start Vite dev server (http://localhost:5173)
npm run build # Production build to dist/
npm test # Run all tests once
npm run test:watch # Run tests in watch mode
npx vitest run src/fruits.test.js # Run a single test file
No vite.config or vitest.config files — both use defaults.
Architecture
This is a Suika Game (watermelon merge puzzle) built with vanilla JavaScript + Matter.js + Canvas2D, bundled by Vite.
Module Orchestration
game.js is the central orchestrator. The Game class owns the physics engine and game state, delegating to specialized modules:
- physics.js — Thin wrapper around Matter.js. Creates engine, walls, fruit bodies. Bodies are annotated with custom properties:
fruitTier(0-10),removing(merge flag),dropTime(grace period timestamp). - merger.js — Listens to Matter.js
collisionStartevents. Queues merges into a pending array;flushMerges()is called by the game loop afterEngine.update()to avoid mid-step world mutation. ReceivesaddScore()callback to stay decoupled from game state. - renderer.js — Pure rendering:
render(ctx, bodies, state)draws everything to Canvas2D with no side effects. - input.js — Mouse/touch event binding +
clampX()utility that accounts for fruit radius to keep drops within container walls. - fruits.js — Static array of 11 fruit tiers. Only tiers 0-4 are randomly selected for dropping.
- constants.js — Single source of truth for all dimensions, physics tuning, and timing values.
Key Patterns
- Deferred merge processing: Collisions are queued during physics events, then flushed after the engine step completes. This prevents Matter.js internal state corruption.
- Grace period: Newly dropped fruits have 1000ms immunity from game-over detection to prevent instant-loss on drops near the danger line.
- State via callbacks:
setupMergeHandler()receivesgetState()andaddScore()callbacks rather than importing game state directly.
Testing
Tests are colocated (src/*.test.js) using Vitest with describe/it/expect. No mocking — tests use real Matter.js engine instances and pure function assertions. Physics integration tests step the engine 10-60 times and assert state changes.