---
name: kid-game-builder
description: Build web games WITH a kid (not just for them) — paper drawings to deployed, agent-native, playable game. Use when a child is the design lead, when the user mentions their son/daughter/kid is helping design a game, when turning hand-drawn sprite sheets into game assets, when iterating on a kid-designed platformer, or when deploying a kid's game. Honors the kid's vision exactly. Tech stack: vanilla HTML5 Canvas + JS, no framework, deployed as a Cloudflare Worker. Every project ships agent-native by default — robots.txt with Content Signals + AI rules, sitemap, Link headers, markdown negotiation, /.well-known/api-catalog (RFC 9727), MCP server card, agent-skills discovery index that mirrors this skill, and WebMCP tools — so any agent can find the game, read the design as markdown, and call the kid's tools. Includes the paper-to-playable pipeline, two-pass sprite cleanup script, telegraphed boss design pattern, kid-tuned game feel constants.
when_to_use: User mentions building, designing, or iterating on a game with their child. Phrases like "my son/daughter and I are making", "kid drew a sprite sheet", "kid wants the boss to do X", "deploy our game", "process this drawing", "add a level", "make the site agent-native". Auto-trigger on any kid-collaborative game work.
---

# Kid Game Builder

A playbook for building web games **with** a child as the design lead. Forged on **lil-critters** — a 4-level 2D platformer designed by Isaac (age 6), with hand-drawn sprite sheets, hunting boss AI, full controller support, and a Cloudflare Worker deployment. The hard parts have been figured out; this skill is what survived.

## Bootstrap URL — paste this to any agent

**`https://lilcritters.stereovoid.com/skill`**

That single URL 302-redirects to this file, with all relative links (reference/, templates/, scripts/) resolving from the same origin. An agent that follows the redirect has the entire playbook plus every supporting file. The reference site is also the proof — every file referenced here is reachable from that domain. See `https://lilcritters.stereovoid.com/index.md` for the canonical example of an agent-native deploy produced by this skill.

## The pipeline (two paths to a sprite sheet)

```
                          Kid draws on paper
                                  │
                ┌─────────────────┴─────────────────┐
                ↓                                   ↓
   PATH A: kid draws ALL frames        PATH B: kid draws ONE base
   (8-frame walk strip on paper)       (single character pose)
                │                                   │
                │           Photo on disk           │
                │                                   ↓
                │              Upload to ChatGPT image, prompt:
                │              "8-frame [walk/attack/idle/jump]
                │              sprite sheet of this character,
                │              side view, transparent background,
                │              horizontal strip, preserve style"
                │                                   │
                └─────────────────┬─────────────────┘
                                  ↓
                       Sprite sheet (any source)
                                  ↓
                  scripts/process-sprite.py — TWO-PASS bbox
                                  ↓
                Tight-cropped, transparent sprite sheet
                                  ↓
                       drawImage with frame index
                                  ↓
                       Critter on screen, alive
                                  ↓
                  cfman personal wrangler deploy
                                  ↓
                Game on the real internet — kid shows grandma
```

**Path A** (kid draws every frame) gives 100% kid-handmade animation. Use when the kid wants total ownership.

**Path B** (kid draws ONE base, AI generates frames per state) is the scale move. Use when going from "1 critter" to "4 critters × 4 animations each" — the kid stays the artist of the *character*, AI fills in the in-between poses preserving their style.

Both paths feed the same `process-sprite.py`. Same threshold rules, same bbox cleanup. See [reference/sprite-pipeline.md](reference/sprite-pipeline.md) for the prompt templates and which path to recommend when.

Every step is something the kid can watch happen. That's the magic. Make it visible.

## Core principles (non-negotiable)

