skillby tolitius

game

Autonomous browser game agent. Analyzes game concept, implements with KAPLAY.js (2D) or Three.js (3D), playtests in headless browser, critiques gameplay/mechanics, fixes, and launches the result.

Installs: 3
Used in: 1 repos
Updated: 2d ago
$npx ai-builder add skill tolitius/game

Installs to .claude/skills/game/

# Game Agent
Use this skill to create browser-based games using KAPLAY.js (2D) or Three.js (3D) with a focus on **playable mechanics, clear feedback, and polished feel**.

## Workflow
Follow this **strict loop** when asked to create a game:

### Phase 1: Bootstrap
1. **Check Context**: If `package.json` is missing, run `bash .claude/skills/game/scripts/setup.sh`.
2. **Scaffold**: Ensure `index.html` and `src/game.js` exist (or inline in index.html).
3. **Read API Reference**:
   - For 2D games: Read `references/kaplay-ref.md` for KAPLAY API.
   - For 3D games: Read `references/threejs-ref.md` for Three.js API.
   - For FPS games: Read `references/fps-patterns.md` for pointer lock, hit detection, enemy AI.
4. **Read Game Patterns**: Read `references/game-patterns.md` for architecture patterns.
5. **Read Game Systems**: Read `references/game-systems.md` for difficulty scaling, scoring, persistence, and UI patterns.
6. **Read Visual Assets**: Read `references/visual-assets.md` for procedural sprites, palettes, and visual effects.

### Phase 1.5: Game Design Analysis (Before Coding!)

This game needs to be **playable and fun** from the first iteration.
Therefore, define the core loop before writing any code.

Before writing any code, decompose the game:

1. **Identify the Core Mechanic**: What is the ONE thing the player does repeatedly?
   - Strip away everything else first
   - This mechanic must be satisfying on its own
   - Examples: jump, shoot, match, dodge, collect, solve

2. **Define the Challenge**: What makes it difficult?
   - Timing? Precision? Resource management? Puzzle solving?
   - How does difficulty progress?
   - What's the failure state?

3. **Establish the Feedback Loop**:
   - **Input**: What does the player press/click/drag?
   - **Response**: What happens immediately? (must feel < 100ms)
   - **Outcome**: Success or failure indication
   - **Reward/Penalty**: Score change, sound, visual effect

4. **Scope to Minimum Viable Game (MVG)**:
   - ONE level or endless mode
   - ONE enemy type or obstacle  
   - ONE player ability
   - Win AND lose conditions
   - Can be expanded later, but MVG must work first

5. **Research the Domain** (for educational/simulation games):
   - Look up actual facts (angles, counts, formulas, rules)
   - Don't guess scientific/mathematical details
   - See `references/physics-constants.md` for common values

### Phase 1.6: Game Feel Principles

6. **Juice**: The game must feel alive and responsive.
   - **Input Response**: Every input produces immediate visual/audio feedback
   - **Screen Shake**: On impacts, collisions, explosions - use `shake(intensity)`
   - **Flash**: Brief color flash on damage or success - use `flash(color, duration)`
   - **Particles**: On deaths, pickups, actions (spawn small objects with `lifespan`)
   - **Squash & Stretch**: Scale objects on jumps, bounces, movements

7. **Clarity**: The player must always understand:
   - Where they are (player position obvious, distinct color/shape)
   - What they can do (affordances clear)
   - What hurts them (dangers visually distinct - red, spiky, animated)
   - What helps them (pickups/goals highlighted - gold, glowing, animated)
   - Current state (score, lives, progress visible in HUD)

8. **Pacing**: Control the rhythm
   - Moments of tension followed by release
   - Difficulty curves, not walls
   - Rest points between challenges
   - Even endless games need rhythm variation (spawn rate waves)

9. **Polish Details**:
   - Title/start screen with game name and controls
   - Pause functionality (P key or Escape)
   - Restart on game over (R key)
   - Score or progress display (top-left, `fixed()` for HUD)
   - Control hints visible ("Arrow keys: Move | Space: Jump")

### Phase 1.7: Physics & Reachability Validation

**CRITICAL**: Validate that game physics allow the player to accomplish required actions.

16. **Test Core Movement**: Before finalizing level/game design:
    - Can the player reach all required locations?
    - Can the player avoid all avoidable hazards?
    - Does movement feel responsive (not sluggish or twitchy)?
    - Are speeds balanced (player vs enemies vs projectiles)?

17. **Validate With Math**: For physics-based games, calculate limits:
    - Movement range per second = speed × time
    - Jump/launch height = (force)² / (2 × gravity)
    - Projectile range = speed × lifetime
    - **If design requires X, verify physics allow X**

