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/gameInstalls 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/gameDetails
- Type
- skill
- Author
- tolitius
- Slug
- tolitius/game
- Created
- 4d ago