# CCC GAME STANDARD (the locked bar every kit game must hit)

This is the quality contract. A game is not "done" until it meets all of this.

## 1. Engine (never a raw renderer) — AND THE RIGHT PHYSICS FOR THE GAME
- **2D → Phaser 3. 3D → Babylon.js.** Load from a pinned CDN with SRI. The engine owns
  the loop, physics, collisions, scenes — do NOT hand-roll those.
- **Pick the physics body type by what the game needs — this is not optional:**
  - **Arcade physics** ONLY for axis-aligned movement: top-down, side-scrollers, grid games,
    simple platformers. Arcade bodies are AABBs that CANNOT rotate and CANNOT collide against
    angled or curved surfaces. Using arcade for anything that needs real bounces is the #1
    cause of "it looks right but plays broken."
  - **Matter physics (Phaser's built-in Matter plugin)** for ANY game with: angled/curved walls,
    a bouncing ball, real reflection, rotating bodies, or swinging parts. Pinball, breakout with
    angled bricks, Peggle/plinko, marble/physics puzzles, billiards, anything "bouncy" → Matter.
  - Rule of thumb: if you ever find yourself hand-writing collision math, reflection, or
    "fake" rotated colliders on top of arcade, STOP — you need Matter.
- **Matter anti-tunnelling (mandatory when you use Matter):** Matter has no continuous collision.
  Clamp the fastest body's speed BELOW the thinnest wall's thickness (e.g. maxSpeed 18 with 26px
  walls), and bump solver iterations (positionIterations ~12). A fast ball through a thin wall is
  a tunnelling bug, not bad luck.
- **Moving paddles/flippers in Matter:** drive them KINEMATICALLY (static body, set its angle each
  frame toward a target, hard-clamped to its arc). Do not fight the solver with setAngularVelocity
  on a constrained dynamic body — it oscillates and freezes. The swept kinematic body still throws
  the ball. (Reference implementation: the NEON PINBALL engine-test.)

## 2. Real art (the #1 "looks pro" lever)
- Use **custom AI-generated art** (fal.ai `nano-banana-pro`) or **Kenney CC0** packs. NEVER plain coloured shapes for the main actors.
- Cohesive single art style across background + characters + items. Sprites on transparent PNGs (chroma-key magenta if needed).

## 3. Game juice (feel)
- Easing/tweens on ALL motion (no linear movement).
- Screen shake on impacts; a brief **hit-stop** (40–80ms freeze) on big hits.
- **Particles** on every collision/score; squash & stretch; trails on fast objects; a 1-frame white flash on hits.
- Juice scales with importance — common actions get light juice, rare ones (win/boss/clear) get big juice.

## 4. Sound (never silent)
- Web Audio SFX on every action (move/hit/score/lose) + a looping music track.
- AudioContext resumes on first user gesture.

## 5. Performance (locked 60fps)
- `pixelRatio`/`hardwareScalingLevel` = 1 (never 2). Object **pooling**/recycling. **Zero per-frame allocations.** Clamp delta-time.

## 6. Structure & shell
- Scenes: Boot → Preload (asset loader w/ progress) → Menu → Game → GameOver.
- Clean HUD (score/lives/etc.), start screen, game-over screen, **high score in localStorage**, pause where sensible.
- Mobile-friendly controls (keyboard + touch). AI opponent where the game needs one.

## 6b. Clickable input MUST be reliable (every button works on the first click)
- **Put input on a plain interactive Rectangle/Zone, NOT on a Container's hitArea.** Phaser
  Container hitAreas can silently fail to register a click (you'd have to click several times).
  `UI.button` now uses a dedicated top-level hit Rectangle — use it; don't hand-roll container buttons.
- **When a modal/overlay is open, disable input on everything behind it** (e.g.
  `obj.input.enabled = false`), or the things underneath steal the click. A dim scrim alone is not
  enough — and an *interactive* full-screen scrim will itself swallow clicks meant for the buttons,
  so disable the background instead of relying on the scrim.
- **Keep modal pieces at the same level with explicit depths** (buttons on top). Phaser only sorts
  input reliably among same-level objects; mixing container-children and top-level objects breaks
  the ordering. Verify with a REAL single click in the harness, not just by eye.

## 7. Ship
- Multi-file project (index.html + assets/) → runs on a local http server, deploy-ready (Vercel/Netlify/itch).

## 8. Verify (definition of done)
- Runs with **ZERO console errors**, fully playable, the core rules actually work, holds 60fps. Captured by the verify harness (serve → console check → screenshot).