18. **Common Physics Pitfalls**:
    - Targets placed beyond movement range
    - Gaps larger than jump/dash distance
    - Enemies faster than player can react
    - Timers shorter than required actions
    - **Always prototype movement before building levels**

### Phase 1.8: Visual Polish (Before Coding!)

**CRITICAL**: Games must look polished from the first iteration. No "sticks and boxes."

**Quality Bar**: Ask yourself - "Would someone pay $5 for this?" If not, it's not ready.

10. **Choose a Color Palette**: Select from `visual-assets.md` palettes:
    - `PASTEL` - friendly, casual games
    - `PICO8` - retro pixel art feel
    - `ENDESGA` - modern indie aesthetic
    - `NEON` - cyberpunk, arcade style

11. **Generate PREMIUM Procedural Sprites**: Every sprite needs MULTIPLE layers of polish:
    - **Player/Hero**: outer glow + multi-stop gradient + shadow + character details (eyes, expression) + highlights
    - **Collectibles**: glow aura + metallic/shiny gradient + inner detail + shine streak + sparkle accents
    - **Enemies/Hazards**: danger glow + gradient body + expressive features + shadow + distinguishing details
    - **Environment** (platforms, walls, tiles): surface texture + body gradient + edge highlights + shadow + structural details
    - **Projectiles/Effects**: core glow + color gradient + trail suggestion + bright center
    - **NEVER use bare `rect()`, `circle()`, `polygon()` for visible game objects**
    - **"Has a gradient" is NOT enough** - premium sprites have 5+ visual layers
    - See `visual-assets.md` for the universal sprite layer checklist

12. **Create Gradient Background**: Flat backgrounds look cheap.
    - Use `makeGradientBg()` with palette colors
    - Add subtle stars/dots for depth
    - Consider parallax layers for side-scrollers

13. **Add Idle Animations**: Static objects feel dead.
    - Coins: `addFloat()` - gentle bobbing
    - Player: `addBreathing()` - subtle scale pulse
    - Enemies: combine breathing + slight movement
    - Pickups: `addSpin()` or glow pulse

14. **Plan Particle Effects**: Every interaction needs MULTIPLE feedback layers:
    - **Positive events** (collect, score, win): particle burst + floating text (+1, +100) + screen flash + UI reaction + small shake
    - **Negative events** (damage, death, lose): explosion particles + screen shake + color flash + UI feedback
    - **Movement events** (jump, dash, land, turn): directional particles + object deformation (squash/stretch/spin)
    - **Ambient atmosphere**: floating particles + twinkling/pulsing background elements
    - **Projectiles/Actions**: spawn flash + trail particles + impact burst
    - **One effect is NOT enough** - premium feedback stacks 3+ effects per action

15. **Establish Z-Index Hierarchy**: Proper layering adds depth.
    - Background: z(-100)
    - Platforms: z(0)
    - Pickups: z(10)
    - Enemies: z(20)
    - Player: z(30)
    - Particles: z(50)
    - HUD: z(100) + fixed()

### Phase 2: Autonomous Loop (The "Work")
Repeat this cycle until the game is **Playable and Polished**:

1. **Implement/Refine**: Write game code.
   * *Constraint*: Use KAPLAY.js for 2D (default), Three.js only if 3D is explicitly needed.
   * *Constraint*: Single HTML file with CDN imports (no build step for player).
   * *Constraint*: **Color Palette**: Use a predefined palette from `visual-assets.md` (PASTEL, PICO8, ENDESGA, NEON).
   * *Constraint*: **No Bare Primitives**: NEVER use `rect()`, `circle()`, `polygon()` for game objects. Use procedural sprites from `visual-assets.md`.
   * *Constraint*: **Gradient Background**: Always use `makeGradientBg()` instead of flat `background` color.
   * *Constraint*: **Idle Animations**: All game objects must have subtle animations (float, breathe, pulse, spin).
   * *Constraint*: **Particle Effects**: Every collision/pickup must spawn particles using `burstParticles()` or `deathExplosion()`.
   * *Constraint*: **Z-Index Layering**: Use proper z-index hierarchy (BG:-100, platforms:0, pickups:10, enemies:20, player:30, particles:50, HUD:100).
   * *Constraint*: **Game Loop**: Use KAPLAY's `onUpdate()` for continuous logic. Never use `noLoop()`.
   * *Constraint*: **Input Handling**: Use KAPLAY's `onKeyPress`, `onKeyDown`, `isKeyDown`.
   * *Constraint*: **Collision**: Use `area()` component and `onCollide()` for interactions.
   * *Constraint*: **Canvas sizing**: 800x600 or 16:9 aspect ratio.
   * *Constraint*: **State Management**: Use KAPLAY scenes for menu/play/gameover states.
   * *Constraint*: **HUD**: Use `fixed()` and `z(100)` for UI that ignores camera.
   * *Constraint*: **Controls Display**: Show control hints on screen at all times.
   * *Constraint*: **Keyboard Handling**: Use `onKeyPress("space", ...)` not raw DOM events for game input.