1. **Kid leads design.** Their paper spec is canonical. "Ant mound" is not "home." "Pinchers" is the ability name. Their words map 1:1 to code constants and copy. Suggest, never override.
2. **Ship tiny, then grow.** First playable: one critter, one screen, one obstacle, reaches goal. Refactor only what hurt. Don't pre-plan abstractions for levels 2-4 while building level 1.
3. **Authenticity > polish.** Hand-drawn art with paper-frame artifacts beats polished vector art. Scrappy is the brand. The kid's drawings ARE the look.
4. **Make every step visible.** Kid should see paper photo → cleaned sprite → moving character. Build a sprite-sheet demo page early so they understand the magic.
5. **Vanilla, no framework.** HTML5 Canvas + JS, deployed as a Cloudflare Worker. No build step. `cmd-r` = see the change.
6. **Two-pass sprite cleanup.** Single threshold loses ink OR keeps ghost outlines. Use threshold 150 for transparency, then a stricter dark-sum mask for bbox computation. See [scripts/process-sprite.py](scripts/process-sprite.py).
7. **Agent-native is non-negotiable.** Every deploy ships robots.txt + Content Signals, sitemap, Link headers, markdown negotiation, /.well-known/api-catalog, MCP server card, agent-skills discovery index (mirroring this skill), and WebMCP tools. The kid is publishing software the next generation of software can read. See [reference/agent-native.md](reference/agent-native.md).

## Modes — figure out which one applies

When invoked, work out which mode based on conversation:

- **Bootstrap** ("we're making a game", "starting with my kid"): scaffold from `templates/`. Set up `public/`, `scripts/`, `wrangler.jsonc`, `.gitignore`. See [reference/bootstrap.md](reference/bootstrap.md).
- **New sprite** ("kid drew the X", "process this sheet"): copy photo to `sketches/`, run `scripts/process-sprite.py <source> <output> <frames>`, update game.js with new frame dimensions. See [reference/sprite-pipeline.md](reference/sprite-pipeline.md).
- **New mechanic** ("kid wants Y to do Z"): build it minimally, no abstractions. Iterate after playtest. See [reference/iteration.md](reference/iteration.md).
- **Boss/encounter** ("anteater that hunts", "owl that swoops"): use the telegraphed-attack pattern (hunt → tell → strike). See [reference/boss-design.md](reference/boss-design.md).
- **Deploy/redeploy**: see [reference/deploy.md](reference/deploy.md).
- **Game feel issue** ("too hard to jump", "feels off"): tune feel, not difficulty. See [reference/game-feel.md](reference/game-feel.md).

Always start by reading the kid's design doc — paper photo, .pen file, or what they tell you. Their words are the spec.

## Tech stack (default)

- **HTML5 Canvas + vanilla JS** — single `index.html`, single `game.js`, single `style.css`
- **Internal canvas resolution 960×540** — 16:9, scales to any window size via JS-driven `fitCanvas()`
- **No build step** — files served directly by Cloudflare Worker
- **Cloudflare Worker (assets-only)** — `wrangler.jsonc` with `assets.directory: "./public"` + `routes` with `custom_domain: true`
- **Deploy:** `cfman personal wrangler deploy` (account_id REQUIRED in config)
- **Sprite pipeline:** Python + PIL (`/Applications/Xcode.app/Contents/Developer/usr/bin/python3` on macOS)
- **Audio:** Web Audio API beeps. No assets.
- **Input:** keyboard + Gamepad API (Xbox controller maps cleanly).

See `templates/` for ready-to-copy starters.

## Game feel constants (kid-tuned, don't touch unless asked)

```js
const GRAVITY = 0.42;          // slow fall = floaty, kid-friendly
const JUMP_V = -12;            // initial jump velocity
const JUMP_CUT = 0.5;          // tap = short hop, hold = full jump
const MOVE_SPEED = 4.0;
const COYOTE_FRAMES = 6;       // 0.1s grace after walking off ledge
const JUMP_BUFFER_FRAMES = 8;  // 0.13s grace before landing — pre-press jump
```

Plus: variable jump (release while rising → vy *= JUMP_CUT), feet-precise platform collision (one-way platforms via prev/next position check). See [reference/game-feel.md](reference/game-feel.md).

## Boss design pattern (telegraphed attacks)