2. **Playtest**: Run `node playtest.js`
   - Captures screenshots at t=0, t=2s, t=5s
   - Simulates basic inputs (arrow keys, space, click)
   - Checks console for errors
   - Extracts game state variables if exposed

3. **Critique**:
   * **Logs**: Are there JavaScript errors?
   * **Visual Audit**: Open *all* generated screenshots (`playtest-screenshots/`) and evaluate:
     * **Does it run?**: Is there movement/change between frames?
     * **Input Response**: Did simulated input cause visible change?
     * **Readability**: Is text/HUD legible? Good contrast?
     * **Composition**: Is game area centered? Nothing cut off?
     * **State Changes**: Can you see game progressing (score changing, objects moving)?
   * **Visual Quality Audit** (CRITICAL - no sticks and boxes!):
     * **No bare primitives?**: Are all objects using procedural sprites with gradients/details?
     * **Gradient background?**: Is the background a gradient (not flat color)?
     * **Objects alive?**: Do coins bob, player breathe, objects animate?
     * **Particles present?**: Are there particle effects on interactions?
     * **Color harmony?**: Is a consistent palette used throughout?
     * **Visual depth?**: Are z-indexes creating proper layering?
     * **Glow/highlights?**: Do important objects (coins, player) have visual emphasis?
   * **Gameplay Audit** (mental simulation):
     * Is the core mechanic present and functional?
     * Is there a clear goal?
     * Is there a failure state?
     * Would a player understand what to do without external instructions?

4. **Decide**:
   * *Errors?* → Fix code → **Repeat**.
   * *Static/Frozen?* → Fix game loop, ensure `onUpdate` runs → **Repeat**.
   * *No Input Response?* → Fix input handlers, check key names → **Repeat**.
   * *Missing Feedback?* → Add juice (shake, flash, particles) → **Repeat**.
   * *Unclear Goal?* → Add visual indicators, HUD elements → **Repeat**.
   * *No Win/Lose?* → Implement end conditions → **Repeat**.
   * *Unreadable Text?* → Increase font size, add contrast → **Repeat**.
   * *Bare rectangles/circles?* → Replace with procedural sprites → **Repeat**.
   * *Flat background?* → Add gradient background → **Repeat**.
   * *Static objects?* → Add idle animations (float, breathe) → **Repeat**.
   * *No particles?* → Add burst/explosion effects → **Repeat**.
   * *Playable, Clear, Responsive & Visually Polished?* → **Proceed to Phase 3**.

### Phase 3: Presentation (The "Launch")
Once the loop is complete and the game is polished:
1. **Launch**: Run `npx vite --open`.
2. **Notify**: Tell the user:
   - "Game is ready!"
   - "Controls: [List all controls]"
   - "Goal: [One sentence on how to win/play]"

---

## Technology Selection

| Request Type | Framework | Template |
|-------------|-----------|----------|
| 2D game (default) | KAPLAY.js | `templates/kaplay-2d.html` |
| 3D game (explicit) | Three.js | `templates/threejs-3d.html` |
| FPS / first-person shooter | Three.js | `templates/threejs-fps.html` |
| Ultra-simple (quiz, flashcard) | Vanilla Canvas | `templates/canvas-minimal.html` |

**Decision rule**:
- Use KAPLAY for most 2D games (platformer, top-down, puzzle, etc.)
- Use `threejs-fps.html` for first-person shooters, DOOM-likes, or any game requiring pointer lock + mouse look
- Use `threejs-3d.html` for third-person 3D games, 3D puzzles, or non-shooter 3D experiences
- FPS indicators: "first-person", "FPS", "shooter", "DOOM", "Wolfenstein", "gun", "pointer lock"

---

## File References
- **KAPLAY API**: See `references/kaplay-ref.md` for component list and patterns
- **Visual Assets**: See `references/visual-assets.md` for procedural sprites, color palettes, animations, and particle effects
- **Three.js API**: See `references/threejs-ref.md` for 3D setup
- **FPS Patterns**: See `references/fps-patterns.md` for pointer lock, hit detection, enemy AI, weapon rendering
- **Game Systems**: See `references/game-systems.md` for difficulty scaling, scoring, persistence, UI patterns
- **Game Patterns**: See `references/game-patterns.md` for architecture (state machines, ECS, proc-gen)
- **Physics Constants**: See `references/physics-constants.md` for educational accuracy