The pattern that works for 6-year-olds: a clear **tell** before the **strike**. The tell IS the dodge window. Without a tell, attacks feel unfair. With one, they feel like a real boss fight.

State machine inside the boss's "active" state:

```
hunt (slow tracking)
  └─ every N seconds → tell (frozen, eye flashes red, audio rising tones, ~0.5s)
                          └─ → strike (snap to lock, ~0.7s recovery)
                                  └─ → back to hunt
```

Two-tier predator: **body/snout drifts slowly** toward player (smoothing 0.018), **strike point** tracks faster (smoothing 0.045). On the strike, both lurch hard.

Hide spots (rocks, trees) form `isHidden(p)` regions. Hidden = immune. Critical for fairness.

Caught penalty: **knockback + invuln + lose recoverable resources** (e.g., leaves pop out as physics particles, land back on the ground, kid can recollect). Never hard-game-over for a 6yo.

See [reference/boss-design.md](reference/boss-design.md) for full implementation.

## Default project layout

```
my-game/
├── public/                  # Served as-is by Cloudflare Worker
│   ├── index.html           # Game page (use templates/index.html)
│   ├── game.js              # Game loop + state (start tiny)
│   ├── style.css            # Storybook palette (use templates/style.css)
│   ├── og.png               # Social card (use scripts/generate-og.py)
│   └── assets/
│       ├── <critter>-walk.png    # Walking sprite sheet
│       └── <critter>-attack.png  # Action sprite sheet
├── sketches/                # Original photos of kid's drawings
│   └── *.png / *.jpg
├── scripts/
│   ├── process-sprite.py    # Sprite sheet two-pass cleaner
│   └── generate-og.py       # OG image generator
├── wrangler.jsonc           # CF Worker config (use templates/wrangler.jsonc)
└── .gitignore
```

## Collaboration ethic

When the kid:

- **Has a wild idea** → build it, full strength. ("Anteater tongue should slurp around and chase me!" → ship the slurping AI.)
- **Says it's hard** → tune the FEEL not the difficulty. (Coyote, jump buffer, hit windows, audio feedback, telegraphed attacks.)
- **Asks for art** → use their drawings. Always. Paper-frame artifacts and all.
- **Loses interest** → the game is done. Ship what's there. Don't push.
- **Names things** → those names are sacred. "Ant mound" not "home." "Pinchers" not "attack."

Parent's job: engineering. Kid's job: design. Claude's job: making the parent fast.

## Resources in this skill

**References** (deep dives, loaded only when needed):
- [reference/bootstrap.md](reference/bootstrap.md) — first-time project setup
- [reference/sprite-pipeline.md](reference/sprite-pipeline.md) — paper photo → in-game sprite, the two-pass fix
- [reference/game-feel.md](reference/game-feel.md) — full implementation of coyote/buffer/cut
- [reference/boss-design.md](reference/boss-design.md) — telegraphed attack state machine, hide mechanics, leaf knockback
- [reference/iteration.md](reference/iteration.md) — playtest loop, when to refactor (rarely!)
- [reference/deploy.md](reference/deploy.md) — Cloudflare Worker + custom domain
- [reference/collaboration.md](reference/collaboration.md) — kid + parent + Claude working ethic

**Templates** (copy and customize):
- [templates/index.html](templates/index.html) — game page with stage wrapper, fullscreen button, OG meta tags
- [templates/style.css](templates/style.css) — cream/brown storybook palette, fullscreen-ready
- [templates/game.js](templates/game.js) — minimal canvas + physics + controller scaffold
- [templates/wrangler.jsonc](templates/wrangler.jsonc) — CF Worker config (with the account_id gotcha)
- [templates/.gitignore](templates/.gitignore)

**Scripts** (battle-tested, drop into `scripts/`):
- [scripts/process-sprite.py](scripts/process-sprite.py) — two-pass sprite sheet cleanup
- [scripts/generate-og.py](scripts/generate-og.py) — OG image with kid's sprite as the hero