---

## Common Pitfalls (Avoid These)

### Gameplay Pitfalls
1. **No game loop**: Forgetting `onUpdate()` results in static screen
2. **Wrong key names**: Use `"space"` not `"Space"`, `"left"` not `"ArrowLeft"` in KAPLAY
3. **Missing `area()`**: Objects won't collide without the `area()` component
4. **Missing `body()`**: Objects won't fall or respond to physics without `body()`
5. **HUD moves with camera**: Use `fixed()` component for UI elements
6. **No scenes**: Putting everything in global scope - use `scene()` for states
7. **Forgetting `go()`**: Must call `go("sceneName")` to start the first scene
8. **Text too small**: Default text size is often too small - use 20+ for HUD
9. **No restart**: Player stuck at game over - always add R to restart
10. **Missing `opacity()` for `lifespan()`**: The `lifespan` component requires `opacity()` to be present on the object
11. **Unreachable goals**: ALWAYS verify physics allow completing required actions. If player must reach X, calculate whether movement/jump/projectile range allows it.
12. **Variable name `rgb` conflicts with KAPLAY**: Never use `const rgb = ...` as it shadows KAPLAY's `rgb()` function. Use `const c = hexToRgb(...)` instead.

### Visual Pitfalls (CRITICAL)
13. **Bare primitives**: Using `rect()`, `circle()`, `polygon()` for game objects looks terrible - use procedural sprites
14. **Flat backgrounds**: `background: [r,g,b]` looks cheap - use `makeGradientBg()` with texture/particles
15. **Static objects**: Game objects sitting motionless feel dead - add idle animations (`addFloat()`, `addBreathing()`, `addSpin()`)
16. **No particles**: Interactions without visual feedback are unsatisfying - add particle bursts on all events
17. **Random colors**: Picking colors without a palette creates visual chaos - use PASTEL, PICO8, ENDESGA, or NEON
18. **No z-index**: Everything at same layer looks flat - use proper z-index hierarchy (-100 to 100)
19. **No glow/outline**: Important objects don't stand out - add glow/aura to key game objects
20. **Bean for everything**: `loadBean()` is a placeholder, not a finished sprite - create proper procedural sprites
21. **"Good enough" sprites**: A sprite with ONE gradient is functional, not premium. Premium = 5+ layers (glow + gradient + highlight + shadow + detail)
22. **Single-effect feedback**: One particle burst is weak. Premium = stacked effects (particles + text + flash + shake + UI reaction)
23. **No movement deformation**: Objects moving without squash/stretch/rotation feel stiff - add deformation on velocity changes
24. **No impact particles**: Collisions and surface contacts without particles lack weight - add particles on all physical interactions
25. **No floating text**: Score changes without visible "+N" text miss dopamine feedback - show value changes visually

### FPS-Specific Pitfalls
26. **Pointer lock not recovering**: After alt-tab or focus loss, pointer lock is lost. ALWAYS re-request on focus/click events.
27. **Enemies shoot through walls**: Must check line of sight (step along ray) before allowing enemy attacks.
28. **Enemies spawn in walls**: Validate spawn positions against collision map; use fallback positions if invalid.
29. **3D hit detection for 2D gameplay**: Classic FPS uses 2D XZ-plane distance with cone-of-fire, ignoring Y axis.
30. **Weapon drawn sideways**: FPS weapons should point forward (barrel vertical), not left-to-right like a side view.
31. **No weapon feedback**: Always add recoil animation (move down/up) and muzzle flash on fire.
32. **Static enemy sprites**: Animate walk (leg movement) and shoot (arms raised) states with canvas texture updates.
33. **AI too aggressive**: Balance detection range, attack rate, and damage. First-time playability > difficulty.
34. **Score counts down during play**: Live score should ONLY increase. Time bonuses calculated at end, only if mission succeeded.
35. **Time bonus on failure**: Speed bonus should only be awarded when the player wins, not on death.
36. **Floating point stat display**: Always use `Math.floor()` for health, armor, score display to avoid "99.7" health.
37. **Modal UI not interactive**: Game over screen must have proper `pointer-events: auto` and exit pointer lock.

---

## Known Warnings (Safe to Ignore)

- **Puppeteer ARM64 warning**: On Apple Silicon Macs, you may see a "Degraded performance warning" about Chrome/Rosetta. This is expected and does not affect playtest functionality.

Quick Install

$npx ai-builder add skill tolitius/game

Details

Type
skill
Author
tolitius
Slug
tolitius/game
Created
4d ago