Prompts that move, an Opus 5.5 field guide

Every line you write shows up on screen.

A field guide to briefing Claude Opus 5.5 and Sonnet 5.5 (with notes for GPT-6 Astra and GPT-6.1 Sol) for animations, games, dioramas and coded video: engine choice, game design, art direction, illustration, 3D assets, asset generation (hosted models with your keys, or local ComfyUI), level design, game AI, procedural generation, physics, cameras, animation, VFX, shaders, sound, game juice, accessibility and performance. Built from Anthropic's model docs, OpenAI's model notes, and the prompts and skills people shipped in the first week after launch.

schedule111 min full read bolt42 min in skim mode verifiedFacts checked 6 Oct 2026
Your prompt
lightbulbWatch the scene gain each thing the prompt asks for.

Lines you leave out still get drawn. The model fills them with its most average guess, which is why vague prompts return scenes that feel familiar. This guide is about deciding those lines yourself.

Start here: what are you making?

Pick one and read these sections in order. Skip the rest until you need them.

The 60-second version

Skim mode is on. You are seeing the essentials only.

flag

Describe the finish line, not the route

State the outcome, the inputs, the limits, the evidence you want, and when to stop. Opus 5.5 plans its own steps better than a hand-written recipe, so spend your words on what "finished" looks like.

speed

Use the effort dial, delete "think hard"

Opus 5.5 always thinks and defaults to medium. Raise effort only after medium misses details you listed, instead of writing instructions about thinking. Sonnet 5.5 defaults to high and can skip thinking at lower levels (see Effort).

block

Ban defaults by name

"Avoid a generic look" trades one default for another. List the exact looks you refuse and extend the list after each render. Anthropic's frontend-design skill names five default clusters: cream with a terracotta accent, near-black with one acid accent, broadsheet rules and columns, identical rounded cards with the same soft shadow, and template chrome such as tracked capitals, middle-dot meta strings and a trailing arrow. For games, add a HUD of glass cards framing the view.

photo_camera

Give it eyes and ears

Name the frames to capture and what to check in each. For sound, have it render to WAV and read loudness and a spectrogram, because it cannot listen.

travel_explore

Let it study before it builds

Opus 5.5 starts work fast. On loose briefs, ask it to research the real thing first (a real map, real wave footage, the original controls). Anthropic measured better results when it explored before acting.

straighten

Numbers over adjectives

"AAA" is a mood. 60 fps at 1440p on an M-series laptop is a spec. So are resolution, palette size, loop length and frame budget.

science

Give feedback in physics

When iterating, say where it breaks, what you see, and what should physically happen. "Looks cartoony" gives the model nothing to aim at.

Most of these come from Anthropic's Opus 5.5 prompting guide and frontend-design skill. "Numbers over adjectives" and "Give feedback in physics" are patterns from the community prompts later on this page.

Anatomy of a build brief

stacksStrong creative prompts cover nine layers. Click a layer to see the lines that carry it.

The example takes the one-line Halloween diorama request ("rainy night, warm firelight, 1080p, loops for hours") and writes out every decision the short version left to chance. Write the layers in this order: what you are shipping first, how to prove it works last.

Build one self-contained HTML file with vanilla JS and Canvas 2D. No libraries, no network requests, no text anywhere on screen.

A pixel-art Halloween street corner on a cold rainy night: a crooked house with two lit windows, a pumpkin patch, an iron fence, a lamp post, and a small bonfire in the foreground.

The bonfire is the hero: a three-layer flame, embers that rise and fade, and warm light that flickers across the wet stones around it.

Loop exactly every 60 seconds with no visible seam. Poses step at 10 fps while particles update at 60 Hz. A cat walks the fence once per loop.

28-colour palette: 16 cold blues and violets for the night, 12 warm oranges for fire and windows. The warm pockets are the brightest, highest-contrast areas.

Render at 320×180 and scale ×6 to exactly 1920×1080 with image-rendering: pixelated. Rain as 1px streaks in three depth layers with splashes on the ground. Soft falloff uses Bayer dithering only.

Hold 60 fps for ten hours: fixed timestep, pooled particles, zero allocation in the loop, no memory growth.

Before finishing, capture frames at 0 s, 15 s, 30 s and 59.9 s, compare the first and last frame for the seam, and fix anything that pops, clips or floats.

Reply with the file, the four captures and two sentences on what they show.

One line, one visible change

tuneTurn each spec line on and watch what it does to the same little scene.

With every switch off you get what an unspecified prompt tends to produce: soft edges, smooth tweening and a gradient sky. Nothing is wrong with it, it just is not pixel art. Four short lines are the difference.

Playbooks by format

categoryEach format fails in its own way. Pick yours, check the must-haves, copy the starter.
recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • three.js examplesHundreds of working scenes by feature. Ask the agent to start from the closest one instead of a blank file.
  • Phaser MITMature 2D game framework: scenes, input, physics, tilemaps, audio.
  • Kaplay MITSmall, friendly 2D game library, quick for jam-sized prototypes.
  • threejs-game-skills MITNine Claude Code and Codex skills for three.js games (v0.1.0). Worth borrowing: its test hooks, bot playtest, canvas checks, per-device budgets and release checklist. Its Tripo, Gemini and ElevenLabs generators are paid cloud services that run whenever keys exist, so say "procedural only" and keep those keys out of the environment. It uses GLSL and a clamped variable timestep, so keep this guide's TSL (three.js Shading Language) and fixed-timestep rules.
  • OpenAI Game Studio plugin MITCodex skills for browser games: a low-chrome HUD rule, sprite strips from one seed frame with local normalising scripts, and 3D playtest checks (pointer lock, WebGL context loss, SpectorJS). Its image generation is hosted, so feed its scripts local images instead.

Character loops, sprite scenes, ambient cutscenes. Exact numbers matter most here: resolution, palette size, fps and state timings.

check_circleNail these

  • Logical resolution and the scaling rule
  • Palette size with a role for each colour group
  • Named states with durations, and easing between them
  • Pose parameters, animated smoothly, stepped at a stated fps
  • How the loop closes without a seam

errorWhere it breaks

  • Sub-pixel shimmer on edges
  • A visible pop at the loop point
  • Poses drifting as float errors pile up
  • Gradients or blur sneaking into pixel art
Starter prompt
Build one self-contained HTML file (vanilla JS, Canvas 2D, no libraries, no network) showing [subject] as a looping pixel-art animation.

Canvas: draw at [320×180] logical pixels, scale by the largest integer that fits, centred, image-rendering: pixelated. Snap every draw to whole pixels. No gradients or blur. Soft falloff uses 4×4 Bayer dithering.
Palette: [24] fixed colours. Roles: [sky steps], [skin and cloth], [3 bright accent colours], [2 outline darks].
Character: about [24×32 px], built from rects and pixel runs. Pose parameters: [list]. Animate them smoothly, then quantise poses to [10] fps inside a 60 Hz loop.
States: [IDLE 2 s] then [ACTION 1.5 s] then [RESOLVE 1 s], eased between keyframes, looping with no seam.
Particles: one preallocated pool of [300], zero allocation inside the loop, fixed 60 Hz timestep.
Evidence: capture a frame in every state plus the loop point, compare first and last frame, fix shimmer, clipping and pops.
Done when it holds 60 fps on [device] and each state is identifiable in its captured frame at 1×. Reply in two sentences and attach the captures.

Playable builds. The most-shared one-shot game prompts on both models spell out an objective, controls, feedback, scoring and a restart state.

check_circleNail these

  • The core loop in one sentence, and the kind of fun it targets
  • Control feel as numbers: speed, acceleration, inertia, jump height
  • Title, play, fail, win, restart without a reload
  • Camera rules: spring arm, collision, never inside walls or below ground
  • Physics on a fixed timestep, jump set by height and time to apex
  • A self-playtest with screenshots of each state
  • A grey blockout that plays well before any art
  • Enemy AI with a debug overlay: state, vision, path
  • A juice pass only after the loop is fun
  • An engine the agent can build, test and screenshot from a terminal (see Engines and libraries)

errorWhere it breaks

  • Floaty or laggy controls
  • The camera clipping through geometry
  • Many features and no loop worth repeating
  • Levels built at real-world scale, so they feel empty
  • Enemies with instant detection and perfect aim
  • No fail or restart path
  • A HUD of four to six glass cards framing the view. The first screen should be playable, with information second.
Starter prompt
Build a complete browser game in one HTML file using [three.js r186 / Canvas 2D]. Inline every library (no CDN at runtime) and generate every model, texture and sound in code. No paid or hosted generators, even if API keys exist.

Fun target: [challenge / discovery / expression / ...] (see Game design).
Core loop: the player [does X] to [achieve Y] while [avoiding Z]. Pacing: the core action repeats every [5 to 30] s, something new appears every [1 to 5] min, pressure starts in the first minute, and the first real decision comes within 30 s.
Controls: [WASD + mouse]. Feel targets: top speed [n], reaches it in [0.4 s], turn inertia [light], jump defined by height [2.2 m] and time to apex [0.4 s], coyote time and jump buffer [100 ms]. Physics on a fixed timestep with interpolated rendering. Input responds within one frame.
Touch, if mobile ships: the same actions as the keyboard, targets of at least 44 px, touch-action set on the canvas only, and input released on pointercancel, lostpointercapture and blur.
Structure: title, play, fail, win, and restart without reload. Score plus one difficulty curve that rises over [3 minutes].
Camera: third-person on a spring arm at [6 m] with a collision cast, never inside walls or below ground, no bob with the walk cycle, shake on a separate layer.
Level: grey blockout first, sized from the controller's metrics (doors at least 2× player width), a critical path with numbered beats, one loop that returns as a shortcut, one landmark visible from most of the path. Art only after the blockout plays well. Audio synthesised, [M] mutes.
Enemies: [state machine / behaviour tree] with a vision cone, hearing and last known position, navmesh or grid A* pathfinding, a visible awareness telegraph before attacking, and a debug overlay on [F1]. All randomness seeded.
Juice, once the loop works: hitstop, trauma-based shake, spring squash, layered hit sounds, all scaled by an intensity value, with a reduce-shake toggle.
Performance: 60 fps on [a named mid-range laptop], drop render scale below 50 fps.
Test hooks: expose window.__GAME_TEST__ with seed(n), setState(name), pause() and hideDebugUi(), so tests reach every state without playing to it.
Evidence: a scripted bot plays [3] seeded runs in Playwright (channel "chromium", one worker). A run passes when it renders over 100 frames, moves the player, raises the score, never goes [5] s without movement or progress, and logs zero console errors. Rerun with a 300 ms reaction delay to check the game stays winnable. Then reach a win and a fail yourself and screenshot every state.
Done when the bot runs pass, every state has a screenshot, and the 10-second screenshot shows the goal, the player and the first threat without any text. Stop after [30] turns and list what is still open.

Showreels, explainers, lyric and music videos rendered from code. The skill is timing: every accent lands on a planned beat.

check_circleNail these

  • Duration, fps, aspect ratio and the one idea to land
  • A timeline with timestamps and a beat grid
  • A style system: two typefaces, a palette, one motion signature
  • A framework that seeks every frame (HyperFrames, Remotion) or your own seek(t), then MP4
  • A contact sheet review at fixed intervals

errorWhere it breaks

  • Picture drifting off the audio
  • Stock transitions that could be anyone's
  • Type unreadable at phone size
  • Dropped frames from real-time capture
Starter prompt
Make a [15]-second, [1920×1080], [60] fps motion-graphics piece rendered frame by frame from code in [HyperFrames / Remotion / one HTML page with window.seek(t)]. Use only that framework. Deterministic time, no real-time screen capture.

Purpose: [showreel / explainer / lyric video] for [audience]. The single idea it must land: [idea].
Timeline: 0.0 to 2.0 s [hook], 2.0 to 6.0 s [build], 6.0 to 11.0 s [peak], 11.0 to 15.0 s [resolve and end frame]. Cut on a [120] BPM grid (0.5 s).
Style: [2 typefaces], [4 to 6 hex colours], one motion signature ([spring with 8% overshoot]), transition vocabulary: [mask wipes, match cuts, type morphs]. Do not use: [the looks you refuse].
Audio: [supplied track / synthesised hits]. Visual accents land within one frame of their audio events.
Export: every animation is seekable (a paused anime.js or GSAP timeline), nothing reads wall-clock time, and each frame is captured after a seek, then encoded to MP4 (H.264, yuv420p) with FFmpeg.
Evidence: a contact sheet of frames every 0.5 s, a phone-size sheet at 360 px wide, and the frame offset at [listed beats]. Fix and re-render, at most [3] rounds.
Done when the contact sheet reads as a story without sound, every listed beat lands within one frame, and no text is under [36] px tall at 1080p.

Ambient loops and video covers that run for hours. The risk is not the first minute, it is hour six.

check_circleNail these

  • Loop length and a first-frame versus last-frame seam test
  • Every periodic motion uses a period that divides the loop
  • Warm versus cold palette roles, with a count for each
  • Exact output size: 320×180 scaled ×6 is 1920×1080
  • A soak test for memory and particle counts

errorWhere it breaks

  • Memory creeping up over hours
  • Every layer repeating in sync, so the loop feels short
  • Flicker harsh enough to tire the eye
  • Non-integer scaling that blurs pixels
Starter prompt
Create a looping pixel-art diorama for a [10-hour] lofi video cover. One HTML file, Canvas 2D, no network, no UI or text on screen.

Frame: 320×180 logical, scaled ×6 to exactly 1920×1080, pixelated.
Scene: [location], [weather and time], hero light: [bonfire / lit window / lantern].
Palette: [28] colours split by role: a cold field ([16]) against warm pockets ([12]). Warm areas stay the brightest and highest-contrast.
Ambient layers: [rain in 3 depths], [sparks], [drifting smoke], [flickering light].
Loop: exactly [60] s. Every periodic motion uses a period that divides 60 s ([4, 5, 6, 12, 20 s]) so layers do not visibly sync, yet the loop closes cleanly.
Stability: fixed timestep, pooled particles, zero allocation per frame, flat memory over an hour of fast-forwarded time.
Evidence: compare frame 0 with the final frame, run the fast-forward soak test, capture four frames across the loop, soften any flicker that strobes.
Done when frame 0 and the last frame differ in under [1]% of pixels and memory stays flat through the soak test. Reply briefly and attach the four frames.

Interactive worlds and simulations such as the ocean and the sakura river. Many systems, one frame budget. Priorities decide what survives.

check_circleNail these

  • Renderer and shading language (WebGPU with TSL, or WebGL2)
  • Landmarks and how they relate in space
  • Hero systems in priority order, each defined by what you would see
  • An asset policy: procedural, or embedded open-licence assets
  • A screenshot matrix: views × times of day

errorWhere it breaks

  • Floating or intersecting objects
  • A camera that dips into terrain
  • Shader compile stalls on load
  • Frame rate eaten by feature creep
Starter prompt
Build an interactive 3D [scene] in one HTML file with three.js r186 ([WebGPU renderer and TSL / WebGLRenderer and GLSL]). Inline the library, no CDN and no other runtime network requests.
Assets: [procedural / CC0 from Poly Haven, ambientCG and Kenney, embedded], each logged in ASSET_MANIFEST.json with source and licence.

World: [landmarks, and where each sits relative to the others], with a critical path and sightlines to one main landmark. Everything rests on ground or water. Nothing floats or intersects.
Hero systems, in priority order: 1 [water], 2 [time-of-day lighting], 3 [wind in foliage]. Vegetation and props scattered by seeded Poisson disk sampling, never uniform random. Define each by what I would see, for example "white foam collars on rocks, trailing downstream".
Look: match [the style frame in art-bible.md], checked in greyscale and silhouette at gameplay distance.
Time of day: [dawn, noon, storm, golden hour, night], each with key light, fog and grade.
Camera: [chase / orbit], never below terrain or inside geometry, [drag to orbit, scroll to zoom].
Budget: 60 fps at 1440p on [an M-series laptop], dynamic resolution, a quality tier that drops the costliest effect first.
Evidence: a screenshot matrix of [3 views] × [each time of day]. Read the console, fix artefacts, clipping and floating objects.
Done when every screenshot passes every art-bible check and the console is clean. Reply in two sentences and attach the matrix.

Games, 3D scenes and videos lean on crafts the starters only touch. The sections that follow go deeper on each, grouped as design and look, play and motion, polish, and shipping.

Engines and libraries

constructionPick by where it ships, then by what the agent can build, run, test and screenshot from a terminal. Text files and a headless command line give the agent a fast loop. Binary assets and editor-only steps leave it guessing.

Pick by the job

You are makingStart withWhy
A link people open instantly, a coded video, a one-file demothree.js (R3F if the team lives in React)Largest example library, TSL and WebGPU, Gaussian splats in r186, everything is text
Web 3D that needs physics, GUI and an inspector out of the boxBabylon.jsHavok physics, GUI, inspector and node editors are built in, so there is less to assemble
Web 3D that artists edit visually, or splat-heavy scenesPlayCanvasVisual editor, compact SOG splats with streaming LOD. The editor is hosted, so projects live in their cloud.
A 2D web gamePhaser 4, or PixiJS if you only need a rendererPhaser brings scenes, physics, tilemaps and audio. PixiJS is fast 2D drawing and nothing more.
A jam-sized 2D gameKAPLAYTiny API, quick to prototype. Stable line quiet since Jun 2025.
A native desktop or mobile game, built mostly by an agentGodot 4.7Text scenes, a real headless CLI and deterministic frame capture. MIT, no fees.
A C# team, mobile or console, heavy 3D, asset-store contentUnity 6Mature platform reach. The new Unity CLI makes batch builds, tests and editor commands scriptable.
High-end visuals, archviz showcases, consolesUnreal 5.8Best rendering out of the box. The agent works through C++, Python and the editor MCP, since assets and Blueprints are binary.
A code-only, ECS game in RustBevy 0.19Everything is code, and it targets WebGPU. The API still changes each release, so pin the version.

Web or engine? A web library wins when the result must load from a link with no install, sit inside a site, or become a coded video. An engine wins for large content, native performance, console targets or an existing C# or C++ team. Godot 4 web export uses the WebGL 2 Compatibility renderer, needs cross-origin isolation headers for threads, and cannot export C# projects. Unreal has no official web export, only Pixel Streaming from a server.

How the agent drives each one

three.js

r186 (Sep 2026). MIT
Loop
Vite dev server, Playwright screenshots, npm tests
Agent tools
No official MCP. threejs.org/docs/llms.txt. Community skills.
Watch
Old APIs from training data: Geometry, examples/jsm paths. For WebGPU import three/webgpu and three/tsl, for WebGL2 import three. Both use three/addons. r183 renamed PostProcessing to RenderPipeline.

R3F and drei

fiber 9.8, drei 10.7. MIT. React 19.
Loop
Same as three.js
Agent tools
llms.txt and a pmndrs docs MCP
Watch
v8 examples break on v9: ThreeElements types, async gl factory for WebGPU, no automatic sRGB on textures

Babylon.js

9.x. Apache 2.0
Loop
Vite and Playwright. The Playground for quick API checks.
Agent tools
Official MCP servers for the node editors (npx -y @babylonjs/mcp-servers nme), llms.txt
Watch
Use Physics V2 (Havok), not the legacy V1 plugins. WebGPU needs await engine.initAsync().

PlayCanvas

2.22. MIT engine, hosted editor
Loop
Engine-only projects use the web loop
Agent tools
Official editor MCP server and a Claude Code skills plugin (playcanvas/skills), llms.txt
Watch
The editor loads from playcanvas.com. WebGPU is opt-in.

Phaser

4.2 (4.0 shipped Apr 2026). MIT
Loop
Web loop
Agent tools
28 skills in the repo, including v3-to-v4 migration. Phaser's Game Agent MCP is hosted and paid.
Watch
Phaser 3 code from training data: pipelines are now RenderNodes, FX and masks are Filters. No WebGPU renderer.

PixiJS

8.21. MIT
Loop
Web loop
Agent tools
26 skills ship inside the npm package, llms.txt
Watch
WebGPU only when you pass preference: 'webgpu'. It is a renderer, not an engine.

Godot

4.7 (Jun 2026). MIT, free
Loop
godot --headless --path . --import, --export-release "Web" build/index.html, -s script.gd --check-only to parse, GUT or gdUnit4 tests from the CLI, Movie Maker for frames
Agent tools
No official MCP. Coding-Solo/godot-mcp (MIT) runs the project, reads debug output and edits scenes, but has no screenshot tool.
Watch
Godot 3 syntax: yield, onready, KinematicBody. In Godot 4 these are await, @onready, CharacterBody3D.

Unity

6.6, or 6.3 LTS. Personal free up to $200k revenue and funding, Pro $2,310 per seat per year, Enterprise required above $25M.
Loop
Unity -batchmode -nographics -projectPath . -executeMethod Build.Run -logFile - -quit, -runTests -testPlatform PlayMode -testResults results.xml, or the Unity CLI: unity build, unity test, unity eval, unity vcs diff, --format json
Agent tools
unity mcp in the Unity CLI replaces the AI Assistant MCP. Community CoplayDev/unity-mcp (MIT) adds screenshots and test runs.
Watch
Never hand-edit scene YAML or .meta files. Old Input Manager versus Input System. Built-in pipeline deprecated from 6.5, so use URP. WebGPU left experimental in 6.6 but needs HTTPS.

Unreal

5.8 (Jun 2026). Games: 5% royalty on lifetime gross above $1M per product. Non-game use at companies above $1M: $1,850 per seat per year.
Loop
UnrealEditor-Cmd Proj.uproject -run=pythonscript -script=build.py, -ExecCmds="Automation RunTest Project.Smoke;Quit" -ReportExportPath=out, RunUAT BuildCookRun, HighResShot 3840x2160
Agent tools
Unreal MCP plugin (experimental, 127.0.0.1:8000/mcp, no auth) and Epic's MIT Claude Code plugin with 30+ toolsets
Watch
.uasset and Blueprints are binary. Write C++ and editor Python, and use MCP for scene edits. The Python commandlet does not load levels on its own.

Bevy

0.19 (Jun 2026). MIT or Apache 2.0
Loop
cargo run, cargo test, scenes in code with bsn!
Agent tools
None official
Watch
Breaking changes every release. Pin the version and read the migration guide.

For real-estate or interior visualisation in Unreal, the seat licence applies, not the game royalty. Defold (free, Lua, a bob.jar CLI with a headless build, and an llms.txt) is a lighter 2D and 3D alternative. Godot, Unity and Bevy have no llms.txt, so have the agent read the docs for your exact version. Confidence: high for versions, licences and commands, which come from official docs, release notes and package registries. Moderate for the "start with" picks, which are practitioner judgement.

What makes an engine agent-friendly

Text over binaryGodot .tscn and web code diff cleanly and can be edited directly. Unity scenes must go through the editor. Unreal assets need the editor, Python or MCP.
Headless build and testEvery step the agent needs (import, build, test, export) runs from one command with an exit code and a log it can read.
Deterministic captureFrames rendered at a fixed step, not recorded live: seek(t) on the web, Godot's Movie Maker (--write-movie out.png --fixed-fps 30 --quit-after 300, without --headless), a fixed timestep with HighResShot in Unreal.
An editor bridge, used sparinglyMCP servers run code inside the editor. Unreal's listens on localhost with no authentication, and Blender's Lab server runs model-written Python unguarded. Keep them on a dev machine and off shared networks.
Pinned version, migration guide at handModels have seen far more old code than new. Name the version in the brief and point the agent at the migration guide (Godot 3 to 4, Phaser 3 to 4, R3F 8 to 9, three.js releases).
Prove the rendererA web build can fall back to WebGL silently. Assert which backend ran, for example renderer.backend.isWebGPUBackend in three.js, so a fallback screenshot does not pass as a WebGPU test.

Headless Chromium on a machine with no GPU: WebGPU needs a secure context (localhost counts) and --enable-unsafe-webgpu, which gives a SwiftShader adapter. Since Chrome 139, WebGL no longer falls back to SwiftShader silently, so add --use-angle=swiftshader --enable-unsafe-swiftshader. On a Linux GPU, Chrome documents --headless=new --use-angle=vulkan --enable-features=Vulkan --disable-vulkan-surface --enable-unsafe-webgpu. Keep Playwright's Chromium current, since an old browser build can reject newer three.js WebGPU calls.

Starter prompt
Build [game] as a Godot 4.7 project in GDScript. Godot 4 syntax only: @onready, await, CharacterBody2D/3D. Never Godot 3 APIs. If unsure, read the Godot 4.7 docs for that class first.

Scenes and resources stay as text (.tscn, .tres). Keep every tunable number in one resource with an in-game debug panel.
Loop after every change: godot --headless --path . --import, then parse each changed script with -s [script] --check-only, then run the GUT tests from the command line (-gexit and a JUnit XML report). Fix failures before continuing.
Evidence: render [300] frames with Movie Maker (--write-movie captures/frame.png --fixed-fps 30 --quit-after 300. It needs a display, so on a server run it under xvfb-run), build a contact sheet, and check it against the brief.
Export with --export-release "[preset]" and confirm the build starts and reaches the title screen.
If godot-mcp is connected, use it to run the project and read debug output, not to replace the tests.
Done when the tests pass, the contact sheet matches the brief and the export runs.
Starter prompt
Build [game] in Unity [6.3 LTS] with URP and the Input System package. No Built-in render pipeline, no UnityEngine.Input calls.

Never hand-edit .unity, .prefab or .meta files. Change scenes and prefabs through the editor: the Unity CLI (unity command, unity eval) or its MCP server (unity mcp).
Put gameplay in plain C# classes that EditMode tests can reach, and keep MonoBehaviours thin.
Loop after every change: unity test (or -batchmode -runTests -testPlatform EditMode, then PlayMode, with -testResults), read the log, fix, repeat.
Evidence: a PlayMode test that loads each scene, plays [10] s of scripted input, and saves screenshots at named moments. Build a contact sheet from them.
Build with a static BuildScript method through -executeMethod or unity build, for [targets].
Done when all tests pass, the screenshots match the brief, and the build launches.
Starter prompt
Build [experience] in Unreal Engine 5.8. Gameplay in C++, editor setup in Python scripts saved in the repo, so every step can be rerun. Do not create logic in Blueprints you cannot diff. Thin Blueprint subclasses for designer-facing values only.

Scene edits go through the Unreal MCP plugin on localhost, or through editor Python. The plugin has no authentication, so keep it bound to localhost and off shared networks. Log every MCP action in build-log.md.
Loop after every change: compile, run automation tests with -ExecCmds="Automation RunTest [Project].Smoke;Quit" and -ReportExportPath, read the JSON report, fix.
Evidence: a Python or console script that moves the camera to [named shots] and runs HighResShot at [3840x2160]. Build a contact sheet and compare it with the style frame.
Package with RunUAT BuildCookRun for [Win64] and launch the build once.
Licence note: this is [a game / non-game visualisation]. Record which Unreal licence applies in README.
Done when the tests pass, the shots match the style frame and the packaged build launches.
recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • godot-mcp MITRun a Godot project, read its debug output, create and edit scenes from an agent.
  • Unity CLIBatch builds, tests, editor commands, scene diffs and an MCP server for Unity 6.
  • unity-mcp (Coplay) MITCommunity Unity MCP with screenshots, console reads and test runs.
  • Unreal Engine skills for Claude Code MITEpic's plugin that drives the Unreal editor through its MCP toolsets.
  • PlayCanvas skillsOfficial Claude Code skills for the PlayCanvas engine.

Game design

extensionDesign decisions for the player to make, then build only the features those decisions need. Name the kind of fun you are after, prototype the smallest loop that produces it, and let playtests decide which rules stay.

Mechanics make dynamics, dynamics make the feeling

The MDA framework (Hunicke, LeBlanc and Zubek) splits a game into mechanics (the rules you write), dynamics (what happens when players meet those rules) and aesthetics (what the player feels). You can only change the mechanics. The player experiences it from the other end. Pick the feeling first, then work backwards.

Prompt line

The eight kinds of fun come from the MDA paper, developed for the GDC Game Design and Tuning Workshop (2001 to 2004): sensation, fantasy, narrative, challenge, fellowship, discovery, expression and submission. The example games are illustrations, not claims about their designers' intent.

Ideas that hold up

Core loopThe action the player repeats most, stated in one sentence with verbs: "dash through a room, grab loot, spend it between runs".
Interesting decisionsSid Meier's test for a mechanic: does it ask the player to choose between options that are both attractive? If one option always wins, it is a chore.
Fun as learningRaph Koster's argument: play is the brain enjoying learning a pattern. When the pattern is mastered or unreadable, boredom sets in. Keep adding readable twists.
FeelSteve Swink defines feel as real-time control of objects in a simulated space, emphasised by polish. It lives in numbers and feedback, which is why the juice and physics sections exist.
Risk and rewardBigger rewards sit behind bigger risks the player can see and choose.
Difficulty as a curveTeach, test, then twist. Ramp challenge in waves with rests, as in the level design pacing curve.
Depth from few rulesFewer mechanics that interact beat many that don't. Tynan Sylvester (RimWorld) builds emotional experiences from elegant mechanics, fiction and pacing working together.
Readable failureWhen players lose, they should know why and want to try again at once.

The process

  1. Experience goalOne sentence on what the player should feel, plus the MDA fun target
  2. Core loopVerbs, a goal, an obstacle and a reward, all in one sentence
  3. Find the funA grey prototype of the loop only. No menus, no story, no art.
  4. Playtest silentlyWatch strangers play without explaining. Note where they hesitate, smile or quit.
  5. Tune in a configEvery number in one file with a live panel, changed one at a time
  6. Grow systems around the loopProgression, economy and content only once the loop is fun on its own
  7. Vertical sliceOne level at final quality: art, audio, juice, UI and performance
  8. Content and polishScale up what the slice proved

Where agents help and where they don't

check_circleUse the agent for

  • Three small variants of the same loop in an afternoon, so you compare instead of guessing
  • A tuning panel and a config file for every number
  • Bots that search for dominant strategies, exploits and dead economies
  • Telemetry: deaths, quits and time spent per area, drawn as heatmaps
  • A structured critique of the build through named design lenses

errorKeep for humans

  • Deciding what is fun. The model has never been bored by your game.
  • Watching a first-time player
  • Cutting a feature you like that the playtest says to cut
  • Choosing the fun target in the first place

The shelf

SourceUse it for
The Art of Game Design: A Book of Lenses (Jesse Schell)Over 100 lenses, each a set of questions. They make good critique prompts for an agent.
Game Feel (Steve Swink)The only book-length treatment of feel: control, response, polish, metaphor
Designing Games (Tynan Sylvester)An engineering view of experience, pacing, and keeping a project on track
A Theory of Fun for Game Design (Raph Koster)Why fun fades, and why games are about learning patterns
Rules of Play (Katie Salen and Eric Zimmerman)Rigorous vocabulary: rules, play and culture
MDA paper (free)The mechanics, dynamics and aesthetics split and the eight kinds of fun
Game Programming Patterns (Robert Nystrom, free online)Architecture that keeps design changes cheap: state, commands, components
itch.io game jamsHundreds of small, playable takes on one theme. Play five before prototyping and note which rule made each one work. Study mechanics and feel, never copy art or code.
Game Maker's Toolkit (Mark Brown)Video breakdowns of specific design decisions in shipped games

Balance checks an agent can run

Resistance × verb matrixList every obstacle against every player verb. A row nothing answers means frustration. One verb that answers everything means boredom.
Parameter cross-checkTest every required gap against jump length, and every time limit against route time at player speed, before building content.
One new pattern at a timeIntroduce it safely, charge a mild price, combine it with known patterns, then test it under pressure. Every tutorial text box is a scene that failed to teach.
Hold the thresholdNever relax a target number in the same iteration that failed it.

From Higgsfield's game design system reference, which also asks the agent to say plainly at delivery that feel and delight still need a human to play the game.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • Claude Code Game StudiosA community skill pack with game-design and art-bible workflows for Claude Code. Read it before trusting it, then borrow the structure.
Starter prompt
Before building [game idea], write design.md (one page), then build three small prototypes of the core loop only.

design.md: the experience goal in one sentence. The fun target from MDA ([challenge / discovery / expression / ...]) and one secondary. The core loop as verbs, goal, obstacle, reward. Three interesting decisions the player makes every minute. What failure looks like and why the player retries. What is out of scope.
Prototypes: three variants that differ in one rule each ([e.g. resource decays / resource is capped / resource is shared]), grey boxes only, every number in config.json with a live tuning panel, restart in under 1 s.
Bots: a random bot and a greedy bot play each variant 200 times. Report win rates, the most-used action, and any strategy that wins more than [70]% of the time.
Stop there. I will playtest and choose a variant before any art, story or menus.
Starter prompt
Critique the current build of [game] as a design reviewer, not a coder. Play it through [the test level] with the bot and read design.md first.

Use these lenses from Jesse Schell's The Art of Game Design, and answer each lens's questions with evidence from the build: Essential Experience, Surprise, Fun, Curiosity, Problem Solving, Challenge, Meaningful Choices, Reward, Punishment, Skill vs Chance.
For each lens: one line on what works, one on what fails, and the smallest mechanic change that would fix it.
Then rank the five changes with the biggest expected effect on the fun target in design.md. Do not implement anything yet.

Art direction, reference first

paletteDecide the look before any code: a reference board, one or two style frames, and a short art bible the agent can check its renders against. Readability comes from value and silhouette, not hue.

Switch to Values on the hue-only scene: the player, the enemy and the pickup melt into the ground. The planned scene keeps its hierarchy in greyscale, as a silhouette and when squinted. That is what "readable" means.

The process

  1. Pillars and moodThree words it is, three it is not. "Cosy, handmade, dusk. Not neon, not gritty, not glossy."
  2. Reference boardSorted by job: mood, colour, composition, characters, environment, UI
  3. Style framesOne to three images of the actual game view, painted or generated, that the build must match
  4. Art biblePalette with roles, value structure, shape language, lighting, materials, UI, technical limits
  5. Golden sceneBuild one small scene to match the style frame side by side before anything else
  6. Lock with checksGreyscale, silhouette and squint tests at gameplay distance on every milestone
Value structureDecide which things are lightest and darkest before choosing hues. Gameplay objects get the most contrast against their background.
Silhouette testEvery enemy, pickup and interactive object must read as a solid black shape at gameplay distance. If two read the same, redesign one.
Palette with rolesFive to seven colours, each with a meaning (safe, danger, reward, interactive). Hex codes alone do not guide decisions.
Shape languageRound, angular or boxy, chosen for what it communicates, applied to characters, environment and UI alike.
Detail where the eye goesHero objects and the play area get detail. Backgrounds stay quieter so gameplay reads.
Colour is never aloneAnything that matters also has a shape, icon or sound, so colour-blind players are covered by design, not by a mode.

The silhouette rule and role-based palettes come from game art-direction skill packs used with Claude Code (AlterLab GameForge, Claude Code Game Studios), which also ask for colour-blind backups on every semantic colour. The reference-image step is the trick GPT-6 Astra testers credited for their best 3D results: generate the reference first, then match it in code. It works just as well with Opus 5.5.

Worked example: "Lantern Hollow"

A small art bible for a cosy night-exploration game, and a style frame drawn from it in SVG. Every choice in the frame traces back to a line on the left.

PillarsCosy, lonely, handmade. Not neon, not gritty, not glossy.
Palette with roles
#141a33 night field, darkest #2a3160 far layers #5a4f78 horizon haze #ffc46b warmth and safety #e9dcc4 the player, lightest shape #e05a5a danger, used tiny
Value planNear trees darkest, far layers mid-dark, warm lights brightest, the player the lightest cool-neutral shape in the frame.
Shape languageTall pointed pines read as threat. Round lanterns, doors and the cottage read as safety.
LightingCool moon key from upper right, warm point lights, no pure black or pure white.
RefuseSaturated purple glow, outlines, lens flares, perfect symmetry.

Try the value check: the player and the warm lights still lead the eye in greyscale, and the red eyes in the left pines only show up once you look for them. That is the value plan working.

Lock the style for generated assets

Style formulaOne 60 to 90 word paragraph in five blocks: rendering style, shape and line language, palette by role (the hero contrasts, hazards and pickups share one signal hue), light and mood, readability plus perspective. Paste it byte-identical into every asset prompt. Asset content, keying and sizes stay out of it.
Key colour for alphaMost image models cannot output transparency (GPT Image 2.5 and local Qwen-Image 2.1 can, and 2.1 is non-commercial). Pick the key away from the subject's hue: green for pink, purple and red subjects, magenta for green and teal ones, never cyan or blue. Check that small features (eyes, gems) survive keying, and check enclosed holes.
Scale contact sheetGive every asset a scale in hero units. Before approval, lay them all out at scale on the ground tile and look at them together.
Light from the formulaDerive the engine's light, fog and ambient from the light and mood block. New textures under old lighting look pasted on.
Anti-convergence ledgerRecord six identity axes of the last build: palette family, type pairing, hero composition, signature technique, UI shapes, corner language. The next build must differ on at least four.
Reference board rules10 to 25 images, each tagged with a role, a reason and one thing to take. Keep 2 or 3 anti-references per 4 to 8 positives, then reduce to 3 to 6 tagged references before generating.
Choosing a directionOffer 3 or 4 mutually exclusive options on one named axis, each with when it wins and when it fails. Ask for the pick first, then for a graft such as "C's light on A's composition".
Generating alternativesList 5 to 10 candidate directions with rough likelihoods, drop the most obvious ones, and build from the rest. The literal answer stays as a control.

The style formula, key-colour rule and anti-convergence ledger come from Higgsfield's game-stylization and review-rubric references. The board and choosing rules come from Scenario's inspiration skill. All of them work on either generation route.

Starter prompt
Before writing any game code, set the art direction for [game] and save it as art-bible.md.

Pillars: it is [three words]. It is not [three words].
Reference board: I attached [images]. Sort them by job (mood, colour, composition, characters, environment, UI) and write one line on what to take from each.
Palette: 5 to 7 colours, each with a role (safe, danger, reward, interactive, background). Plan the value structure first: gameplay objects get the strongest contrast.
Shape language, lighting (key direction, warm or cool, contrast), materials, UI style, and technical limits ([texture size, triangle budget, post effects allowed]).
Style frame: describe [one / two] key shots of the real game view precisely enough to paint or generate. [If I provide images, treat them as the target.]
Golden scene: build one small scene that matches the style frame. Render it next to the frame, plus greyscale, silhouette and blurred versions. List every mismatch and fix it, for up to [3] rounds, before building anything else. Report any mismatch still open.
From now on, every milestone repeats the greyscale and silhouette checks at gameplay distance.

Illustration, SVG and generative art

brushA model draws by writing coordinates it cannot see. Give it a composition, a palette with roles and a style vocabulary, let it look at the render, and change one thing per round.
"Draw a lighthouse at sunset." Centred, outlined, default gradient, everything the same weight.
Same subject, directed: focal point on a third, six-colour palette, far layers lighter, one warm accent, grain.

What separates tasteful from generic

Composition firstPlace the focal point on a third, overlap shapes for depth, contrast big and small. Centred and symmetric reads as clip art.
Palette with rolesFive to seven colours, chosen by hue, saturation and brightness. Tyler Hobbs recommends thinking in HSB rather than RGB.
Depth by atmosphereFar layers lighter, bluer and lower in contrast. Near layers darkest and sharpest.
Value before colourBlock the image in greys first. If it reads in greyscale, colour can only help.
One light, one accentA single light direction and one warm or saturated accent where the eye should land
Shape qualityCurved paths and varied widths instead of stacked primitives. No uniform black outlines.
Texture, lightlyfeTurbulence grain at 5 to 10% opacity, or a small displacement for a hand-drawn wobble
RestraintNegative space, detail only at the focal point, fewer elements than you think

The process

  1. BriefSubject, mood, composition, palette with roles, and style described by technique (flat shapes, soft grain, limited palette), never "in the style of" a living artist
  2. ThumbnailsThree compositions as simple grey shapes. Pick one.
  3. ValuesBlock the chosen one in greys. Check the focal point leads.
  4. ColourApply the palette by role
  5. DetailOnly at the focal area, then texture and light
  6. Look at itRender to PNG (Playwright or resvg), view it next to the brief, list mismatches
  7. One change per roundSmall edits keep the rest of the drawing intact

Pick the medium

MediumBest forWatch out
Hand-written SVGIcons, flat illustration, diagrams, logos-in-progress, UI art, animated stickersAnatomy and complex overlaps. Painterly looks are out of reach.
Canvas or p5.js with codeGenerative art, textures, thousands of marks, flow fieldsNeeds seeding and a batch review like any generator
Image model, then match or tracePainterly, photographic or detailed concept artLicence and consistency. Use it as a reference, then rebuild in code.

Model notes. SVG quality rises with effort only up to a point. In Simon Willison's pelican test GPT-6 Astra drew the legs correctly only at max, while Opus 5.5 and Sonnet 5.5 at max ran out of output before drawing anything. Start at high, cap at xhigh, and give the model a render to look at. For generative work, Tyler Hobbs describes palettes as probability distributions and warns that giving each element a random colour gives terrible results.

check_circleFile hygiene

  • viewBox set, no fixed width or height, no external references
  • Layers as named groups: sky, far, mid, near, fx
  • Colours only from the palette (a script can check this)
  • Text converted to paths or with an embedded font
  • Run through svgo, and check the file size

errorTells of a default drawing

  • Purple-to-pink gradient backgrounds
  • Thick uniform black outlines on everything
  • The subject dead centre and perfectly symmetric
  • Emoji-like faces, sparkles and glow on everything
recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • Impeccable Apache 2.0Design skill for coding agents, built on Anthropic's frontend-design. Its detector flags AI tells such as purple gradients and dark glows.
  • Anthropic skillsOfficial skills, including frontend-design, which pushes an explicit aesthetic direction before code.
  • SVGO MITOptimises SVG files. Run it after the art is final, not before.
  • canvas-sketchFramework for generative artwork: seeds, sizes in print units, frame export.
  • draw-better-svg MITSVG skill that draws in passes (composition, structure, geometry, style), renders each at target sizes on light, dark and transparent backgrounds, and runs a local review page where your pins become element names and coordinates for the agent. No hosted calls.
Starter prompt
Draw [subject] as a hand-written SVG, viewBox 0 0 [1200 800], no external references.

Mood: [quiet dusk, a little lonely]. Composition: focal point [the lamp] on the upper-right third, horizon on the lower third, overlapping layers far to near.
Palette, six colours with roles: [#1f2a44 darkest near shapes, #454a6c far sky, #7a5c73 haze, #e8a87c horizon warmth, #f4e3c3 the single brightest accent, #a9554f small detail]. Use nothing else.
Style by technique: flat shapes with curved paths, no outlines, far layers lighter and bluer, one light direction from [left], feTurbulence grain at 8% opacity.
Refuse: purple-pink gradients, black outlines, centred symmetric subject, glow on everything.
Process: first three composition thumbnails as grey shapes, pick the strongest and say why. Then values in greys, then colour, then detail at the focal point only.
After each stage, render to PNG, look at it next to this brief, and list what does not match before continuing, at most [2] fix rounds per stage.
Done when the render passes every line of this brief at full size and at [320] px wide.
Starter prompt
Design a set of [12] icons for [product / game UI]: [list].

Write icon-style.md first: 24 × 24 grid with 2 px padding, stroke [1.75] px, round caps and joins, corner radius [2], optical sizes checked at 16, 24 and 48 px, one fill accent colour [#ffc46b] used only for state.
Draw all icons in one pass so they share a style, each as its own SVG with viewBox 0 0 24 24 and currentColor for strokes.
Render a contact sheet at 16, 24 and 48 px on light and dark backgrounds. Check that every icon has a distinct silhouette, similar visual weight and the same stroke width. Fix outliers and re-render, at most [2] rounds. Done when every icon shares the stroke width and every silhouette is distinct at 16 px.
Starter prompt
Make a generative artwork in p5.js as one HTML file: [flow-field strokes over a paper texture].

Seeded: the seed is in the URL, and the same seed gives the same image.
Colour: a palette of [5] colours in HSB, chosen as a probability distribution ([55]% dominant, [25]%, [12]%, [6]%, [2]% accent), with small seeded jitter in brightness. Never a uniformly random colour per element.
Composition: an area of calm negative space, density varying across the canvas, no element touching the edge by accident.
Output [3000 × 3000] PNG with a key press.
Evidence: render 24 seeds as a contact sheet. Judge variety and the worst output, not the best. Tune the rules for up to [3] rounds, until the worst of the 24 still meets the composition rules above.

3D assets: build, measure, source

deployed_codePick the route first. Then make every pass prove itself against the reference with numbers, not a glance.

Asset work is where one-shot prompts fail hardest, because detail gets stacked on wrong proportions and the eye forgives drift. The two strongest community pipelines, img2threejs and Majid Manzarpour's blender-game-skills, fix this the same way: a written brief, staged passes, and a gate at every pass.

Which route fits?

Does it need to match a specific reference closely?
Must it ship inside one file, with no downloads?
Is it a generic thing (tree, rock, crate, texture, HDRI)?
codeBuild it in code

A function that returns a Three.js group from primitives, generated geometry and procedural shaders. Diffable, tiny, fits in one file. img2threejs is the reference pipeline.

view_in_arBuild it in Blender

Re-runnable bpy scripts, measured gates, GLB or FBX out with LODs, UVs, bakes and a rig. blender-game-skills is the reference pipeline.

travel_exploreSource it (CC0 first)

Poly Haven, ambientCG, Kenney and Quaternius cover most generic needs. The agent searches, checks the licence, normalises and logs every file.

auto_awesomeGenerate, then clean up

An image-to-3D model gives a fast starting mesh: Tripo P2 or Meshy with a key, Pixal3D or TRELLIS.2 in local ComfyUI without one. Blender then retopologises, fixes scale, rebuilds materials and passes the same gates.

The gate ladder

From blender-game-skills: each phase ends with renders from a camera matched to the reference, plus a compare sheet with numbers. Mismatches get written as measurements ("head 12% too tall") and fixed in the build script, never by eye.

  1. BriefViews, scale evidence, 8 to 15 proportions to check, what is inferred
  2. CalibrateReferences as planes at real scale, a ruler, the game camera
  3. BlockoutSilhouette IoU ≥ 0.85, proportions within 5%
  4. FormsIoU ≥ 0.90, proportions within 2%
  5. TopologyInside the triangle budget, LOD1 and LOD2
  6. UVs and bakeMaterial turntable under a moving light
  7. RigExtreme-pose sheet, no stray weights
  8. Export round tripRe-import into an empty scene, height within 1%

check_circleHabits worth stealing

  • List identity-defining details (bevels, seams, fasteners, painted lines, gloss zones) before any code
  • Every constant cites the view it was measured from, or says "inferred"
  • One side-by-side sheet per review, not a scatter of screenshots
  • Named pivots and sockets so the asset can move
  • Scripts do the bookkeeping, the model only judges images

errorWhere it breaks

  • Measuring proportions off perspective concept art
  • Detail added before the silhouette passes
  • Inventing the unseen back instead of flagging it
  • Trusting the viewport instead of what the engine imports

Generated inputs: preflight, orbit views, tileable textures

One figure per imageA four-view character sheet comes back from image-to-3D as four fused figures. Crop to a single subject first.
Clean input imageFull body, plain white, no cast shadow or text, limbs clear of the torso, A-pose or T-pose if it will be rigged. Use multi-view input only when the pose is identical in every panel.
Triangle budgetsHero 15 to 30k, NPC 5 to 15k, prop 1 to 5k, filler 300 to 1,500. Retopologise to these in Blender.
Check before the expensive stepApprove the input image, then four cardinal thumbnails of the mesh, before texturing. Fix style drift by retexturing, not by regenerating the mesh.
Orbit viewsRender a grey clay model from a ring of 16 cameras at 22.5°, then repaint each render with exactly two references: the layout and the source. Independent per-angle generations drifted 7 to 53% in scale in Scenario's tests.
Tileable texturesRoll the tile 50%, inpaint the seam cross with "replace damaged elements with new complete ones", and composite only the cross. Match the histogram to the reference. Check a 2×2 proof sheet at 1:1. For a scrolling background, sprite-gen's background-tile finds a minimum-cost seam in an overlap strip instead.
Seam metricCompare the difference across the wrap edge with the difference between neighbouring interior columns. Near 1.0 is good, above 1.3 needs work. For a skybox, the left and right edge columns should be near-identical.
Material familiesGroup a model's materials by physical family (41 became 14 in one test), use one seed per family, set metres per repeat (0.3 for hand-sized detail, 1 to 2 for walls), and check the geometry hash is unchanged afterwards.

From Higgsfield's image-to-3D input rules and texture pipeline and Scenario's orbit-views and retexture skills. Generating assets lists the hosted and local picks for the image-to-3D step.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • glTF Transform MITOne command to inspect and optimise GLB files: Draco or Meshopt geometry, WebP or KTX2 textures.
  • blender-mcp MITLets the agent drive a live Blender session through MCP. Now published as mcp-for-blender (2.1.8, 5 Oct), with on-demand guides for animation, bpy, level design, materials, retopology, rigging and scenes. Set BLENDER_MCP_SAFE_MODE=1 to check every script before it runs, which matters when downloaded asset text reaches the agent.
  • Blender Lab MCPBlender's own MCP server, for Blender 5.1 and later. It runs model-written Python with no guards, so Blender recommends a VM or a machine without sensitive data.
  • blender-node-skills MITTeaches agents Geometry Nodes for Blender 4.5 to 5.2: node and socket names are looked up in the running Blender instead of guessed, and each graph is read back and checked before it counts as done.
  • Kenney assets CC0Large CC0 library of 2D and 3D game assets, including prototype kits.
Starter prompt
Rebuild the object in the attached reference as a procedural Three.js model: one function that returns a THREE.Group, no mesh or texture files.

Before any code, list the identity-defining details (bevels and rounding, panel seams, fasteners, painted or engraved lines, gloss versus matte zones, wear) and map each one to a real component. Anything the image cannot show is marked inferred.
Build in passes: blockout, structure, form, materials, surface detail, lighting, interaction, optimisation. After each pass, render from a camera matched to the reference and put reference and render side by side in one sheet. Do not start the next pass until silhouette IoU (overlap of the two silhouettes) is at least 0.85 at blockout and 0.90 from forms on, with proportions within 5%.
Derive colours and material classes from the reference pixels, not from memory.
Runtime: named pivots and sockets for anything that moves, a userData.tick for an idle loop, under [8k] triangles, one draw call per material.
Finish with per-region confidence and a list of what was inferred.
Starter prompt
Build [asset] in Blender from the attached references as a game-ready asset for [Three.js / Unity / Godot]: about [1.85 m], [3k] triangles, [rigged / static], GLB with LOD0 to LOD2.

Write asset-brief.md first: each view and its camera estimate, the scale evidence, 8 to 15 proportions to check, parts, materials, and what must be inferred. Ask me only what the images cannot tell you.
Model through re-runnable bpy scripts, one per phase. Every constant is a measured value with a comment naming the view it came from, or is marked inferred.
Gate each phase with a compare sheet from a reference-matched camera and at gameplay pixel size: blockout silhouette IoU at least 0.85 with proportions within 5%, forms at least 0.90 within 2%. Nothing gets detail until its silhouette passes.
Measure only from orthographic views. Perspective art is for silhouette and surface.
Export, re-import into an empty scene, and check triangle counts, bones, clips and height (within 1%) against ASSET_MANIFEST.json.
Hand over a report of what matches, what deviates, and what was inferred.
Starter prompt
Source assets for [scene] instead of modelling them: [three tree species, a rock set, crates, a grass PBR texture, a sunset HDRI].

Licences: CC0 first (Poly Haven and ambientCG through their public APIs, Kenney, Quaternius, KayKit free packs, Smithsonian items marked CC0). CC-BY only when nothing CC0 fits (Sketchfab with licence slug cc0 or by, Poly Pizza, BlendSwap CC-0 or CC-BY, itch.io packs whose page states CC0 or CC-BY). Blendkit: CC0 assets only, and ask me first. Never NC, ND, Editorial, Sketchfab Standard or Free Standard, Blendkit Royalty Free, CGTrader or TurboSquid free models, Textures.com, or anything without a stated licence.
Read each licence from the asset's own page or API response at download time, never from a site-wide claim. If the field is missing or not on this list, stop and ask.
For every file, record source URL, author, licence and SHA-256 in ASSET_MANIFEST.json, and generate CREDITS.md for anything that needs attribution.
Normalise on import: metres, Y-up, origin at the base, PBR materials, KTX2 textures, meshopt or Draco compression, at most [5k] triangles per prop.
Render a contact sheet of every imported asset under the scene's own lighting and flag any that clash with the art direction: [palette, stylisation level].
If the build must be a single file, embed only what fits a [10 MB] total and build the rest procedurally.

Licences, at a glance

LicenceCommercialCreditTypical sourcesAgent rule
CC0YesNot requiredPoly Haven, ambientCG, Kenney, Quaternius, KayKit free packs, Smithsonian CC0 items, 3dtextures.me, cgbookcaseDefault choice
CC-BYYesRequiredSketchfab (slug by), most of Poly Pizza, BlendSwap, OpenGameArt (also OGA-BY)Allowed, log in CREDITS.md
CC-BY-SAYesRequired, and adaptations share alikeSome OpenGameArt and BlendSwapAsk me first
Store licence, no redistributionOnly if nobody can extract the fileVariesBlendkit Royalty Free, Fab Standard, ShareTexturesAsk me first. Never in a web build or public repo, where anyone can pull the GLB out.
NC, ND, editorial, unstatedNo or unclearn/aSketchfab Standard and Free Standard, BlendSwap GAL, CGTrader and TurboSquid free, Textures.com, ObjaverseNever

Agents can search these libraries directly through asset MCP servers such as threenative-asset-mcp, which filters by licence tag and hashes every download. Blender MCP can pull Poly Haven HDRIs, textures and models into a live scene, and Sketchfab or Poly Pizza models with a key (its telemetry is on by default, so switch it off). BlendSwap runs an official MCP server. Check each asset's own page before shipping.

Where to look, and how an agent gets in

SiteWhat it hasLicenceAgent accessRule
Poly HavenHDRIs, textures, modelsCC0 site-widePublic API, no key. Send a User-Agent that names your tool.Default
ambientCG2,000+ PBR materials, HDRIsCC0 site-widePublic v3 API, no keyDefault
Kenney, Quaternius, KayKitLow-poly kits, rigged and animated packsCC0 (KayKit free tier only)Manual downloadDefault
Smithsonian 3DMuseum scans in glTFCC0 only where markedAPI key from api.data.gov. Decimate the heavy scans.CC0 items only
3dtextures.me, cgbookcasePBR texturesCC0ManualDefault
SketchfabVery large catalogue, GLBPer model, returned by the APISearch with license=cc0, free token to download. Sold to KitBash in Aug 2026.Slugs cc0 and by only
Poly Pizza10,000+ low-poly modelsPer model, mostly CC-BYAPI with a tokenCC0 and CC-BY only
BlendSwapAbout 26k .blend files, about 8.6k CC0Per asset, declared by the uploader and not verifiedOfficial MCP and REST API, 5 to 7 free downloads a dayCC-0 and CC-BY only, and check the uploader owns it
Blendkit (formerly BlenderKit)About 149k models, materials, HDRIs, scenesCC0 or Royalty Free per assetBlender add-onCC0 assets only, ask first
OpenGameArtMostly 2D and audio, some 3DPer asset, on the page onlyNo API, 10 s crawl delayCC0, CC-BY or OGA-BY, by hand
itch.io2D sprites, tilesets, UI, fonts, SFX, music, some 3D packs. About 2,700 tagged CC0.Per project, in an optional "License" field under More information, often custom textNo catalogue API (its API covers only your own projects and purchases), so a human downloadsStated CC0 or CC-BY only, "No AI" filter on. Custom licences: ask first. No licence: never.
Fab (Megascans)Scans and materialsFab Standard, or CC-BYNo public download API foundAsk first

Skip CGTrader and TurboSquid free models (files must stay protected or in proprietary formats, and bulk downloads are banned), Textures.com (its terms ban AI use, scripted downloads and open-source release), and Objaverse (scraped from Sketchfab, mostly CC-BY with NC mixed in). ShareTextures calls itself CC0 but its own terms forbid automated downloads and redistribution. Blendkit's Royalty Free licence allows use in software only when the asset "cannot be opened or separated by a third party", which rules out web builds. BlenderKit renamed itself Blendkit on 23 June 2026. On itch.io the licence is whatever the creator typed, and creators can edit a page after you download, so save the page and licence text with the file hash. Generative-AI disclosure has been mandatory for asset packs since November 2024, but it is self-declared. Kenney, KayKit and Quaternius also publish there, so prefer their own sites for the same packs. Confidence: high for the licence terms, which come from each site's own pages. Moderate for download limits and catalogue sizes, which change.

Building levels rather than props? The next section covers level design. For a real-world location instead, OpenStreetMap footprints or streamed 3D Tiles (3d-tiles-renderer) are the usual routes, and OpenStreetMap data needs visible attribution.

Generating assets: hosted first, local fallback

memoryWhen code or a CC0 library cannot give you a concept frame, sprite, mesh, clip, voice or music bed, generate it. The agent asks which route you want, uses the best hosted model when you have a key, and falls back to local ComfyUI with one pick per job. Every output passes the same gates and lands in the same manifest.
Code or CC0 first› Ask the route› Hosted pick, or local fallback› Clean-up in code or Blender› Gate and log

Ask before the first generation

helpFour questions, one message

  • Keys: which of OPENROUTER_API_KEY, FAL_KEY, OPENAI_API_KEY, MESHY_API_KEY, TRIPO_API_KEY are set. The agent checks names only and never prints a value.
  • Spend: a cap for this job, in dollars
  • Data: may these inputs leave the machine? Client plans, unreleased IP and faces often cannot.
  • Use: shipped or internal, company size and territories. This decides which terms and licences are acceptable.

alt_routeThen pick the route

  • A key for the job and inputs may leave: use the hosted pick below
  • No key, inputs must stay, or no answer in an unattended run: use the local pick, and say so in the first update
  • The hosted pick fails the rubric twice: try its alternative before switching routes

Hosted picks, checked 30 Sep 2026

JobPickAlternativeHow to reach itRough price
Concept art, style framesGPT Image 2.5 FlareNano Banana 2OpenAI gpt-image-2.5-flare, OpenRouter, fal$0.01 to $0.05 per 1024 px image
Sprites and UI with alphaGPT Image 2.5 Flare with background: "transparent"Ideogram 4 (fal)As above. Most other hosted models return no alpha.As above
Edits, consistent characters, text in the imageGPT Image 2.5 SunburstNano Banana 2 EditOpenAI gpt-image-2.5-sunburst, OpenRouter, fal. Up to 16 references and masks.$0.05 to $0.09 at high
Icons and true SVGRecraft V4.1 VectorFlare PNG, vectorised in codefal fal-ai/recraft/v4.1/text-to-vector, OpenRouterAbout $0.08
Text to videoWan 3.0Seedance 2.5 or H3 MaxOpenRouter alibaba/wan-3.0, fal alibaba/wan-3.0/text-to-videoAbout $0.05 to $0.20 per second
Image to video, first and last frameMiniMax H3 MaxSeedance 2.0fal minimax/h3-max/image-to-video, OpenRouter minimax/hailuo-3-maxAbout $0.08 per second at 768p
Game-ready props with a face budgetTripo P2 (quads or triangles)Meshy 7.1 smart topologyfal tripo3d/p2/image-to-3d, or Tripo's own API$1.00 to $1.30 per model
Hero meshes, retexture, remeshMeshy 7.1Tripo H3.1Meshy's own API (Pro plan), or fal5 to 35 credits
Rig and animateMeshy rigging and animation (textured humanoids)Tripo auto-rig (creatures)Own APIs onlyCents per rig and clip
VoicesElevenLabs v4OpenAI gpt-4o-mini-tts, which retires on 6 Jan 2027ElevenLabs key or fal. OpenAI TTS also on OpenRouter.Per 1,000 characters
Sound effectsElevenLabs Sound Effects v2, with its loop optionLocal MOSS-SoundEffectElevenLabs key or falFractions of a cent per second on fal
MusicLyria 3 Pro (Lyria 3.5 for vocals)ElevenLabs Music, when you need stemsLyria on OpenRouter and fal. ElevenLabs key or fal.About $0.08 per Lyria track, $0.15 to $0.80 per ElevenLabs minute
Which key reaches whatOpenRouter: images, video, speech and Lyria music, no 3D. fal: images, video, 3D, ElevenLabs audio. OpenAI: images and speech, and no video since the Sora API closed on 24 Sep 2026. Meshy and Tripo keys: 3D, including rigging.
Look the id up, never recall itRead the provider's list (/api/v1/images/models and /api/v1/videos/models on OpenRouter, the model page on fal) before the first call. Hosted names change monthly.
Budget every batchEstimate cost before each round, stop at the cap, and log provider, model id, cost and request id per output. Video jobs run async, so poll them and never resubmit one whose status is unknown.
Keys stay in the environmentNever write a key into code, logs, the manifest or a shipped bundle. Safer still, keep it in an MCP server's config so the session never sees it. A browser build calls your own small proxy, never the provider directly. fal's terms also forbid exposing its API to end users.
Read the output termsOpenAI assigns output rights to you. fal marks commercial use per model. Meshy and Tripo free plans give CC BY or public models, so ship only from paid plans. GPT Image and Gemini outputs carry C2PA or SynthID marks.
Hosted still needs clean-upGenerated meshes still get retopology checks, sprites still get keyed and packed, music still gets its loop point crossfaded. No hosted music model promises a clean loop point.

Picks follow Artificial Analysis arena rankings read on 30 Sep 2026 (GPT Image 2.5 first for generation and editing, H3 Max first for image to video, Wan 3.0 first for text to video with audio after Artificial Analysis reset that board on 29 Sep, Lyria above Eleven Music), top3d.ai's blind 3D votes, and each provider's docs. Prices are list prices on the day and move often. Confidence: High for ids and endpoints, Moderate for rankings and for Tripo P2's topology, which a Digital Production review found mostly quads but not always clean edge flow.

Local fallback: best open model per job

Each row leads with the best-quality open-weight model, ranked on Artificial Analysis's open-weights arenas or published benchmarks where they exist. Several of the best carry licence strings, so the next column names the model to ship with at company scale. Internal and research jobs use the first column. Shipped work uses the second.

JobBest open modelLicenceShip with, at company scaleMemory (approximate)
Images and edits, RGBA outQwen-Image 2.1, first among open models for both generation and editing, up to ten referencesNon-commercialQwen-Image-2512 to generate, Qwen-Image-Edit-2511 to edit Apache 2.0. About 40 and 50 Elo behind. For RGBA UI and text-heavy layouts, Ming-Image 0.1 Design MIT, native since ComfyUI 0.38.2.1: about 28 GB BF16, int8 on 16 GB. 2512: FP8 on 24 to 32 GB.
Video, first and last frame, audioMiniMax H3, far ahead of the next open model (LTX-2.5) on both video arenasFree under $20M with "MiniMax H3" shown. Self-hosting excludes the US, EU, UK and South Korea without approval.Wan 2.2 14B first and last frame Apache 2.0, or H3 under Comfy's paid MiniMax licence. The quality gap is large.H3: int8 about 20 GB plus encoder, about 15 min per 5 s on 16 GB. Wan: FP8 on 24 GB.
Image to 3DTRELLIS.2 for loose shapes, Pixal3D when the mesh must follow the concept (up to 4 views). Close on top3d.ai's blind votes.MITSame, through ComfyUI's native build. It loads DINOv3, whose licence asks for a "Built with DINOv3" credit.5.6 GB int8, 11 GB BF16. 64³ detail needs 24 GB.
Voices, design and cloningFish Audio S2 Pro, second among open TTS models and first with Hindi and 80+ languages. Breeze TTS 2 rates higher but speaks only English and Chinese.Non-commercialChatterbox Multilingual V3 MIT for Hindi and 22 other languages. Step Audio EditX Apache 2.0 for English and Chinese with emotion editing.Fish 12 to 16 GB. Chatterbox small. EditX about 12 GB.
MusicMiniMax Music 3, strongest with independent evidence. YuE2 leads its own lab's benchmark and is non-commercial.Free with "MiniMax-Music3" shown, approval above $20MACE-Step 1.5 XL MITMusic 3 about 11 GB with int8. ACE XL 12 GB minimum, 20 GB comfortable.
Foley from videoHunyuanVideo-Foley, best on MovieGen-Audio and Kling-Audio evals. MMAudio is close but non-commercial.Excludes the EU, UK and South KoreaSame, outside those territories. Inside them, MOSS-SoundEffect from text, synced by hand.XL 16 GB, XXL 20 GB, less with offload
Sound effects from textMOSS-SoundEffect v2.0, 48 kHz, up to 30 s. No open arena exists, so this is the newest strong model, not a ranked winner.Apache 2.0SameSmall, custom node
Cut-outs, masks, depthBiRefNet, SAM 3.1, DA3MONO-LARGE or DA3METRIC-LARGE. DA3-GIANT is better only for multi-view depth and camera poses.MIT, SAM, Apache 2.0Same. DA3-GIANT is non-commercial.Small
Normals and de-lit albedoMarigold V2Apache 2.0SameAbout 17 GB at 1024 px
RiggingSkinTokens, less than half UniRig's skinning error. Make-It-Animatable v1 for fast humanoid rigs.MITSameSkinTokens 14 GB or more
UpscaleSeedVR2Apache 2.0SameFP8 and int8 builds. ComfyUI 0.38 decodes frame by frame, so memory no longer grows with clip length.

Log scale of annual company revenue, group-wide. HunyuanVideo-Foley is limited by territory, not revenue, so it is not on the chart. Terms read from each licence file on 30 Sep 2026. Comfy resells a MiniMax licence that covers local H3 use worldwide, from $5k a month. This is a map, not legal advice.

Rankings read on 30 Sep 2026 from Artificial Analysis's open-weights views (image, editing, video, speech), top3d.ai, WildSongBench, and each model's paper. Speech and music arenas have wide error bars, and sound effects have no open arena, so treat those rows as provisional. Moderate. Left out on purpose: FLUX.2 dev and klein 9B, Krea 2 and Ideogram 4 open weights (all below Qwen-Image 2.1 and restricted), LTX-2.x (well behind H3 and paid above $10M), Hunyuan3D 2.1 and RMBG-2.0. If a brief names one, the agent should say why it was skipped and use the pick.

Driving local ComfyUI

No partner nodesComfyUI's API nodes are hosted calls billed to a Comfy account. On the local route, reject them. For hosted, call the provider with your own key instead.
Drive the local serverComfyUI's HTTP API on 127.0.0.1:8188, comfy-cli with --where local, or Comfy's MCP server (pip install comfy-mcp), which sees your real nodes and model files with no sign-in.
Templates before wiringStart from an official template or your own "Export (API)" file. Wire nodes by hand only when neither exists.
Discover, never recallRead /object_info for node names and inputs and list the model folders. Never write a model filename from memory.
Preflight every graphEvery class_type exists, every model file is present, a Save node is wired and inputs are uploaded. A missing model produces a download list for approval.
Useful chainSAM 3.1 finds "the sofa", BiRefNet softens its edge, DA3MONO gives depth, and Qwen-Image-Edit-2511 changes only the masked area while depth control holds the layout.
JobLocal endpoint
Queue a graphPOST /prompt with the API-format graph and a client_id
Watch progressWebSocket /ws?clientId=, or poll GET /history/{prompt_id}
Fetch outputsGET /view?filename=&subfolder=&type=output
Upload inputsPOST /upload/image
Check nodes and inputsGET /object_info, or /object_info/{class}
JobsGET /api/jobs, GET /api/jobs/{id}, POST /api/jobs/{id}/cancel

Consistency: climb the ladder instead of adding adjectives

  1. Text anchorA fixed identity block, plus a per-shot block for what may change
  2. Approved referenceOne hero image every variation points to
  3. Style referenceA swatch or frame that carries the look
  4. Control mapPose, depth (DA3MONO) or edges to hold composition, on the local route
  5. Trained LoRAOne per character, plus a separate style LoRA, on the local route
Baseline plus deltaThe baseline prompt stays byte-identical across a set. Only the final clause changes.
Anchor to the heroEvery variation references the same approved hero. Chaining output to output compounds drift. A lasting change, such as a new costume, becomes a new approved hero.
Reference beats descriptionOnce a reference image is supplied, stop describing the face in words. The two pull against each other and cause drift.
Seeds repeat one rollA seed reproduces a single image. It carries nothing across a set.
Control mapsStrength about 0.7 for depth or edges, 0.8 to 0.9 for pose. End control around 65% of the steps so detail can refine. Never extract a map from the attribute you are changing.
When to trainOne character across hundreds of images, or four or more identities in shared scenes. Use 5 to 15 images for a character, 10 to 20 for a style. Captions describe what should vary, never what must stay. The best epoch is rarely the last.

Gates and stop rules

Rubric firstWrite pass or fail lines before generating. A rubric written after seeing the batch inherits its flaws.
Verdicts, not vibesThe critic answers index: pass | fail, failed line. A vision model can check the lines, but it cannot prove an exact hex, font or spacing, so measure those in code.
Plausibility is on youQuality scorers catch artefacts, not impossible objects. In Scenario's tests a car with mismatched wheels scored 92 and passed. Add structural checks: counts, attachments, what carries the weight.
Cheapest fix firstA local defect gets a masked inpaint. A uniform grade or crop gets a code pass. Wrong content means editing the delta clause. Drift means tightening references. If everything fails, change the model.
One variable per roundRegenerate from the baseline each time, changing one thing.
Stop ruleA clean round ships. After three rounds without one, stop and report the best result with its flaws. A line that fails twice under two different fixes is evidence about the model.
Sweep video at 2 fpsA single sample missed a defect half a second away in Scenario's tests. Judge frame sheets, never only the first frame.
Log every nodeid, role, model, inputs, outputs and status (accepted, retried, rejected), so any output can be traced and rerun.

Comparing two models? Pre-register three to five pass or fail criteria, keep prompts and inputs byte-identical with the same output count, and turn prompt expansion off. Seeds do not compare across models. Build a contact sheet in candidate order, then judge each image at full size. The winner holds for this brief only.

The consistency ladder, rubric-first loop, fix routing and stop rules come from the Scenario, fal and Higgsfield skill packs, restated for both routes. Their measured figures come from small samples run by the skill authors.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • OpenRouter image and video APIsOne key for images (POST /api/v1/images) and async video (POST /api/v1/videos, then poll), with first and last frame through frame_images.
  • fal model galleryImages, video, 3D and ElevenLabs audio behind one key. Each model page shows its endpoint id, price and commercial-use label.
  • Meshy APIImage and text to 3D, retexture, remesh, rigging and up to ten animation clips per request.
  • comfy-cliInstalls, launches and runs local ComfyUI from the terminal with no account. Its agent skills install with comfy skills install.
  • comfy-mcpComfy's MCP server. Against a local install it runs workflows, watches jobs, lists your real nodes and models and validates graphs.
  • TRELLIS.2 and Pixal3D in ComfyUIImage to mesh with PBR maps, with the non-commercial dependencies removed.
Starter prompt: generation job, either route
Generate [asset or set] for [project].

Route: before generating, ask me in one message: which keys are set (OPENROUTER_API_KEY, FAL_KEY, OPENAI_API_KEY, MESHY_API_KEY, TRIPO_API_KEY, checked by name, values never printed), the spend cap for this job, and whether the inputs may leave this machine. If I am not there to answer, use the local route and say so.
Hosted, when a key fits the job and the inputs may leave: use [GPT Image 2.5 Flare / Sunburst for edits / H3 Max for image to video / Tripo P2 for props / ElevenLabs for audio]. Read the provider's model list to confirm the id before the first call. Estimate the cost of each round and stop at the cap. Poll async jobs and never resubmit one whose status is unknown. Keys stay in environment variables, never in files, logs or the build.
Local, otherwise: ComfyUI at http://127.0.0.1:8188 with the best open model for the job, or its ship-with model if this ships: [Qwen-Image 2.1 or 2512 / H3 or Wan 2.2 / TRELLIS.2 / Fish S2 Pro or Chatterbox]. Start from an official template, read /object_info to confirm every node and input, and stop with a download list if a model is missing. No partner or API nodes.
Use: this is [shipped by a company with about $X revenue, sold in (territories) / internal only]. Use only models and plans whose terms allow that, and name the terms you relied on.
Before generating, write the rubric: [3 to 6 pass/fail lines]. Keep the baseline prompt byte-identical across the set and change only the final clause. Anchor every variation to [hero.png]. For video, chain shots from the previous clip's last frame instead.
Batch: [4] per round at draft settings. Judge each output at full size as "index: pass | fail, line". Fix the cheapest way first (inpaint or edit, then code, then the delta clause, then references, then the alternative model), one variable per round.
Stop when a round is clean or after 3 rounds, and report the best result with its remaining flaws.
Log route, provider, model id, version, terms or licence, seed, cost and request id per output in ASSET_MANIFEST.json. Deliver the files, the workflow JSON or request payloads, and a contact sheet.

Level design

stadia_controllerA level is a sequence of decisions in space. Plan the beats and the metrics, block it out in grey, walk it at player speed, and only then dress it. Agents jump straight to art unless the prompt stops them.
  1. Teach the jump in a safe yard
  2. Develop: first fight, the tower comes into view
  3. Twist: grab the key under pressure
  4. Reveal: vista from the tower, a breather
  5. Finale, then a shortcut loops you home

The five beats follow the teach, develop, twist, conclude structure Nintendo used in Super Mario 3D World. The bottom curve is the pacing: tension rises, releases at the vista, peaks at the finale.

The process pros follow

  1. Pre-productionGoal, references, a beat list, what the level teaches
  2. Layout sketchCritical path, loops, landmarks, gates. Any drawing works.
  3. Metrics playgroundA test map of every jump, door, stair and cover size
  4. BlockoutGrey primitives on a grid sized to the player, prototype textures
  5. Playtest at player speedWalk it with real gravity and collision, never fly the editor camera
  6. Diverge and iterateMost blockouts do not survive the first playtest. That is the point.
  7. Scripting and lightingEncounters, triggers, then light for wayfinding and mood
  8. Art passSwap blocks for kit pieces with the same dimensions

The sequence follows The Level Design Book's process. Its blockout method: sketch a layout, add a ground plane, a player-sized scale figure and walls, playtest, then diverge and repeat. It also notes that art-dependent narrative games (Firewatch, Untitled Goose Game) got more from an art-first vertical slice or location scouting than from a grey blockout.

Principles, as prompt vocabulary

Metrics firstPlayer size, speed, jump height and distance set every door, gap and room. Build the world to the metrics, never the reverse.
Critical path and beatsThe ideal route through the level, with numbered beats. Players will wander, so it is a plan, not a prediction.
PacingAlternate tension and release. Teach a mechanic safely, develop it, twist it, conclude.
Loops over dead endsCycles give multiple routes and shortcuts back. Unexplored generates dungeons from cycles because trees feel random and artificial.
Lock and keyA visible gate first, the key elsewhere, then the return. Gates create goals and structure exploration.
Landmarks and sightlinesSomething tall and distinct, visible from many places, so players build a mental map.
Over or aroundBreath of the Wild's triangle rule: shapes that hide what is behind them and ask the player to climb or circle, with points of interest at the peaks.
Desire linesCompare the path you drew with the path players actually take, and pave the one they want where it fits.

A useful counterweight: The Level Design Book argues against heavy-handed "guiding the player". Too much signposting and breadcrumbing makes a level feel like Disneyland. Aim for a readable space players can learn, not a path they are dragged along.

Starting metrics

MeasureStart hereWhy
GridSnap to player width (1 m for a 1 m wide player)Keeps every opening a clean multiple of the player
Doorways and corridorsAt least 2× player widthAnything tighter feels cramped and snags the camera
Wall height150 to 200% of player heightReads as a room without looking like a hangar
Jump gapsAbout 80% of the controller's max, measured, never guessed (see Physics and controllers)Leaves margin for imperfect input
Stairs in blockoutUse rampsFaster to build and change. Stairs arrive with art.
Overall scaleSmaller than real lifeReal-world scale makes game spaces feel too big and empty
Travel timeMultiplayer: 8 to 12 s from spawn to objectiveSplash Damage's target for Dirty Bomb. Longer frustrates, shorter gets chaotic.

Width, wall and grid values come from The Level Design Book. Jump margin is a common practitioner rule. Always confirm by walking the blockout with the real controller.

How an agent should do it

check_circleAsk for this, in order

  • A one-page level brief: goal, beats, what it teaches, target play time
  • The layout as data first: a graph of areas, connections, locks and keys, as JSON
  • A metrics file read from the controller: speed, jump height, jump distance
  • Blockout from primitives on the player grid, colour-coded: walkable, blocker, interactive
  • Automated checks, then a human walk-through, then art

errorWhere agents go wrong

  • Art and detail before anything is playable
  • Real-world scale, so everything feels huge and empty
  • A branching tree of rooms with dead ends and no loops
  • Judging the level from the editor camera instead of the player's eyes
  • Landmarks everywhere, so none of them work

Checks an agent can actually run: pathfinding reachability from start to every beat and the exit, every required jump inside the controller's measured limits, a bot's critical-path time inside the target, no spot on the path without a landmark or next goal in view for more than [20] s, and a list of dead ends that exist on purpose. Pair them with a top-down render with the path drawn on it and a player-eye screenshot at every beat.

To block out in a real editor, use the engine's MCP or CLI route from Engines and libraries.

Starter prompt
Design and block out one level for [game] in [Three.js / Godot / Unity]. No art yet: grey primitives only.

Brief first, one page: goal, target play time [6 to 8 min], and five beats: teach [mechanic] safely, develop it, twist it, a breather with a view, a finale. Put the brief in your first update and continue without waiting.
Metrics: read speed, jump height and jump distance from the existing controller and write them to metrics.json. Grid = player width. Doors and corridors at least 2× player width, walls 150 to 200% of player height, jump gaps at most 80% of max, ramps instead of stairs.
Layout as data before geometry: level.json with areas, connections, one lock and key, and at least one loop that returns as a shortcut. One landmark visible from most of the critical path.
Blockout: build from level.json. Colour-code walkable, blocker and interactive surfaces. Grid texture on every surface. Spawn and exit marked.
Verify: pathfinding reaches every beat and the exit, every required jump is inside the measured limits, a bot runs the critical path in [target] s. Render a top-down map with the path drawn, and a player-eye screenshot at each beat. List every dead end and why it exists.
Stop after the blockout. Art comes after I have walked it.
Starter prompt
Write a procedural dungeon generator for [game] that builds levels from cycles rather than branching trees, in the spirit of Joris Dormans' cyclic generation in Unexplored.

Stage 1, mission graph: start, goal, and 1 to 3 cycles. Each cycle is a pattern: lock and key (the lock visible before the key), hidden shortcut, or a one-way drop that returns to the start of the loop.
Stage 2, space: place rooms and corridors on a grid sized to the player metrics in metrics.json, preserving the graph.
Stage 3, content: encounters and pickups placed by beat, with rising intensity toward the goal.
Seeded: the same seed gives the same level. Expose the seed in the URL.
Validate every generated level: the goal is reachable, every key is reachable before its lock, no softlocks, the critical path length stays within [min to max] rooms. Reject and regenerate on failure, and log the reason.
Output: 20 seeds rendered as a contact sheet of top-down maps with the critical path, locks and keys drawn, plus pass or fail per seed. (Algorithms and validation: see Procedural generation.)
Starter prompt
Block out an open zone, about [400 × 400] m of game space, for [game], in grey with terrain as stepped terraces first, smoothed later.

Points and lines: one tall landmark visible from the whole zone, plus [4] smaller points of interest, each distinct in silhouette. Main paths run low along valleys, so walking downhill tends to lead somewhere.
Over or around: hills and rock forms shaped so the player must choose to climb or circle, hiding what is behind them. Put a reward or view at each peak.
Density: from any point on the main paths, at least one unvisited point of interest is in view.
Metrics from metrics.json: climbable slope limit, sprint speed, and a target of [30 to 60] s between points of interest at walking speed.
Verify: a heatmap of 50 bot walks from spawn with random goals, a view-coverage map showing where no point of interest is visible, and screenshots from the player's eye at each point of interest. Fix empty stretches before any art.

Game AI

smart_toyGame AI has to look smart and be fun, not be smart. Build it in layers (sense, decide, move, pace), pick the simplest decision model that covers the behaviour, and make every decision visible on a debug overlay.
Move your pointer over the map to steer the player. Otherwise it walks a loop.
PatrolInvestigateChaseSearchReturn
Patrolling its waypoints.

Sense: a vision cone blocked by walls, a hearing radius, a memory of where you were last seen. Decide: a five-state machine. Move: A* on the grid. The awareness meter fills before the chase starts, which is the telegraph that makes it fair.

Pick the decision model

ModelHow it decidesUse it forCost
Finite state machineExplicit states and transitionsGuards, simple enemies, animation logic. Nest them (HFSM) when states multiply.Cheapest. Turns to spaghetti past about ten states.
Behaviour treeSequences, selectors and decorators over tasks that succeed, fail or keep runningMost NPCs. Readable, reusable, easy to debug by following the tree.Structured and predictable, less emergent
Utility AIScores every option from curves over inputs, picks the bestNeeds, survival, companions, anything that constantly reprioritisesTuning curves takes time. Hard to see why without score readouts.
GOAPPlans backwards from a goal through actions with preconditions and effectsEmergent tactics with many interchangeable actionsSearch cost, and fun is harder to control and debug
HTNPlans forwards by decomposing a high-level task into designer-built subtasksSquads and bosses that need multi-step plans a designer can shapeYou author the whole network. Fewer surprises, fewer happy accidents.

The common practitioner advice: start with the simplest model that serves the gameplay. Davide Aversa's rule of thumb is that behaviour trees cover most cases, and planners pay off only when you need emergent solutions. Studios often combine them, for example a utility layer choosing priorities and a behaviour tree executing them. Game AI Pro's overview explains the HTN versus GOAP difference: HTN plans forward from the current state through a designer-built network, GOAP plans backward from the goal.

The four layers

SenseVision cones with line of sight, hearing radii, and memory (last known position, how long ago). Perception is where fairness lives.
DecideOne of the models above, with every transition logged and drawn.
MoveA* on a grid or navmesh for routes, steering (seek, arrive, avoid, flock) for motion, flow fields for crowds going to one goal.
PaceA director watches player stress and spawns or withholds threats. Left 4 Dead's cycles build-up, peak and relax, and changes pacing rather than difficulty.

Libraries for the web

LibraryWhat it gives youLicence
YukaEngine-agnostic: entities, state and goal-driven agents, steering, graphs and A*, navmesh queries, vision and memory, fuzzy logicMIT. Last commit Jan 2023: stable but unmaintained.
recast-navigation-jsWebAssembly port of Recast and Detour: navmesh generation, pathfinding, crowds, temporary obstacles, three.js helpersMIT
navcatPure JavaScript navmesh generation and queries, dynamic off-mesh links for jumps and laddersCheck the repo
three-pathfindingNavmesh path queries for three.js (you supply the navmesh)MIT
rot.jsRoguelike toolkit: field of view, A* and Dijkstra, map generators, schedulerCheck the repo

check_circleRules practitioners follow

  • Telegraph before acting: an awareness meter, a bark, a wind-up
  • Let players read the state: a guard that says "Who's there?" is doing design work
  • Cheat only where nobody can see it, never through walls the player can check
  • Tick decisions at 5 to 10 Hz, movement every frame, and time-slice path requests
  • Seed all randomness so a bug can be replayed

errorWhere it breaks

  • Perfect aim and instant detection, which reads as unfair
  • States with no exit, so NPCs freeze or loop
  • Pathfinding every agent every frame
  • No debug view, so nobody can say why it did that

What an agent can verify on its own: scripted scenarios with expected outcomes ("noise at X, the guard arrives within 6 s"), a headless run of 500 seeded encounters reporting detection time, time to lose the guard and stuck agents, and screenshots of the debug overlay at each state change.

Starter prompt
Add stealth guard AI to [game] in [Three.js / Canvas] using [Yuka / a hand-written FSM] and [recast-navigation-js / grid A*].

States: patrol (waypoints), investigate (a noise), chase (player seen), search (last known position, then look around for [4] s), return. Every state has an exit and a timeout.
Perception: vision cone [90]° and [18] m with line of sight through the navmesh or walls, hearing radius per noise type, memory of last known position. Awareness fills over [0.4 to 1.5] s depending on distance and light before a chase starts, shown above the guard.
Barks for each transition ("Who's there?", "Lost them"), so the state is readable without UI.
Performance: decisions at 10 Hz, movement every frame, path requests capped at [4] per frame.
Debug overlay on [F1]: state name, vision cone, hearing radius, current path, last known position.
Verify: seeded scenario tests (noise at X reaches X within 6 s, a player out of sight for 5 s gets lost), then 200 headless seeded runs reporting detection time and stuck guards, plus overlay screenshots at each state.
Starter prompt
Build squad combat AI for [game]: a utility layer chooses what each enemy wants, a behaviour tree executes it.

Utility options: attack, take cover, flank, reload, retreat, regroup. Each score is a curve over inputs (health, ammo, distance to player, cover quality, allies nearby). Show the scores on the debug overlay.
Behaviour tree per option: move via navmesh to a cover point scored by protection and line of sight, then act. Tokens limit attackers to [2] at a time so the player is never swarmed.
Fairness: telegraph shots with a [0.4] s aim line, accuracy that ramps over the first second of exposure, never shoot through cover.
Barks when flanking or reloading so the player can read the plan.
Verify: 300 seeded fights against a scripted player bot, reporting time to kill, damage taken per second, how often each option wins, and any agent stuck for more than 3 s.
Starter prompt
Add an AI director to [game] that shapes pacing, modelled on Left 4 Dead's build-up, peak and relax cycle.

Intensity per player from damage taken, enemies nearby and recent kills, decaying over time.
Build-up: spawn threats out of sight, ahead on the player's path. Peak: when intensity passes [0.8], stop new spawns. Relax: [30 to 45] s of calm, or less if the player pushes forward. Then build up again.
Change pacing, not difficulty: enemy strength stays fixed, frequency and placement change.
Log intensity and director state every second and chart them after each run.
Verify: 50 seeded runs with a scripted player bot. The intensity chart must show repeated peaks and valleys, no stretch of calm longer than [60] s, and no death spiral.

Procedural generation

casinoA generator is a design tool, not a content fountain. Seed it, constrain it, validate every output, and judge it on a hundred results rather than the one that looked good.
5

The algorithm cookbook

AlgorithmGood forKnobsWatch outJS options
Seeded PRNGEverything belowSeedMath.random() makes bugs unrepeatablemulberry32, sfc32, @redblobgames/prng
Noise and fBmTerrain, textures, variation, windFrequency, octaves, lacunarity, gain, domain warpEndless same-looking blobs. Shape it with falloffs and curves.simplex-noise, FastNoise Lite, three's ImprovedNoise
Poisson disk samplingNatural scatter: trees, rocks, spawn pointsMinimum distanceUniform random clumps and leaves gapspoisson-disk-sampling
Voronoi and DelaunayRegions, biomes, polygon maps, cracksPoint layout, Lloyd relaxationRaw cells look mechanical until relaxed and noiseddelaunator, d3-delaunay
Cellular automataOrganic cavesFill %, birth and survival rule, iterationsIsolated pockets. Flood fill, then connect or cull.rot.js Map.Cellular
BSP, rooms and corridors, drunkard's walkDungeons and interiorsMinimum room size, depth, corridor styleSamey grids of boxes. Add loops and hand-made rooms.rot.js Digger and Uniform
Graph grammars and cyclesMission structure, lock and keyRewrite rules, cycle typesMore authoring up front. See Level design.Hand-written
Wave Function CollapseTiles, towns, textures from examplesTileset, adjacency rules, weightsContradictions (the problem is NP-hard, so add backtracking) and homogeneous resultskchapelier/wavefunctioncollapse
L-systems, space colonisationPlants, trees, branching riversRules, angles, iterationsExponential growth. Cap iterations.Hand-written
Marching cubes over SDFs3D caves, voxels, blobsField function, resolutionMemory and triangle counts climb fastthree's MarchingCubes addon

WFC ships in Bad North, Caves of Qud and Townscaper according to its author Maxim Gumin, who also notes that contradictions are rare in practice. Red Blob Games' polygon map generator chains Poisson points, Delaunator, and noise-driven elevation, rivers and biomes, which is a good model of stacking simple algorithms.

The process that makes generators good

  1. Describe the outputWhat a great output has, what a bad one looks like, and hard constraints
  2. Hand-make three examplesYou cannot generate what you cannot describe or build once
  3. Structure firstGraph, zones or constraints before geometry
  4. Stack simple algorithmsPoints, then cells, then noise, then dressing. Each stage is testable.
  5. Validate and rejectConnectivity, path length, playable area. Regenerate and log why.
  6. Judge in batchesContact sheets of 50 to 1000 seeds and histograms of every metric
  7. Mix with hand-made piecesAuthored rooms or set pieces placed by the generator
  8. Curate or tuneFix the rules, not individual outputs

Steps 1, 4 and 6 follow Kate Compton's essay So you want to build a generator, which separates free-form algorithms (noise, Voronoi, triangulation) from constrained tile and constraint-solving methods, and warns that the free-form ones are often too uncontrollable for gameplay. Her best-known warning, the "10,000 bowls of oatmeal" problem, is that outputs can be mathematically unique yet feel identical, which is why you judge perceived variety across batches.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • MarkovJunior MITGumin's rewrite-rule language with 150+ example generators: mazes, dungeons, buildings, voxels.
  • mapgen4Red Blob Games' interactive map generator with painted elevation, rivers and biomes.
  • wavefunctioncollapse (JS)A JavaScript WFC port listed by the original author.
Starter prompt
Write a seeded terrain generator for [game] in [Three.js], chunked at [64 × 64] m.

Everything derives from one seed through a seeded PRNG. No Math.random anywhere. Same seed, same world, on every machine.
Height: fBm simplex noise ([5] octaves, lacunarity 2, gain 0.5), domain warped, shaped by a curve so plains stay flat and mountains stay rare. Rivers flow downhill from chosen sources to the sea.
Biomes from height and a moisture noise. Vegetation and rocks scattered by Poisson disk sampling with per-biome density. Nothing on slopes over [35]°.
Design hooks: [3] hand-made landmark set pieces placed on suitable flat ground, at least [300] m apart.
Performance: chunk generation under [8] ms in a worker, streamed around the player.
Verify: a contact sheet of 24 seeds as top-down maps, plus per-seed metrics (land %, largest landmass %, biome shares, landmark placement success). Flag any seed outside the target ranges.
Starter prompt
Write a seeded [dungeon / cave] generator for [game] that combines algorithms instead of trusting one.

Structure: [BSP rooms and corridors / cellular automata at 45% fill, 4-5 rule, 4 iterations], then flood fill and remove or connect isolated regions. Add [1 to 2] extra corridors to create loops.
Mix in hand-made pieces: [entrance, treasure room, boss room] templates placed by the generator in rooms that fit.
Placement: start and exit at least [60]% of the level's width apart, keys before their locks, enemies scaled by distance from the start.
Metrics from metrics.json: grid sized to the player, corridors at least 2× player width.
Verify: generate 500 seeds and report playable area, path length start to exit, loop count, rejected seeds with reasons, generation time. Render a contact sheet of 24 and flag outliers.
Starter prompt
Implement Wave Function Collapse (simple tiled model) for [a town / a dungeon floor] in [Three.js], seeded.

Tileset: [list tiles] with sockets on each edge, rotations generated automatically, weights per tile. Adjacency is derived from sockets, not hand-listed pairs.
Solver: lowest-entropy cell first with seeded tie-breaking, propagation after every collapse, and backtracking on contradiction with a retry cap.
Constraints before solving: fixed tiles for [the plaza, the road entry points], a border of [wall / water].
Post-process: flood fill to confirm every walkable tile connects to the entry, and reject outputs that fail.
Verify: 200 seeds reporting contradiction rate, backtracks, solve time and connectivity. Render a contact sheet of 24 to check the results do not all look alike.

Physics and character controllers

sports_handballSimulate on a fixed timestep, interpolate what you render, and move the player with a kinematic controller, not a free physics body. Feel lives in the controller's numbers.

Both balls get the same jump every second. The left one integrates with each frame's delta, so jump heights change with frame rate. The right one steps at a fixed 120 Hz and interpolates for display, so every jump is identical on any machine.

The loop that fixes it

Fixed timestep with interpolation
const DT = 1 / 60;               // simulation step, never the frame delta
let acc = 0, prev = performance.now();
function frame(now) {
  let ft = (now - prev) / 1000; prev = now;
  ft = Math.min(ft, 0.25);       // avoid the spiral of death after a stall
  acc += ft;
  while (acc >= DT) { savePrevious(); step(DT); acc -= DT; }
  render(acc / DT);              // alpha: blend previous and current state
  requestAnimationFrame(frame);
}

This is Glenn Fiedler's accumulator from "Fix Your Timestep": clamp the frame time, step in fixed increments, then render a blend of the previous and current state using the leftover fraction.

Pick an engine

EngineStrengthPick it when
Rapier (WASM)Fast, deterministic option, built-in kinematic character controllerDefault for web games that need a real controller
Jolt (jolt-physics, WASM)AAA-grade rigid bodies, vehicles, soft bodiesLarge, heavy simulations
cannon-esPure JavaScript, simple APISmall toys and prototypes
Your ownExactly the rules you needPlatformers and arcade feel, where real physics fights the design

Rapier's character controller handles move-and-slide against obstacles, sliding on slopes, climbing stairs automatically (autostep), snapping to the ground when walking downhill, and moving platforms. Its docs show a 45° climb limit and a 30° slide threshold as example settings. One gotcha costs agents hours: a Rapier sensor collider reports nothing until you enable ActiveEvents.COLLISION_EVENTS on it, so pickups and triggers silently never fire.

Controller numbers that define feel

SettingStart hereWhy
JumpDefine height h and time to apex t, then gravity = 2h ÷ t², launch speed = 2h ÷ tDesigners think in heights and times, not gravity constants
Fall gravity1.5 to 2.5× rising gravityA snappy landing instead of a floaty arc
Variable jumpReleasing jump early cuts upward speed by about halfShort taps give short hops
Coyote time and jump bufferAbout 100 ms eachForgives input that is a few frames early or late
Acceleration0.1 to 0.2 s to full speed on the ground, slower in the airResponsive without feeling weightless
Slopes and stepsClimb up to about 45°, autostep about 0.3 to 0.5 mPlayers never snag on kerbs
Scale1 unit = 1 m, real gravity only for dynamic propsPhysics engines are tuned for metres

The height-and-time jump derivation is from Kyle Pittman's GDC talk "Math for Game Programmers: Building a Better Jump". The other values are common practitioner starting points. Tune them in a metrics test map.

check_circleRules

  • Physics steps are fixed. Rendering interpolates.
  • The player is kinematic. Crates and ragdolls are dynamic.
  • Continuous collision detection on anything small and fast
  • Collision shapes are simple: capsules, boxes, convex hulls

errorWhere it breaks

  • Physics tied to frame rate, so jumps differ per machine
  • A dynamic-body player that tips, bounces and slides
  • Bullets tunnelling through thin walls
  • Triangle-mesh colliders on everything
recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • @react-three/rapierRapier bindings for React Three Fiber.
  • ecctrlCharacter, vehicle and drone controllers for R3F and Rapier, with a live tuning demo. It uses a floating, spring-damped rigid body, a deliberate alternative to the kinematic rule above.
Starter prompt
Build the player controller for [game] with [Rapier / a hand-written kinematic controller] in [Three.js].

Loop: fixed [60 / 120] Hz simulation with an accumulator, frame time clamped to 0.25 s, rendering interpolated between the last two states.
Controller: kinematic capsule [0.4] m radius, [1.8] m tall. Move-and-slide, climb slopes up to [45]°, autostep [0.35] m, snap to ground [0.3] m, ride moving platforms.
Jump defined by height [1.4] m and time to apex [0.38] s (derive gravity and launch speed). Fall gravity [2]×. Early release halves upward speed. Coyote time and jump buffer [100] ms each.
Ground acceleration [0.12] s to top speed [6] m/s, air control [60]%.
All values in one controller.json, with a live tuning panel.
Evidence: measured jump height within 2% of spec at 30, 60 and 144 fps. A replay of recorded inputs gives identical positions. A test map with every step, slope and gap from metrics.json passes.

Camera systems

videocamCameras are most noticeable when they fail. Frame what the player needs next, move less than you think, and never let the camera enter geometry.

Position lock drags the whole world through every jump. Lerp smooths it but still bobs. The window only moves when the runner pushes an edge, looks ahead in the direction of travel, and re-centres vertically only when the runner lands on a platform, which Itay Keren traces back to Super Mario World.

2D: a vocabulary from Itay Keren's "Scroll Back"

Position lockCamera fixed to the character. Fine for small characters with small jumps, as in Terraria.
Camera windowThe character moves freely inside a box. The camera moves only when it pushes an edge.
Platform snappingVertical re-centring happens when the character lands, not while it jumps.
Look-aheadShift the view toward where the player is heading, so they see threats sooner.
Edge snappingStop at the level's edges instead of showing empty space.
Cues and zonesAuthored hints that pull the camera toward a boss, a secret or a vista.

3D third person: what John Nesky warns against

check_circleDo

  • A spring arm: cast from the character to the camera, pull in fast on a hit, ease back out slowly
  • Fade or dither objects that block the view instead of zooming wildly
  • Tilt pitch gently when running up or down slopes
  • Smooth with a framerate-independent damp (1 − e−k·dt)
  • Keep shake on a separate layer from the gameplay camera

errorDon't

  • Bob the camera with the walk cycle
  • Move the camera up and down with every jump
  • Use a narrow or rapidly shifting field of view
  • Snap to a new position without a transition
  • Shake excessively, or test only with experienced players

The "don't" list paraphrases items from Nesky's GDC 2014 talk "50 Game Camera Mistakes", given by the camera designer of Journey. The spring-arm pattern is the standard Unreal approach: without a collision test, the camera ends up inside other objects.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • camera-controls MITSmooth transitions, collision, first- and third-person, boundaries, and a camera-shake example for three.js.
Starter prompt
Build the camera for [game], a [2D side-scroller / 3D third-person] game. Keep the 2D or the 3D line below and delete the other.

For 2D: camera window [30% × 40%] of the screen, horizontal look-ahead of [20]% in the direction of travel easing over [0.5] s, vertical re-centring only on landing (platform snap), clamped to level edges, optional zone cues for [boss arenas].
For 3D: orbit camera on a spring arm [4.5] m behind and [1.6] m above the character. Sphere-cast from the character to the camera every frame, pull in within 1 frame on a hit and ease out over [0.4] s. Dither-fade objects between camera and character. Pitch follows slope by up to [8]°. FOV [65]°, no walk-cycle bob, no vertical follow during jumps.
Smoothing: framerate-independent exponential damping. Shake and FOV kicks live on a separate juice layer.
Verify: record camera paths through the test level and report frames with the camera inside geometry (target 0), frames where the character is more than [30]% occluded, and peak angular speed. Screenshot every zone transition.

Character animation

directions_walkClips supply the motion, a state machine picks them, blending hides the seams, and IK makes feet and hands meet the world.

The canned cycle plays the same leg motion everywhere, so feet float over dips and sink into bumps. With IK, each foot plants on the ground, stays locked while the body moves, and steps when it drifts too far. Two-bone IK solves each leg analytically.

The pipeline

  1. Rig and clipsA rig from a CC0 pack or a local auto-rigger (below), plus clips from Quaternius, Mixamo or your own
  2. RetargetMap bones between skeletons. Check rest pose, root bone and axis orientation first.
  3. State machineIdle, walk, run, jump, fall, land, attack, with blend spaces driven by speed
  4. BlendCrossfades of about 0.1 to 0.25 s. Playback rate matched to movement speed.
  5. IK and look-atFeet on slopes and stairs, hands on ledges and props, head toward points of interest
  6. Secondary motionSprings for tails, capes, antennae and hair
  7. EventsFootsteps, hit frames and effects fired from clip markers

check_circleRules

  • Playback rate = movement speed ÷ the clip's authored speed, so feet never slide
  • Anticipation and follow-through on every action that matters
  • In-place clips for controllers, root motion only where the clip must drive the body
  • Animation events drive footstep sounds and dust, not timers

errorWhere it breaks

  • Feet skating because speed and clip do not match
  • Inverted feet or backwards hands after retargeting mismatched rigs
  • A T-pose flash on a missing transition
  • Snapping between clips with no blend

In three.js, SkeletonUtils.retargetClip maps a clip from a source skeleton to a target, AnimationMixer handles crossfades, and the CCDIKSolver addon does chain IK. Forum reports show retargeting between mixamorig skeletons with different proportions can invert feet and hands, so compare rest poses before trusting the output.

Auto-rigging on your own machine

Hosted riggers (Meshy for textured humanoids, Tripo for creatures) and local learned auto-riggers both give a usable first pass for the skeleton and body weights. Fingers, shoulders and loose clothing are where they break, and nobody has published an independent benchmark, so treat the output as a draft that must pass weight gates before any animation work.

AssetFirst passFallback when a gate failsWatch out
HumanoidMake-It-Animatable v1, run directly or as the MIA node in ComfyUI-UniRig MIT code, Apache 2.0 weightsRigify with a hand-fitted metarig, converted to a game skeleton with Rigodotify MITMIA v2 loads Hunyuan3D 2.1, which carries territory limits. Stay on v1 for shipped work.
Creature, quadrupedSkinTokens: skeleton and skin in one pass, GLB out, 14 GB or more of VRAM MITUniRig through ComfyUI-UniRig, with the skeleton fixed before skinningUniRig's own README says skinning can degrade badly when bones such as a tail or wings are missing
Prop, vehicle, machineA procedural bpy rig: one bone per rigid part, weight 1.0, hierarchy from the part splitn/aLearned skinners give soft weights that blur rigid joints
Clothing on a rigged bodyRobust Weight Transfer from a clean body GPL-3.0Manual paintGPL applies to the add-on, not to your assets
Four influences, normalisedAt most four bones per vertex, weights summing to 1. glTF clients may read only the first set of joints and weights. Finish with glTF Validator at 0 errors.
Every vertex weightedZero unweighted vertices and no weights on non-deform bones. Headless automatic weighting can fail silently, so count.
No bleedEach vertex's strongest bone is one of its nearest. Hand weights on the thigh fail.
SymmetryMirrored left and right weights differ by less than 0.05 on a symmetric mesh.
Extreme-pose sheetShoulders ±90°, elbows and knees 130°, spine twist 45°, fists. Report volume loss per joint (under about 10%) and self-intersections, and render a contact sheet.
Retarget and round tripPlay a CC0 clip on the rig and render it. Export GLB, re-import, and confirm bone count and rest pose are unchanged.

ComfyUI-UniRig (GPL-3.0, last commit 31 Jul 2026) wraps UniRig and Make-It-Animatable and recommends MIA for humanoids. Its one-click installer is marked experimental, open issues report nodes that fail to register on the latest ComfyUI, and UniRig's sparse-convolution dependency has no CUDA 12.8 build yet (the RTX 5090 fix is an unmerged pull request). Test it on your card before relying on it. UniRig's released checkpoint was trained on the smaller dataset, and its authors now point to SkinTokens. Skip RigAnything (Adobe non-commercial licence), Anymate (no code licence), Puppeteer and MagicArticulate (inactive since Sep 2025), and Mixamo and AccuRig, which need an account and have no API. The pass thresholds above are starting values, not published standards. Confidence: moderate, because quality evidence is mostly GitHub issues and the authors' own benchmarks.

Starter prompt: auto-rig
Rig [character.glb] for [Three.js / Godot]. Ask first whether a Meshy or Tripo key is set and whether the model may leave this machine.

Type: [humanoid / quadruped / prop]. Hosted: Meshy rigging for textured humanoids (face +Z, under 300k faces), Tripo auto-rig for creatures. Local: Make-It-Animatable v1 for humanoids, directly or through the MIA node in ComfyUI-UniRig, and SkinTokens for creatures. Prop: a bpy script with one bone per rigid part and weight 1.0.
Clean up in Blender: limit to 4 influences per vertex, normalise, remove weights on non-deform bones. Transfer clothing weights from the body with Robust Weight Transfer.
Gates: 0 unweighted vertices, no vertex whose strongest bone is not among its nearest, mirrored weight difference under 0.05, volume loss under [10]% per joint on the extreme-pose sheet (shoulders ±90°, elbows and knees 130°, spine twist 45°, fists), a CC0 walk clip plays cleanly, the GLB passes glTF Validator and re-imports with the same bones and rest pose.
If a humanoid fails twice, switch to Rigify with a fitted metarig and Rigodotify, and say which gate failed.
Log tool, version, licence and gate results in ASSET_MANIFEST.json. Deliver the GLB, the pose contact sheet and the gate report.

Sprite sheets from a video model

An image model drawing frames one at a time makes the character "boil" because identity shifts between frames. A video model animates one image, so identity holds. H3 Max does the animating with a key (24 fps), Wan 2.2 in local ComfyUI without one (16 fps), and the steps below turn its clip into a clean, anchored, looping sprite. sprite-gen now runs the whole chain for walk sets in up to eight directions.

  1. Key pose on a safe keyOne still with margin, on a flat key colour far from the subject's hue (green for pink or red, magenta for green, never blue or cyan)
  2. Canvas per actionTall 3:4 with about a third headroom for jumps, wide 16:9 with room in front for attacks, tight for idles
  3. AnimatePin first and last frame only for idles and one-shot attacks. Walks and runs get an in-place prompt and no end frame. sprite-gen video-prompt prints the prompt text it measured on Grok Imagine, which you can send to any video model.
  4. Key every frame the same wayUnmix edge pixels into clean colour plus partial alpha, with one palette per clip, so edges cannot change between frames
  5. Find the periodCompare frames on small thumbnails, take the shortest repeat that is nearly as good as the best, and keep every frame of that cycle
  6. Hold size, then remove driftA walk with no end frame is held at its first frame's size before the cycle search, then the leftover offset is spread as a ramp (--anchor motion-auto). No frame is snapped to its own feet.
  7. Repair and check the loopRIFE remakes up to three jump frames. Then the seam distance must be at most 2× the average frame-to-frame distance, and the report gives a jolt index and any seam pop. Watch the GIF for limb alternation, stalls and snaps.
  8. Align the directionsEvery direction of a walk is resampled to one cycle length and starts as the same foot lands. A loop that may hold two strides stops the set until someone counts them.
  9. Pack with a manifestOne row per state and a manifest.json with absolute frame rects, fps, durations and loop flags. The engine never guesses a grid.
ActionFrom an image-model rowFrom a video clipNotes
Idle4 frames, loopThe whole pinned clip, minus its repeated last frameKeep movement subtle. A breathing idle can also be built from one still.
Jump, attack, wave4 frames, 5 with a return to idle, 6 at mostRest, action, rest, cut from the clipNo forced loop
Walk, runExperimentalOne detected period, every frame keptTreat as experimental until motion QA passes. Pixel art at 8 to 12 fps.
Walk in 4 or 8 directionsn/aSide, front, back and two three-quarter views, each filmed on its ownMirror the rest only if nothing on the character is one-sided
Fluid effectsn/a24 to 48 framesFire, water, smoke
Rows, not one big sheetOne generation per state, cut into frames by connected components. Asking for a whole grid in one image, or cutting fixed cells, drifts identity and overlaps poses. In sprite-gen's validation, 9 and 12 frame rows raised duplicates and extraction failures.
Deterministic keying beats matting hereOn a flat key, unmixing edges into despilled colour plus alpha left less key contamination than BiRefNet-lite or ViTMatte in sprite-gen's ground-truth test. Keep BiRefNet for photos and busy backgrounds.
Never pin each footIn a walk one foot lifts every step, so snapping each frame to its own lowest pixels makes the body lurch by a stride. Remove linear drift and use the mean foot line.
Count the strides by eyeA walk can repeat almost as well at one step as at a full stride, and pixels cannot tell the two apart. sprite-gen flags such a loop and stops the direction set until the agent looks at the frames and passes --cycles. A two-stride loop resampled into a set walks twice as fast as the rest.
RIFE only between neighboursRIFE (rife-ncnn-vulkan, MIT) remakes a jump frame from the two frames around it in the same walk. It smears a changed appearance, so it never draws in-betweens between different poses. On Linux it runs through llvmpipe Vulkan, because its CPU path gave wrong frames in sprite-gen's test.
Name the bodyThe prompt sentences were measured on people. Without --body-plan quadruped or legless, a horse gets walked on two legs, swings arms and strikes with hands.
Draw one-sided items, never mirror themA sword, watch or logo on one side swaps hands in a mirrored view. Pass --handed "the sword=right hand", draw each left-facing view from its own still (video-set --facing right,left), and run handed-check to confirm the item stays on its side.
Thin props jump at the wrapA staff held overhead can sway on a slower beat than the steps. The seam measure is an area, so a thin rod hardly moves it. sprite-gen checks the top band of the silhouette for a jump into the first frame.
Scale keyed pixels premultipliedResize coverage and colour apart. Plain bicubic or Lanczos on a keyed frame leaves a light rim or a green tint at the edge.
One pixel grid, one paletteFor pixel art, measure the pixel pitch per frame, snap outliers to the row's consensus, and share one palette across the run. The logical height must divide the cell height exactly.
Numbers for QAFail a row when frames are near-duplicates or nothing moves. Regenerate a failed row rather than retiming it, and stop after three correction passes.
Cheap extrasA breathing idle from one still (head kept rigid), palette-map colourways that are byte-identical on rerun, and a projected shadow from the foot anchor instead of a painted one.
People choose lastDeliver checked files first. Then a curation view lets a person reorder, reject and nudge frames, stored as edits and baked on export.

Most rules here come from sprite-gen (Apache 2.0, v2.35, 6 Oct 2026, more than 20 releases since 26 Sep), whose docs record the measurements: the period search takes the smallest dip within 15% of the deepest, a seam gate of 2.0, a 96-pixel thumbnail distance, rest frames kept on both sides of one-shots, and jolt reference bounds of 0.43 (index) and 0.75% of body height (head step per frame) from 46 judged takes. The jolt is reported, not gated, unless you pass --jolt-max. Most thresholds rest on one or two hand-run sets, so treat them as starting values. Two extras: video-follow adds damped follow-through to a soft part such as a belly or pouch, and a held walk animated on twos below 13 drawings a second is named for a retake. Prompting for a ground line did not fix drift in Scenario's tests either, while alignment in code brought the spread under 1 px. GIF delays round to 10 ms, so preview at 10, 20 or 25 fps and ship frames or the atlas to the engine. Wan 2.2 14B renders at 16 fps and H3 Max at 24, so pass the real frame rate to every tool.

Starter prompt: sprites from a generated clip
Turn [character.png] into game sprites for [idle, walk, attack] in [side only / 4 directions / 8 directions], with sprite-gen v2.35 or later.

Route: ask me first. Clips come from H3 Max image to video with a fal or OpenRouter key, from sprite-gen's own video command with a SuperGrok login, or from Wan 2.2 in local ComfyUI. Use one source for a whole direction set.
Body: [biped / quadruped / legless]. Pass --body-plan to every command that takes it. One-sided items: [the sword=right hand], passed as --handed. Draw each left-facing view from its own still instead of mirroring, and run sprite-gen handed-check on the loops.
Still and canvas: put the character on a flat [green / magenta] key chosen away from its colours. Run sprite-gen video-canvas --still [still.png] --state [state] --facing [right] for each state (tall for jump, wide for attack).
Prompt: sprite-gen video-prompt --direction [side] --state [state] --facing [right] --json, adding --no-last-frame for walk and run. Send that prompt and the canvas to the video model. Idle and attack also pin the end frame to the canvas.
Per clip: sprite-gen video-frames --clip [clip.mp4] --key [green / magenta] --spill auto --reference [canvas.png], then sprite-gen video-loop --frames-dir [frames/keyed] --state [state] --fps [the fps in frames.report.json] --cycle auto, adding --anchor motion-auto for walk and run.
RIFE: run sprite-gen rife install once, so jump frames get repaired. Without it, loops are cut as filmed with a warning.
Directions: once a walk is cut in every direction, run sprite-gen video-cycle-align with one --loop-dir and one --view per direction (front, side@right, back). If it stops on a suspect loop, look at that loop's frames, count the strides, and rerun with --cycles [loop]=[1 or 2].
QA: read each loop report. Seam at most 2.0, jolt index at most 0.43, no seam_pop warning, or say why the loop is kept. Build a contact sheet and a GIF per state and check limb alternation, stalls and drift. Report walk as experimental unless it passes.
Pack: one row per state with manifest.json (rects, fps, durations, loop flags), plus Aseprite JSON if the target is Phaser.
Log route, model, seed, key, fps and tool versions in ASSET_MANIFEST.json. Deliver the files, then offer the curation view.

Procedural creatures, no clips needed

BodyPhase pattern for A·sin(2πt/T + φ)
QuadrupedDiagonal leg pairs at φ = 0 and π
HexapodTwo alternating tripods
Snakeφ = i·2π/N along the body, amplitude rising toward the tail
FishAmplitude concentrated in the rear third
WingsOuter segment lags 0.15 to 0.25 of a cycle, body bobs against the downstroke
SlimeScale z = 1 + A·sin, x and y = 1/√z to keep volume

Build the skeleton from bounding-box fractions so the rig reruns on a new mesh, and weight each vertex by inverse distance to its two nearest bone segments. Headless automatic weighting can silently give zero weights, so count weighted vertices. To check motion, render a phase grid at uneven fractions (0, 0.23, 0.41, 0.68, 0.87), since even steps can alias with the cycle. From Higgsfield's procedural animation reference.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • MixamoOnline auto-rigging and a large library of humanoid clips. Needs an Adobe account and has no API, so an agent cannot drive it.
  • ComfyUI-UniRig GPL-3.0UniRig and Make-It-Animatable as ComfyUI nodes, with skinning, posing and export. Optional, and test the install first.
  • Rigodotify MITTurns a Rigify rig into a clean game skeleton with Godot, Unity or Unreal bone names.
  • Quaternius CC0CC0 characters and animation packs that share a rig.
  • sprite-gen Apache 2.0Claude and Codex skill plus Python CLI for sprites. Keying, loop finding, jump-frame repair, direction alignment, atlas and manifest, QA, recolour, Aseprite export, shadows, tiles and a curation view all run offline on any clip or row. Its own gen and video commands use a ChatGPT (Codex) or SuperGrok login, or a per-call OpenAI key, so treat them as the hosted route. Needs Python 3.11+, ffmpeg, img2webp from libwebp 1.5+, and rife-ncnn-vulkan for repairs. It changes almost daily, so pin the version.
Starter prompt
Animate the player character in [game] ([Three.js], glTF rig).

Clips: [idle, walk, run, jump start, fall, land, attack] from [Quaternius / the attached files / Mixamo, which needs an Adobe account and its terms checked]. Retarget with SkeletonUtils to our rig using an explicit bone map, and check rest pose, root bone and axes before trusting the result.
State machine with a speed blend space (idle, walk, run) and crossfades of [0.15] s. Playback rate matches movement speed so feet do not slide.
Two-bone IK for both feet: raycast to the ground, plant and lock feet during contact, lift and step when drift exceeds [0.25] m. Pelvis lowers to the lowest foot on slopes. Head looks at points of interest within [60]°.
Secondary motion: spring-driven [cape / tail].
Clip events trigger footstep sounds and dust by surface type.
Verify: measure foot slide during planted phases (target under [2] cm per step), screenshot every state and transition, walk the stairs and slope test map, and confirm there is no T-pose frame.

VFX that reads

flareAn effect is a sequence of beats, and each beat is a stack of layers. Prompt both.

Turn layers off one at a time. Without smoke the impact has no depth. Without the light pulse it floats above the floor. Without shake it has no weight. Most one-shot VFX ship with the core and the sparks only. Shake, hitstop and knockback also belong to the game-juice layer further down, because they answer gameplay, not just the effect.

Lessons from a 100-spell sandbox

Majid Manzarpour's threejs-vfx, built on Achref Elouafi's original sandbox, draws every effect procedurally in Three.js and GLSL, with no textures or sprite sheets. Its README reads like a VFX prompt checklist:

  • tune
    Settings are the APIEvery value lives in one settings object that shaders read each frame, so sliders work live and while paused. You tune a frozen mid-impact frame, not a blur.
  • straighten
    Store fractions, not metresA cast records only what the dice decided (positions as fractions, a seed). Dimensions resolve from settings every frame, so dragging height regrows a field already standing.
  • bolt
    Noise choice is characterLightning uses piecewise-linear noise because the corners are what read as lightning. A beam uses smooth noise stretched along the flow. "A beam that kinks is a bolt."
  • layers
    Draw the glow as geometryA soft halo pass under a hot core keeps glow attached to every kink, where leaving it to bloom smears it. Core, sheath and halo weighted differently fake a volume cheaply.
  • cloud
    Additive and non-additive on purposeMist is non-additive so it occludes and gives depth. Glitter and sparks are additive. A depth prepass gives soft intersections so nothing cuts a line into the ground.
  • speed
    A budget per castRoughly a dozen draw calls per cast, pooled instances, lights parked at zero instead of added, and a check script that fails if moving a slider changes nothing.

Libraries worth naming in prompts: three.quarks (batched particle systems with a visual editor), TSL compute particles on WebGPU (Dan Greenheck's WebGPU skill covers the API), and hand-written GLSL when you want full control.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • three.quarks MITParticle and VFX engine for three.js with batched rendering, trails, a visual editor, and Unity particle import.
Starter prompt
Build a [fireball impact] VFX in Three.js ([WebGL2 with GLSL / WebGPU with TSL]), fully procedural, no textures or sprite sheets.

Beats: wind-up [0.4 s], travel [0.5 s], impact, linger [1.1 s]. Each beat has its own layers.
Layers: a hot core, a soft glow drawn as real geometry (not left to bloom), sparks as velocity-stretched streaks under gravity, non-additive smoke that occludes, a ground scorch decal that cools and fades, one pooled point light pulse, and a short screen shake with heat distortion on impact.
Motion character: [piecewise-linear kinks for electric / smooth noise stretched along travel for fire and beams].
Soft intersections against scene depth so nothing cuts a hard line into the floor.
All parameters in one settings object with a lil-gui panel. Edits apply while paused so I can tune a frozen frame.
Budget: about [12] draw calls and [1,500] particles per cast, pooled, four concurrent casts at 60 fps on [target device].
Verify: capture a frame at every beat plus a paused mid-impact frame, on a dark and a bright floor. Each layer must be visible and none may blow out to white.

Shaders and post-processing

filterRender in linear HDR, add effects in the right order, tone map near the end. "Cinematic" usually comes from a few effects done in order, not from more of them.

With tone mapping off, the lamps and the moon clip to flat white. Bloom only looks right when it reads the bright values before tone mapping, which is why order matters.

A pipeline order that works

Scene in linear HDR› AO, reflections, fog› Bloom from bright pixels› Depth of field, motion blur› Tone mapping› Grade or LUT› Vignette, grain, CA› sRGB out, anti-aliasing
StackHow it worksUse it when
three.js EffectComposerOne pass per effect. RenderPass first, OutputPass last for tone mapping and colour space.Simple setups on WebGLRenderer
pmndrs postprocessingEffectPass merges many effects into one shader pass, drawn with a single full-screen triangleSeveral effects at once, performance matters
WebGPU with TSLNode-based post graphs. Write once, run on WebGPU with WebGL 2 fallback.New WebGPU projects

check_circleRules

  • Never mix the three.js composer with the pmndrs composer
  • Run bloom, AO and blur at half resolution
  • Move heavy maths from the fragment shader to the vertex shader where you can
  • Pick the tone mapper deliberately: ACES shifts hue, AgX and Neutral keep it truer
  • Learn by reading The Book of Shaders and Inigo Quilez's articles

errorWhere it breaks

  • Bloom on everything, so the image turns to haze
  • Washed-out colours from a missing output or colour-space pass
  • Old ShaderMaterial code on WebGPURenderer, which renders nothing
  • Grain and aberration strong enough to read as a bug

Tone mapping is supposed to desaturate the brightest colours as it forms the image. A three.js forum answer on tone mapping recommends accepting that and adjusting colours and exposure instead, and notes that ACES shifts hue more than many people want, which is why AgX was added as an option.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • The Book of ShadersThe standard step-by-step introduction to fragment shaders.
  • LYGIA Non-commercial by defaultLarge library of reusable GLSL, WGSL and HLSL functions: noise, SDFs, colour, tone mapping. Licensed under Prosperity (non-commercial) plus a patron licence, so a commercial product needs a paid licence.
Starter prompt
Add a post-processing stack to [game] using [pmndrs postprocessing on WebGL / TSL nodes in three.js RenderPipeline on WebGPU].

Order: render in linear HDR, then [SSAO], bloom from pixels above luminance [1.0] at half resolution, [depth of field], tone mapping ([AgX / ACES]), a colour grade (LUT or lift, gamma and gain), then vignette [0.3], grain [0.04] and chromatic aberration [0.0015], then sRGB output and SMAA.
Merge effects into as few passes as possible. Bloom, AO and blur at half resolution.
Exposure and every effect strength in one settings object with a tuning panel, plus a per-effect on and off toggle.
Budget: the whole stack under [2.5] ms GPU at 1440p on [target device].
Verify: screenshots with each effect isolated and all combined, a luminance histogram to confirm nothing important clips, and a GPU timing per pass.

Sound and music from code

graphic_eqThe model cannot hear. Give it ears: render audio offline and hand it numbers and pictures.
Press a sound. It plays live and is also rendered offline, then measured.
AttackDecaySustainRelease

Every sound request should carry an envelope in milliseconds, a pitch movement and one feeling word. "Punchy" means a 2 ms attack and a short decay. Say which.

Pick the right tool

ToolBest forLicenceWatch out
ZzFXGame SFX in one line each, 20 parameters, under 1 KBMITThin for music. Great for jams and single-file builds.
Web Audio APICustom synths, spatial audio, OfflineAudioContext renderingBuilt inNeeds a user gesture before sound starts.
Tone.jsScheduled music, synths, effects, Transport timingMITAdds weight. Use its scheduler, not setTimeout.
StrudelPattern music and live coding (TidalCycles in JS)AGPL-3.0Embedding it obliges the whole app to be AGPL-compatible. Render to audio for closed-source work.
SuperColliderDeep synthesis, offline rendering of asset banksGPL-3.0Desktop tool. Ship the rendered files, not the engine.

The listening loop

Write code› Render offline to WAV› Analyse: peak, loudness, spectrogram, onsets, BPM› Model reads the report› Fix and re-render

This is the audio version of screenshot verification. Community tools already do it: strudel-ai renders patterns to WAV and returns a "hearing" report with spectrogram, envelopes, onsets and estimated BPM, and several Strudel MCP servers let Claude compose and play in the REPL. Without the loop, "make it sound punchy" is a guess.

Game mix and local generation

Starting levelsVoice −6, effects −10 to −12, music −18 to −20 dBFS peak, true peak at −3 or lower. Voice sits above effects, effects above music.
Core set firstAbout five sounds in priority order: the main verb, damage, reward, environment, ambience. At most two music loops, with fades at loop boundaries.
One sound per promptWhen generating, ask for one event and say "no music, no voice, no ambience". Run 2 or 3 takes and normalise loudness, since generated effects run loud.
Playable mutedEvery cue has a visual twin, and the mix is checked on phone speakers.

Levels from Higgsfield's game-audio reference, which gives peak levels rather than loudness, so treat them as starting points. With a key, ElevenLabs covers voices, effects and music with stems (see Generating assets). Locally, MiniMax Music 3 or ACE-Step 1.5 XL (MIT) write music with lyrics and section tags such as [Chorus - soft], and Fish Audio S2 Pro, or Chatterbox Multilingual for shipped work, handles voices. For video set to a supplied track, measure beats and onsets with librosa (ISC) first (see Coded video).

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • jsfxrsfxr in JavaScript: preset buttons for jump, hit, pickup and explosion sounds, exportable as WAV or code.
Starter prompt
Create the sound effects for [game] in code with [ZzFX / Web Audio], no audio files: [jump, coin, hit, UI click, footsteps on grass and on stone].

For each sound, define the layers (transient, body, tail), the envelope in milliseconds, the pitch movement, and one feeling word ("dry and tight", "heavy and dull").
Variation: ±[5]% pitch and 3 to 5 variants for anything that repeats, so it never machine-guns.
Mix: true peak at −3 dBTP or lower, UI quieter than gameplay, footsteps quietest. Start the AudioContext on the first input, add an [M] mute key, and pan sounds to their on-screen position.
You cannot hear, so verify with numbers: render every sound with OfflineAudioContext, write WAVs, and report peak, RMS, duration, spectral centroid and a spectrogram image for each. Fix clipping, long tails, and sounds that share a band with something that plays at the same time.
Starter prompt
Compose an adaptive music loop for [scene] in [Tone.js / Strudel].

Key [D minor], [84] BPM, 4/4, exactly [32] bars ([91.4] s), restarting on a bar line.
Intensity layers: 0 pads and texture, 1 adds bass and soft percussion, 2 adds the melody, 3 adds full drums. Layers crossfade over one bar.
Palette: [warm tape-saturated keys, vinyl crackle, brushed drums]. Avoid [bright supersaws, four-on-the-floor kick].
Render each intensity offline to WAV. Report integrated loudness (target around [−16] LUFS), true peak, a spectrogram, and a zoom on the seam from the last bar into the first. Fix any click or level jump at the loop point.
If you use Strudel (AGPL), render every layer to audio files and ship those. Never ship Strudel itself in closed-source work.

Timing maths to keep in the prompt: bars × 4 × 60 ÷ BPM = seconds. For a video loop, pick BPM so the music loop length equals the visual loop (60 s at 120 BPM is exactly 30 bars).

Game juice

boltJuice is many small answers to one player action, stacked in time: motion, camera, time, sound, particles. Prompt it as a list, with numbers and an off switch.

Turn everything off and hit. Then add one feedback at a time. Switch to ¼× to watch the wind-up and the hitstop freeze, and read the strip at the top: it draws the last hit to scale. Sound plays on hits you trigger, after your first click.

Borrow Feel's vocabulary

More Mountains' Feel is a Unity asset, but its model is the clearest way to describe juice to any engine, including a Three.js or Canvas build. One player component holds a list of feedbacks, and each feedback does exactly one thing: a sound, a flash, a camera shake.

Feedback playerA named list per event (JumpFeedback, LandingFeedback). Code only calls play.
Parallel, pause, holding pauseEverything starts together until a pause. A holding pause waits for everything above it to finish.
IntensityOne number passed at play time scales every feedback. A light hit and a crit share one player.
TimingInitial delay, cooldown against spam, repeats, and chance per feedback.
RandomnessA random intensity and duration multiplier, so repeats never look identical.
Shakers and channelsFeedbacks broadcast, and listeners on a matching channel react. Split screens stay independent.
SpringsDamping plus frequency, then MoveTo or Bump. Spammable and additive, no duration to tune.
Global switchesAny feedback type can be disabled everywhere, which is how a "reduce screen shake" option works.

Starting numbers

FeedbackWhat it sellsStart hereWatch out
HitstopWeight of contact40 to 100 ms freeze of simulation time, scaled by damageFreeze the sim, not input or UI. Never stack.
Screen shakeImpact, dangerTrauma 0 to 1, add 0.2 to 0.6 per event, shake = trauma², decay about 1 per second, smooth noisePure random reads as jitter. Always ship a toggle.
Squash and stretchElasticity, lifeSpring at 4 to 6 Hz, damping ratio about 0.3 to 0.5, keep volume (x = 1 ÷ y)Pivot at the feet so contacts stay grounded.
Hit flashConfirmationTarget turns white for 2 to 4 framesFull-screen flashes: stay under three per second.
Knockback and recoilForce directionSpring bump along the hit direction, plus a small kick on the attackerPush the visual, not the collider, unless it is a mechanic.
AnticipationReadable intent80 to 150 ms wind-up before the actionToo long and controls feel laggy.
Particles and permanenceConsequenceA burst on impact, then marks that stay (shells, scorch, debris)Cap counts, pool everything.
SoundHalf the feelLayered hit, ±5% pitch, a low thump on heavy hitsSame sample every time machine-guns.
UI popsRewardNumbers pop with a spring, counters roll, buttons press to 95% scaleMust not cover gameplay information.
ForgivenessFairnessCoyote time and a jump buffer, commonly around 100 ms eachThis is feel, not juice. Tune it before any effect.

The numbers are practitioner starting points, not rules. The shake model comes from Squirrel Eiserloh's GDC talk Juicing Your Cameras With Math: trauma decays over time, displacement is trauma squared driven by smooth noise, and the camera's real transform is untouched for gameplay. The canonical demos are Martin Jonasson and Petri Purho's Juice it or lose it and Jan Willem Nijman's The Art of Screenshake.

check_circleRules practitioners follow

  • Make the loop fun first. Juice amplifies a good mechanic and hides a bad one.
  • Every player action gets an answer within one frame
  • Scale feedback with consequence: a graze is not a crit
  • Juice runs on the game clock, so hitstop and slow motion affect it too
  • Offer toggles for shake, flashes and motion, and respect reduced motion

errorWhere it breaks

  • Every effect at maximum on every event, so nothing stands out
  • Shake that moves the gameplay camera and breaks aiming
  • Particles and numbers covering the thing the player must read
  • Tweens on a separate clock that ignore pause and hitstop
recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • juicy-breakoutThe source of the "Juice it or lose it" demo, with every feedback toggleable.
Starter prompt: juice pass
Do a juice pass on the existing game. Do not change any mechanic, speed, damage or collision.

Structure: one feedback player per event ([jump, land, hit, get hit, pickup, death, UI confirm]). Each player holds a list of single-purpose feedbacks, plays them in parallel unless a pause is listed, and accepts an intensity from 0 to 1 that scales every feedback.
Hit, at intensity = damage ÷ max damage: hitstop [40 to 100] ms of simulation time, target flash for [3] frames, squash spring on the target ([5] Hz, damping [0.4], volume preserved), knockback spring along the hit direction, a spark burst, a layered hit sound with ±5% pitch, and camera trauma +[0.3 × intensity].
Camera shake: trauma model, displacement = trauma² × max offset ([12] px, [3]° roll) driven by smooth noise, trauma decays at [1] per second. Offset only the render camera, never the gameplay transform.
Land: dust puff, squash on contact, a soft thump. Pickup: pop scale, a rising two-note chime, a number that springs in.
Everything runs on the game clock, so pause, hitstop and slow motion affect it. Cap particles and cooldown every feedback against spam.
Settings: one juice object with every value exposed, plus "reduce screen shake" and "reduce flashing" toggles, defaulting to reduced when prefers-reduced-motion is set.
Verify: record the same 10-second input sequence with juice off and on, capture frames at each event, and list every feedback that fired with its measured duration.

Does anime.js help?

animationYes, for UI juice, SVG and DOM motion, and seekable timelines. For in-world juice, keep springs and shake inside your game loop, or drive anime.js from that loop.

Anime.js v4 is a modular, MIT-licensed engine: timelines, stagger, springs, draggable, a scroll observer, SVG morphing, line drawing and motion paths, with every module importable on its own (about 24.5 KB with everything). It animates plain JavaScript objects too, so a Three.js camera position or a shader uniform is a valid target. Version 4.5 (Jun 2026) adds a Three.js adapter for objects, materials, lights and cameras. A v5 beta exists, so pin 4.x in prompts.

JobBest toolWhy
HUD and menu juice, button presses, score popsanime.jsSprings, stagger and timelines in a few lines, small bundle
Coded video and motion graphicsHyperFrames with its anime.js or GSAP adapter, or your own paused timelineseek() puts every element at an exact time, so frame-by-frame export stays in sync. See the coded video section.
SVG diagrams, line draws, morphsanime.jsmorphTo, createDrawable and createMotionPath ship in the core
Scroll-heavy sites with pinningGSAP ScrollTriggerThe deepest scroll toolkit. Free with all plugins since 3.13, under GSAP's own licence rather than MIT.
React UI transitionsMotionDeclarative enter, exit and layout animation
Hitstop, shake, knockback in a game loopYour own springs and trauma in the fixed timestepThey must pause, rewind and slow down with the simulation
Two patterns worth putting in prompts
// 1. Drive anime.js from the game or Three.js loop, so pause and hitstop apply to tweens
import { engine, animate } from 'animejs';
engine.useDefaultMainLoop = false;
renderer.setAnimationLoop(() => {
  if (!hitstopActive) engine.update();
  renderer.render(scene, camera);
});
animate(camera.position, { z: 6, duration: 600, ease: 'outElastic(1, .6)' });

// 2. Frame-exact video export: build a paused timeline, then seek per frame
import { createTimeline, stagger } from 'animejs';
const tl = createTimeline({ autoplay: false })
  .add('.title span', { y: [40, 0], opacity: [0, 1], delay: stagger(30) })
  .add('.logo', { scale: [0.8, 1], ease: 'outElastic(1, .6)' }, '-=200');
for (let f = 0; f < 15 * 60; f++) { tl.seek(f * 1000 / 60); await captureFrame(f); }

Both patterns follow the anime.js v4 docs: engine.useDefaultMainLoop and engine.update() exist for integrating with Three.js or game loops, and timelines expose seek(). If a prompt names anime.js for a single-file build, ask for the module inlined at a pinned version, with no CDN at runtime.

UI, HUD and accessibility

accessibility_newReadable first, pretty second. The four most complained-about accessibility issues in games are remapping, text size, colour blindness and subtitles, so start there.
Colour only
Which allies are hurt? Is health low?
Colour plus shape and text
✕✓✓✕
30%
Readable in any colour vision
I told you not to come back here.
MARA: I told you not to come back here. [door slams]

Top: a stylised, background-free line. Bottom: speaker name, a solid backing box, and a caption for an important sound.

Start with the basic tier

Remappable controlsEvery action, on every input device, including menus
Text size and contrastAdjustable, and applied to all important text, including pop-ups and loading screens
Never colour alonePair every meaningful colour with shape, icon, text or sound
Subtitles done rightOn before any sound plays, speaker names, a solid background, captions for important sounds
Difficulty and paceAdjustable difficulty, text at the player's own pace, no mandatory button mashing
Motion and flashingToggles for shake, flashes and motion blur, a field-of-view slider, no flicker above three times per second

The four top complaints and the FOV default come from the Game Accessibility Guidelines' basic tier. Xbox Accessibility Guideline 101 adds that text settings must carry over to every important text surface, including error dialogs. For web games, a practical target is WCAG 2.1 AA for menus, with reasonable accessibility for gameplay itself.

HUD design

check_circleRules

  • Information hierarchy: health and threat first, everything else quieter
  • Keep HUD inside a title-safe area and scale with resolution
  • Show input prompts for the device in use (keyboard or gamepad)
  • Menus in DOM overlays so screen readers and keyboard navigation work
  • Respect prefers-reduced-motion by default

errorWhere it breaks

  • Red and green as the only difference between states
  • Tiny stylised fonts that look good in a mockup
  • Subtitles that appear only after the first line is spoken
  • Settings that apply to gameplay text but not to menus
recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • react-three-a11yFocus, screen-reader labels and keyboard access for objects in React Three Fiber scenes.
Starter prompt
Design and build the UI, HUD and accessibility settings for [game].

HUD: health, [ammo / stamina], objective and interaction prompts, in a title-safe area, scaled with resolution. Every state uses colour plus shape, icon or text. Prompts switch between keyboard and gamepad glyphs based on the last input used.
Menus in DOM overlays, fully usable by keyboard, gamepad and screen reader.
Settings, applied before the first sound or cutscene: remap every action, text size (at least 3 steps) applied to all text, subtitles on by default with speaker names, a solid background and captions for important sounds, colour-blind safe palette check, difficulty, reduce screen shake, reduce flashing, motion blur off, FOV slider [60 to 100]°. Honour prefers-reduced-motion.
Verify: screenshots of the HUD under deuteranopia, protanopia and tritanopia simulation plus greyscale, every menu navigated with keyboard only, subtitles readable at 360 px wide, and every action remapped once.

Coded video: frameworks and determinism

movieA coded video is a pure function of time: frame number in, picture out. Choose a framework that seeks every frame instead of recording the screen, and give the agent its skills.

Both strips should show a ball moving at a steady speed. The top one is captured in real time while the machine is busy, so frames land late, repeat or skip. The bottom one seeks the animation to exactly frame ÷ fps before each capture, so a slow render only takes longer.

Wall-clock sources to ban in prompts: Date.now(), unseeded Math.random(), CSS animations and videos playing on their own, setTimeout chains, and fonts that load after frame 0.

Which framework?

FrameworkAuthoringAgent supportLicencePick it when
HyperFramesPlain HTML with data-* timing attributes, animation via adapters (GSAP, anime.js, Three.js, Lottie, CSS, WAAPI)21 skills with a /hyperframes router, non-interactive CLI: lint, check, snapshot, preview, renderApache 2.0Agent-made videos at a company, no React, no build step
RemotionReact components, each frame rendered from the current frame numberOfficial skills: best-practices, create, markup, render, docs and moreSource-availableYour team already lives in React and holds a company licence, or needs mature Lambda rendering
Motion CanvasTypeScript generators on a canvas, with a live editor synced to audioCommunity onlyMITHand-crafted technical explainers and diagrams
RevideoMotion Canvas fork with headless renderVideo()Community onlyMITServer-side batch rendering inside your own product
Your own pageCanvas or DOM with a seek(t) function, frames captured by Playwright, encoded by FFmpegAny agent. Opus 5.5 picks this route when no framework is named.YoursSingle-file pieces like this guide's demos, or full control

Remotion's free licence covers individuals, non-profits and for-profit companies with up to three employees, and a larger company needs a paid company licence. Some blogs quote a revenue threshold instead, so check Remotion's own licence page before relying on either. Above that size, assume the company licence.

Ideas worth stealing, whichever tool you use

  • schedule
    Every animation is seekableHyperFrames renders by seeking each frame in headless Chrome and encoding with FFmpeg, so the same input gives the same video. Its adapters make library-clock animations (GSAP, anime.js) frame-accurate.
  • route
    A router skill that confirms the brief/hyperframes reads first, confirms the creation brief, then loads one workflow (product launch, explainer, music-to-video, motion graphic) and only the domain skills it needs.
  • palette
    A design system rewritten for the cameraframe.md translates a web design.md for video, so the agent stops guessing at scale and stops reaching for web chrome like navbars and cards.
  • fact_check
    Lint and snapshot before renderCheck the composition, render stills at named timestamps, look at them, then render the whole thing. The community Remotion skill enforces the same render, inspect frames, fix, re-render loop.
  • widgets
    Blocks before hand-buildingTransitions, captions, charts and overlays come from a catalogue first. Hand-built only when nothing fits.
  • menu_book
    Docs lookup instead of memoryRemotion ships a docs skill so the agent fetches the current API rather than recalling an older version.

Shot planning and continuity

Prompt orderSubject, context, lens and framing, camera motion, atmosphere, mood and colour. Image-to-video prompts describe the motion only, in 15 to 35 words.
Beats and timingHook, setup, development, turn, close. A 15 s piece runs 0 to 2 hook, 2 to 6 context, 6 to 11 proof, 11 to 15 close. Cut on bars (one beat is 60 ÷ BPM seconds) and land payoffs on downbeats.
Pose chainEvery shot ends in the pose the next begins from. Generated per shot, clip N runs from still N−1 to still N, so N shots need N+1 stills. Keep screen side and framing the same at each join.
Bridge from the real frameStart each clip from the previous clip's actual last frame. Make an end frame by editing the start frame, never by generating it separately. Match direction and speed across the join as well as position.
Verify joinsDiff each outgoing last frame against the incoming first frame, and find cuts from frame-difference spikes rather than a contact sheet.
StoryboardsLight pencil on bare paper. Describe the marks as "planning guides drawn by the director, not objects in the world". In Scenario's tests that definition worked where forbidding the marks failed three times.
Text in code onlyTitles and captions are rendered over the frame. Mobile captions carry 3 to 5 words per cue at 60 to 90 px on a 1920 px tall frame. On 9:16, keep the top 14% and bottom 35% clear.
Delivery numbersSocial at −14 LUFS and −1 dBTP, music ducked 12 to 18 dB under voice, voiceover at 2 to 2.5 words per second, no more than 3 flashes per second. Hash the master audio so nothing re-encodes it by accident.

From the shot-planning, cinematography and storyboard skills in the fal and Scenario packs. Chained shots use first and last frame: H3 Max with a key, Wan 2.2 locally. SeedVR2 upscales the result.

From a one-liner to a studio

After the Opus 5.5 launch, coded-video posts said "one prompt". The strongest ones used briefs of 9,500 to 19,000 characters, skills, API keys and runs of up to 12 hours, and one watercolour short openly took 163 model calls over about seven hours. The prompt is a small part of the result. The rest is the harness: a seek(t) renderer, a reference, a beat grid and a loop where the model watches its own frames.

  1. One-liner"A 15-second showreel, go all out" tests your setup. Many people reused it, so the reels rhyme. It contains no idea.
  2. Brand reelGive the product URL. The agent captures real screenshots, logo, colours and fonts into ./assets, lists them, and never redraws the UI from imagination.
  3. ReferenceOne frame, a clip (a frame every 0.5 s) or your own image library becomes style_guide.md and shotlist.md. Take the grammar, never the content.
  4. State-list specTagged blocks for inputs, direction, structure, build rules and gotchas. One element morphs through 8 to 12 states on a beat grid.
  5. Director's briefLogline, references, tools and budget, character bible, beat sheet, text rules, gated workflow, critique loop, deliverables
Say the framework, or get a single fileIn community tests Opus 5.5 wrote one index.html with seek(t), Playwright and FFmpeg, and skipped Remotion and HyperFrames even when installed. Name the framework when you want one.
House rules in CLAUDE.mdThe render contract, banned looks, sound rules and "loop before you show me anything" live in the project, so every film inherits them.
Springs you can seekClosed-form springs are a pure function of time. When a value changes target, add one spring per change instead of restarting, so frame 812 renders without simulating the 811 before it.
Stretch and swapA tab indicator stretches when its leading edge uses a stiffer spring than its trailing edge. Text inside a morphing shape enters after the morph starts and leaves before the next one.
Motion blur from subframesRender 4 subframes per output frame and average them with FFmpeg's tmix filter. Fast moves stop strobing.
A measured beat gridWith a supplied track, detect beats, downbeats and onsets into beats.json: state changes on beats, big moments on downbeats, sound effects on onsets. Without one, synthesise score and effects on the same timeline.
One timeline, every formatLay scenes out with a layout function, not fixed pixels, and render 9:16, 1:1 and 16:9 from the same timeline. Reframe type and UI per format, never crop.
Generate, then traceA video model gives motion that is hard to hand-code. The code layer then redraws the shots on top, so the look stays consistent and owned.
Loop a generated clipFor a title or menu backdrop, pick the cut by matching position and velocity over a few frames around it, at least 2.5 s apart, then bridge the wrap with about seven RIFE frames. Crossfades show as a fade and ping-pong plays motion backwards. sprite-gen documents the cost function.
Probe before the full renderLoad the film under a virtual clock and record console errors and the visible text at five or six timestamps. LaunchVideo runs this check before rendering a 30 s film in 30 to 40 s.
Style as a swappable fileKeep craft rules (DIRECTOR.md, TECHNIQUE.md) apart from the look (one STYLE.md per style), so a new look changes one file. lemo-opuscar ships 39 styles this way, with a storyboard approval and a look approval before the full render.
Headless renders need a GPU pathPainterly fills that take milliseconds on a GPU take seconds per frame in software. On a headless Linux GPU box, launch Chrome with --use-angle=gl-egl and confirm the GPU is used before a long render.
Split long filmsHave the agent write ANIMATION_GUIDE.md so subagents share one style, STORYBOARD.md after the first pass, and one file per chapter.
EffortCreators reported xhigh or max for showcase one-shots. Start at medium and raise it when a render misses listed details. Avoid max for single-file builds, which can use the whole output budget and return nothing.

From Movez's course on the Opus 5.5 motion trend (27 Sep 2026), which collects the posts behind it, and the example repos listed below. The effort levels, character counts and hours are creator-reported, not measured.

Seekable springs (motion.js)
// Damped spring from 0 to 1 as a pure function of time, so seek(t) stays deterministic.
export function spring(t, k = 170, c = 26) {
  if (t <= 0) return 0;
  const w = Math.sqrt(k), z = c / (2 * w);
  if (z >= 1) return 1 - Math.exp(-w * t) * (1 + w * t);   // treat overdamped as critical
  const wd = w * Math.sqrt(1 - z * z);
  return 1 - Math.exp(-z * w * t) * (Math.cos(wd * t) + (z * w / wd) * Math.sin(wd * t));
}

// A value that changes target over time: one spring per change, summed.
export function track(t, keys, k, c) {            // keys: [[time, value], ...] sorted by time
  let v = keys[0][1];
  for (let i = 1; i < keys.length; i++) v += (keys[i][1] - keys[i - 1][1]) * spring(t - keys[i][0], k, c);
  return v;
}

// Render 4 subframes per frame, then blend them into 60 fps with motion blur:
// ffmpeg -framerate 240 -i frames/%06d.png -vf "tmix=frames=4,select='eq(mod(n\,4)\,3)',setpts=N/60/TB" -r 60 -c:v libx264 -pix_fmt yuv420p out.mp4

Make it watch its own frames

Critique captures
# Contact sheet: 2 frames per second, 6 across
ffmpeg -i out/final.mp4 -vf "fps=2,scale=270:-1,tile=6x5" -frames:v 1 out/contact.png
# Strip of 12 consecutive frames around a fast move at 4.1 s (pops, overlaps)
ffmpeg -ss 4.1 -i out/final.mp4 -vf "scale=320:-1,tile=12x1" -frames:v 1 out/strip.png
# Phone test: how it reads at 360 px wide
ffmpeg -i out/final.mp4 -vf "fps=1,scale=360:-1,tile=5x3" -frames:v 1 out/phone.png
# Loop check: play it twice and watch the seam
ffmpeg -stream_loop 1 -i out/final.mp4 -c copy out/loop_check.mp4
# Determinism: render twice, hash every frame, and diff (no output means identical)
ffmpeg -i out/final.mp4 -f framemd5 out/run1.md5
ffmpeg -i out/final_rerun.mp4 -f framemd5 out/run2.md5
diff out/run1.md5 out/run2.md5

Then ask for a harsh director, not a proud author: score the hook in the first 2 s, readability at phone size, motion (springs, no dead frames), variety (something new every 2 to 4 s), composition, brand accuracy and sound sync from 1 to 10. List the three worst problems with timestamps, fix them, re-render only the affected seconds, and repeat until every score is 8 or more or three rounds have passed. Hunt for text overlapping during swaps, anything sliding instead of easing, corner labels and frame borders, centred-on-gradient shots, blurry scaled text, dead beats and a stutter at the loop seam.

Narrated explainers

Script and animatic firstA planning pass writes the script and shot list, reference images fix the look, and a rough animatic checks pacing before any full render.
Narrate without the ticsTell it to avoid its habits in voiceover, such as short punchy sentences and stacks of numbers. A persona helps: "narrate like a university professor".
Word-level captionsRun a local speech recogniser over the final mix for word-timed subtitles: faster-whisper (MIT).
Assemble as a timelineOpenTimelineIO (Apache 2.0) holds the edit as data, FFmpeg does the cuts and mixes. Manim (MIT) joins HyperFrames and Motion Canvas for maths and diagram shots.
A critic that listensCompare the caption transcript with the script, and screenshots with the shot list, before calling the video done.
Real footage, licence firstyt-dlp can fetch Creative Commons clips, but check each clip's licence and the platform's terms, log attribution, and ask before using anything else.

From Deedy Das's workflow post (29 Sep 2026), which uses hosted models for keyframes, video, voice and music. The picks in Generating assets fit it: GPT Image 2.5 for keyframes, H3 Max or Gemini Omni Flash for shots, ElevenLabs for voice and music, with the local picks as the fallback.

CLAUDE.md for a motion studio
# Motion studio rules

Render: every film is a pure function of time. window.seek(t) paints frame t. No CSS transitions, timers or requestAnimationFrame in render mode, no state carried between frames, seeded noise only. Render with the named framework's own renderer (the HyperFrames or Remotion CLI), or Playwright for a seek(t) page. Encode H.264 yuv420p.
Framework: [single file with seek(t) / HyperFrames / Remotion]. Use only the one named here.
Look: one display face, one UI face, [one accent colour]. Something new on screen every 2 to 4 s. Banned: centred title on a gradient, everything fading in, corner labels and frame borders, glow on UI chrome, generic particle bursts.
Motion: closed-form springs from lib/motion.js. At most 8% overshoot on UI, none on large type. Any value with more than one target uses track().
Sound: synthesise score and effects unless a track is supplied. If one is, measure it into beats.json first and put hits on it. Deliver the social master at −14 LUFS and −1 dBTP.
Before showing me anything: render a contact sheet at one frame per beat, score it on hook, phone readability, motion, variety, composition, brand and sync, fix the three worst problems, and repeat until every score is 8 or more or after [3] rounds. List what is still under 8, then render the full film.
recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • ClaudeAnimationBase MITA starter with a seek(t) core, timeline, render script with contact sheets and frame strips, and an ANIMATION_GUIDE.md. Randomness comes from hash(i), never Math.random(), because frames render in parallel and out of order.
  • lemo-opuscar MIT code, CC BY 4.0 guidesClaude Code plugin with 39 film styles, each a STYLE.md over shared DIRECTOR.md and TECHNIQUE.md files. About 30 to 60 minutes per film, by its own account.
  • PDoomVideo No licence fileA music video split into nine chapter files, with ANIMATION_GUIDE.md and STORYBOARD.md. Read it, do not copy it.
  • claude-animation-skill MITClaude Code plugin for hand-drawn Node canvas films: rigs, pens, synthesised sound.
  • awesome-ai-motion MITA prompt library for coded motion.
  • awesome-opus-5-5-videos CC BY 4.0A dataset of Opus 5.5 videos and their prompts, useful for spotting prompts everyone has already used.
  • Manim MITProgrammatic maths and diagram animation.
  • OpenTimelineIO Apache 2.0An edit as data: clips, tracks and transitions an agent can write and FFmpeg can render.
  • faster-whisper MITLocal speech recognition with word timestamps for captions and transcript checks.
Starter prompt
Using /hyperframes, make a [30]-second [product launch / explainer] video for [subject], [1920×1080] at [30] fps.

Confirm the brief with me in one message first: audience, the one idea to land, tone, and whether there is narration or music.
Design: build frame.md from [our design.md / these tokens: colours, two typefaces], sized for the frame, with title safe areas. No web chrome.
Structure: scenes with data-start and data-duration on a [120] BPM beat grid. Hook in the first [2] s.
Motion: GSAP or anime.js timelines only, registered as seekable. No Date.now, no unseeded random, no free-running CSS animation or video.
Use catalogue blocks for transitions, captions and charts before building any by hand.
Loop: lint, check, snapshot stills at every scene start and every beat accent, look at them against the brief, fix, then render.
Deliver the MP4, the snapshot sheet, and a list of anything you invented rather than took from the brief.
Starter prompt
Use /remotion-best-practices. Create a Remotion composition for a [30]-second [explainer] at [1920×1080], [30] fps.

Check current APIs with /remotion-docs before using anything you are not sure of.
Every visual value derives from the current frame (interpolate, spring). Nothing reads wall-clock time.
Scenes as Sequences with durations in frames: [hook 60, problem 150, solution 390, CTA 300].
Audio: [music.mp3] trimmed to the composition, volume ducked under [voiceover.mp3]. Captions word-synced from the transcript.
Props validated with a Zod schema so [headline, stats, colour] can change per render.
Loop: render stills at the start of every Sequence, inspect them, fix, then render the MP4.
Licence note: confirm our company licence covers this before it ships.
Starter prompt
Build a [15]-second motion piece as one HTML file whose entire state is a function seek(t), with t in seconds.

No requestAnimationFrame timing in the render path, no Date.now, randomness from a seeded generator, fonts awaited before t = 0.
A preview mode plays seek(performance time) in the browser. An export mode is driven by a Playwright script that calls seek(frame / [60]) for every frame, screenshots the canvas at [1920×1080], and pipes the frames to FFmpeg (H.264, yuv420p, [60] fps).
If you use anime.js or GSAP, build one paused timeline and call its seek() inside seek(t).
Motion blur: capture [4] subframes per frame and blend them with FFmpeg's tmix filter.
Verify: export twice and compare per-frame hashes (ffmpeg -f framemd5), then build a contact sheet every 0.5 s, a strip around the fastest move and a 360 px phone sheet, and fix what they show.
Starter prompt
Make a [20]-second motion graphics film for [product] ([URL]) paced like a motion designer's showreel: something new on screen every 2 to 4 s.

Assets first: visit the site with Playwright, capture real screenshots, the logo, colours and fonts into ./assets, and list what you found before animating. Crop and animate the real UI, never redraw it from imagination.
Story, one beat each of 2 to 4 s: the problem in [5] words of large kinetic type, the product assembling itself, three features as real UI actions driven by a cursor, one proof number ([metric]), logo and [call to action].
Sound: original music at [120] BPM, synthesised in code, UI clicks and whooshes on the beat.
Formats: [1080×1920] first, then 1:1 and 16:9 from the same timeline, reframed rather than cropped.
Follow the studio rules in CLAUDE.md if the project has them. Show me a contact sheet of one frame per beat before the full render.
Done when all three formats render and every beat on the contact sheet shows real product UI.
Starter prompt
<inputs>
Ask me for: product and URL, [8 to 12] UI states that tell its story, the real data in each state, brand colours, fonts and one accent, a track near [120] BPM, formats.
</inputs>
<direction>
Product-film UI motion. One container never cuts: each state is the same element changing size, radius and fill while its content swaps. A cursor drives every change. [Warm neutral] canvas, one accent, springs with at most 8% overshoot. Banned: bouncy easing, glows, gradients on UI chrome, particle bursts, dead time.
</direction>
<structure>
[120] BPM, [8] bars, something happens on every beat: [logo → button → typed field → loader → success → dashboard card → chart → tooltip → command palette → toast → logo].
</structure>
<build>
One HTML file, window.seek(t), closed-form springs with one spring per target change. Text enters after a morph starts and leaves before the next. Beats measured from the track. 60 fps with 4 blended subframes.
</build>
<gotchas>
No will-change on anything the camera scales. The last frame equals the first, cursor position and velocity included.
</gotchas>
Ask for the inputs, then show me the state list on the beat grid before writing code.
Starter prompt
You are the director, animator, sound designer and render engineer for a [duration] film made in code. This is a multi-session production. Do not rush to a final render.

Film in one line: [logline, and what the viewer should feel at the end].
References: ./refs/ [video, frames or image library]. Take the grammar, never the content. ./audio/track.wav is used unchanged and measured into beats.json first.
Tools: [skills available]. Generated media: ask which route first (hosted with my keys, or local ComfyUI), then use the picks in the guide and log each one. Budget: [time or turns].
Character bible: proportions, palette, expressions, and an identity that survives every style change.
Beat sheet: a hook in the first 2 s, a visual payoff every 3 to 5 s, and a last frame that sets up the first.
Text on screen: when lines go huge and when they sit like subtitles. Leave room for them in every composition.
Gates, in order: style_guide.md and shotlist.md, stills and a contact sheet for every shot, a 960×540 animatic, full animation, polish, sound, final render. Write ANIMATION_GUIDE.md before splitting chapters across subagents.
Critique every shot for up to [3] rounds: score hook, phone readability, motion, composition, depth, sync and polish, log the three worst problems in docs/review_log.md, and fix them. Stop when every score is 8 or more or after round [3], then list what is still under 8.
Deliver: out/final.mp4, out/loop_check.mp4, out/poster.png, out/contact.png and a README.
Starter prompt
Make a [4]-minute [16:9] explainer about [topic] for [audience], in [style].

Plan first: script.md (narration only), shotlist.md (each line mapped to a shot and a technique: HyperFrames, Motion Canvas, Manim or a generated shot), and reference images for recurring elements. Show me both files and wait for my go-ahead.
Narration: a calm expert, "like a university professor". No short punchy sentence runs, no stacks of numbers, about [2 to 2.5] words per second. Voice with ElevenLabs v4 if a key is set, otherwise locally with [Fish Audio S2 Pro for internal cuts / Chatterbox Multilingual if it ships].
Animatic at low resolution with the rough voice before any full render. Fix pacing there.
Assemble the edit as an OpenTimelineIO timeline and render with FFmpeg. Music bed from ElevenLabs Music or, locally, [MiniMax Music 3 / ACE-Step 1.5 XL], ducked 12 to 18 dB under the voice.
Captions: run faster-whisper on the final mix for word-level timings, 3 to 5 words per cue.
Critic: compare the transcript with script.md, and screenshots at every shot change with shotlist.md. Fix mismatches before delivering.
Footage: only clips I supply or whose licence you log in ASSET_MANIFEST.json.
Deliver: final.mp4, captions.srt, script.md, shotlist.md and ASSET_MANIFEST.json. Stop after the critic pass and list any mismatch still open.

Performance and profiling

monitor_heartMeasure first, fix the biggest number, measure again. Most slow scenes are limited by draw calls, pixel fill or wasted frames, not triangle count.

A sample profile of a slow scene. The figures are illustrative, but the order of the fixes is the order to try them in.

Tools

ToolWhat it tells you
renderer.infoDraw calls and triangles per frame, plus geometry and texture counts. If those counts climb while idle, you have a leak.
stats-glLive FPS plus CPU and GPU timing for WebGL and WebGPU, including in workers
Chrome DevTools Performance panelFrame timing, long tasks, garbage-collection spikes, shader compiles
Spector.jsCaptures one frame draw call by draw call, shows overdraw and state changes
three.js InspectorBuilt-in scene and renderer inspection in recent releases

Symptom to cause

SymptomLikely causeFix
FPS drops as the window or pixel ratio growsFill rateCap pixel ratio at 1.5 to 2, half-resolution post effects, dynamic resolution
FPS drops as object count growsDraw callsShare materials, InstancedMesh or BatchedMesh, merge static geometry
Periodic hitchesGarbage collection, shader compiles, texture uploadsPool objects, precompile with compileAsync, KTX2 textures
Memory or counts climb over timeLeaksDispose geometries, materials, textures and render targets
Main thread busy, GPU idleJavaScript per frameProfile, move work to workers or the GPU, stop allocating in the loop

Starting budgets per device

Per frameDesktopMid-range mobile
Draw calls300 or fewer150 or fewer
Triangles750k300k
Textures, and their memory60, 256 MB40, 128 MB
Shadow-casting lights, shadow map2, 20481, 1024
Post passes20 to 1

These are threejs-game-skills' defaults, a starting point to measure against rather than a law. Post-effect cost grows with the square of the pixel ratio, so a DPR of 2 costs four times a DPR of 1. Two habits from recent builds: give each costly subsystem a URL kill switch (Tidewater uses ?noClouds&noVeg) so the agent can bisect frame cost, and run a fast-forward soak test where geometry and texture counts stay flat (one Opus 5.5 demo held a 16 to 26 MB heap over 320 s of play). Sharing one material between objects that look the same is often the easiest win. WebGPU helps most in draw-call-heavy and compute-heavy scenes, but forum users report scenes where it is slower than WebGL 2, so profile before migrating for speed.

GPU compute, only when it pays

Three.js TSL exposes compute shaders with storage buffers, workgroupArray shared memory, workgroupBarrier, atomics and subgroup operations. Use them for large parallel workloads such as particles, simulation or culling, and measure the workgroup size and memory layout on target hardware instead of assuming. Advanced compute (atomics, workgroup memory, indirect draws) is WebGPU-only and plain compute is only partly supported on the WebGL 2 fallback, so a project that ships both needs a reduced path, feature-gated and tested separately.

WebGPU status, Sep 2026: on by default in Chrome and Edge on Windows, macOS and ChromeOS, Safari 26 on every Apple platform, and Firefox 141+ on Windows and 145+ on Apple Silicon Macs. Linux browsers and Firefox on Android still need the fallback. three.js r186 (Sep 2026) adds a TSL Gaussian-splat renderer and loader with glTF import, compileComputeAsync(), a SunLight with cascaded shadows and Object3D.dispose(). It also removes the minified builds and deprecates CommonJS, so single-file prompts should inline the ES module build at a pinned version.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • Advanced TSL and WebGPU optimisationMakio64's notes on TSL caching, compute workgroup sizes, workgroupArray shared memory, subgroups and atomics.
  • detect-gpuClassifies the GPU by benchmark tier, so you can pick quality presets per device.
  • r3f-perfPerformance overlay for React Three Fiber: draw calls, GPU time, memory.
  • glTF Transform MITMesh and texture compression from the command line.
Starter prompt
Profile and optimise [project] without visible quality loss.

Benchmark: a fixed [30] s camera path through the heaviest area, run 3 times. Record average, p95 and p99 frame time, draw calls, triangles, GPU time per pass (stats-gl or timestamp queries), and geometry and texture counts.
Quality guard: capture [8] reference frames on the path before changes. After each change, the per-pixel difference must stay under [1]% (report the metric).
Work order: fix the single largest cost first, then re-measure. Try in this order unless the profile says otherwise: shared materials, pixel ratio cap, instancing or batching, texture compression (KTX2) and mesh compression (meshopt or Draco), shadow map size and cascades, LODs with dithered cross-fade, baked lighting, dynamic resolution.
Log every change with before and after numbers in perf-log.md.
Stop after [5] consecutive changes that each improve p95 frame time by less than [5]%, then write a short report.

Iterate like a director

autorenewMake the model look at its own output, then give notes the way a director gives notes to a VFX team.
each pass within the budget
  1. Build the smallest complete version first.
  2. Run it in a real browser, not in its head.
  3. Capture the frames you named (states, times, loop point), or render the audio and its report.
  4. Critique against the brief, one layer at a time.
  5. Fix the worst problem, re-measure the frame time, repeat.

Anthropic lists browser and computer-use tools as the way to let long tasks check UI work without a human. Opus 5.5 also reads screenshots and diagrams more accurately than Opus 5, which makes step 3 worth the tokens. For dense images (UV layouts, tiny HUD text, technical drawings), capture at higher resolution and give the agent PIL or OpenCV to crop, zoom and measure, or at least a crop tool.

The feedback formula

Where+ What I see+ What should happen+ The limit

These rewrites come from a real ocean-simulation thread. The originals worked for a human who could see the screen. The rewrites give the model the same view.

closeNote
caustics are just noise.
checkDirection
On the reef floor near the pier, caustics read as random speckle. Real caustics are sharp, bright networks that follow the surface waves and drift with them. Derive them from the actual water height field and keep the pass under 1 ms of GPU time.
closeNote
waves crashing still needs improvement. looks cartoony.
checkDirection
On the left-beach breakers, foam appears inside the curl before the lip lands. The lip should throw forward, hit the trough, and only then spawn foam and spray at the impact line. Spray is individual droplets with motion blur, not soft round sprites.
closeNote
performance is starting to suffer.
checkDirection
Frame time went from 11 ms to 19 ms after the foam pass. Profile, name the three biggest costs, and get back under 14 ms with no visible loss. Report before and after numbers.

Two notes from that thread already work well and are worth copying: asking it to research first ("look up how waves crash in real life") and pointing at a named reference ("look at the three.js water pro folder for bow spray"). Research and references turn taste into something checkable.

The target-image loop

  1. ScreenshotCapture the current build at the target size
  2. Edit it into the targetAn edit model (GPT Image 2.5 Sunburst, or Qwen-Image-Edit-2511 locally) repaints the screenshot into the look you want, keeping layout and content
  3. Write the specA vision pass opens with "Hard constraints": numbered imperatives with numbers, plus a tokens file for colours, type and spacing
  4. Build, then diffRe-screenshot and write 10 to 30 measurable fixes, biggest first: type scale, density, colours, components. Skip what already matches.

Adapted from fal's redesign skill, where the edited image is the spec. Edit models still render small text less reliably than code, so keep final text out of the target image and set it in code.

When something breaks

  1. Read the evidenceConsole, screenshots, profiler, the failing test
  2. Search firstDocs, release notes and issue trackers, when the cause is not obvious
  3. One hypothesisThe strongest explanation the evidence supports
  4. Smallest discriminating testOne run that could prove the hypothesis wrong
  5. Fix the causeThen run the checks the change could affect
  6. Two strikesIf two similar fixes fail, question the assumption, the library or the approach

Evidence that counts

Blind A/B criticShow the critic the reference and your render as A and B in random order, unlabelled, and ask which is closer to the brief and why. A critic that knows which one is yours grades it kindly. claude-code-game-builder packs these pairs with a script.
A number per pieceGive each piece a short spec with numeric targets (silhouette, contrast, speed, timing), so two critics cannot contradict each other and the builder knows when it has arrived.
A non-blank frame proves littleIt shows pixels arrived, not that the scene is right. As a floor, require at least 256 opaque pixels and some variance, then check the claim itself against a reference or a number.
Label every numberAuthored (typed in), derived (computed from authored values), measured (read from a run) or gated (a pass or fail check). Only measured and gated numbers count as evidence in the report.
Freeze the state firstSeed, pause, hide debug UI, and warm up for a second so auto-exposure and temporal effects settle. Background tabs pause animation frames, so capture in a visible or headless page.
Score with gatesA 0 to 3 score per category (readability, feel, lighting, motion and so on) with a floor, for example every category at least 2 and an average of 2.3. It stops one strong area hiding a weak one.

From claude-code-game-builder (MIT, a packaging of Matt Shumer's Gauntlet Loop with Sonnet 5.5 building and Opus 5.5 critiquing), the visual-validation skill in linegel's three.js skill set (ISC, 27 WebGPU and TSL skills) and threejs-game-skills (MIT). All three are days to months old with little outside testing, so treat the numbers as starting points. Moderate

Multi-session builds

scheduleLong builds fail in three ways: trying to one-shot everything, leaving features half-done, or declaring victory early. Give the agent shifts: a feature list, a progress log, git commits and a startup ritual.
data_objectfeatures.jsonEvery feature, each starting as failing, with an acceptance check. JSON is harder for the model to quietly rewrite than Markdown.
history_eduprogress.mdWhat the last session did, what is next, what is blocked
terminalinit.shOne command to install, start the dev server and run smoke tests
commitgit historyA commit per finished feature, with a message a stranger could follow
photo_librarygolden/Reference screenshots and perf baselines that every session re-checks
fact_checkevidence/One folder per run, named by a run id, holding the screenshots, metrics and logs the report cites
ruleCLAUDE.mdStable rules: art bible link, metrics, budgets, stop rule, never-do list

Every session, in order

  1. Read progress.md, the git log and features.json
  2. Run init.sh and the smoke tests. Fix anything broken before starting new work.
  3. Pick one failing feature
  4. Build it, then test it end to end in a real browser, with screenshots for visual features
  5. Compare against golden screenshots and the perf baseline
  6. Mark it passing only with evidence, commit, and update progress.md

Anthropic's March 2026 harness-design post adds a separate evaluator agent that clicks through the running app with Playwright MCP and scores four criteria: design quality, originality, craft and functionality. For creative builds, point such an evaluator at taste and leave correctness to tests. It found that a fresh context with a structured handoff beat compaction, and that the evaluator needs its own prompt tuning. The base pattern is Anthropic's harness for long-running agents: an initialiser session sets up the feature list, the progress file, init.sh and the git repository, then each coding session works on one feature at a time, tests end to end with browser automation, commits and leaves notes. For creative builds, add golden screenshots and performance baselines to the feature list, and split roles when it helps: a builder session implements, a reviewer session only critiques against the art bible and budgets.

recyclingReuse before you buildStart here. Pin versions and log licences in THIRD_PARTY.md.
  • autonomous-coding quickstartAnthropic's reference harness for the initialiser and coding-agent pattern, with a sandbox and a command allowlist.
  • cwc-long-running-agentsAnthropic's readable hooks and subagent that rebuild the same loop by hand. In Claude Code, /goal checks a completion condition after each turn.
Initialiser prompt
This is the first session of a multi-session build of [project]. Do not build features yet. Set up the project so future sessions can work reliably.

Create features.json: every feature from the brief as a small, testable item with id, description, acceptance check (how to verify, including which screenshot or metric), and "status": "failing". Include art bible checks, performance budget checks and accessibility checks as features too.
Create progress.md with the goal, the current state, and "next: [first feature]".
Create init.sh that installs dependencies, starts the dev server and runs smoke tests.
Create golden/ with the style frame and an empty perf baseline.
Initialise git and commit.
Put stable rules in CLAUDE.md: link to art-bible.md and metrics.json, the frame budget, the stop rule, and "only mark a feature passing with evidence".
Session prompt
Continue the build of [project].

Start: read progress.md, the last 20 git commits and features.json. Run init.sh and the smoke tests. If anything is broken, fix that first.
Pick the highest-priority failing feature. Work on that one only.
Build it, run it in a real browser, and check it against its acceptance check with screenshots or metrics saved under evidence/[run id]. Compare against golden/ and the perf baseline.
Mark it passing only if the evidence shows it. Commit with a clear message and update progress.md (done, next, blocked).
Keep going to the next feature until [the time budget / N features] is used, then stop with a short summary. Never edit acceptance checks to make a feature pass. Never resubmit a paid or long job whose result is uncertain: check its status first.

The build contract

assignmentSplit long autonomous prompts in two. A stable contract says how to work and lives in AGENTS.md or CLAUDE.md. A short brief says what to build, with numbers. Then tune a few contract lines per model, because Opus 5.5 and Astra lean in opposite directions.

Ideas worth keeping in every contract

Scope triageSort the brief into what was asked, what it needs to work well, and optional extras. Build the first two and list the extras skipped.
Approval lastFinish everything reversible first, so the only thing you approve is a concrete result. Astra's guide recommends exactly this.
Reuse ladderProject code, then official three.js or browser features, then a maintained library, a focused component, an adapted reference, and only then custom code.
Research before brute forceCheck issue trackers and docs, form the strongest hypothesis, run the smallest test that could prove it wrong. Two similar failed fixes mean the assumption is wrong.
Evidence, stated onceA verifier proves only what it measures. Name the completion condition and the evidence for it once, instead of scattering "verify" instructions.
Largest gap firstFor feel and visuals, compare the running build with a reference and fix the biggest gap. Stop when what remains is small or a matter of taste.
No fake workNo stubs or placeholder features, never hard-code for known tests, never weaken a valid test to make it pass.
Hard limitsNo deploying, publishing, purchasing, account changes or remote deletion without explicit permission.
Contract before parallel agentsBefore launching subagents, the lead writes ARCHITECTURE.md, one shared config and an event bus, and gives each agent its own files. No agent edits another's files. Turbo Kart Rally was built this way by five Opus 5.5 agents.

Tune per model

HabitClaude Opus 5.5GPT-6 Astra
Stopping earlyEnds some turns with a progress report. Name the stops you do not want, and treat a text-only turn as a report, not completion. Auto-continue at most two or three times.Asks clarifying questions more than earlier models. Tell it to infer intent, bias towards action and persist until the goal is met.
SubagentsWorks well as a lead that delegates, and a time signal makes teams finish sooner. Allow it only for large, independent tracks, never to double-check its own work, and cap concurrency. In Claude Code, /effort ultracode runs xhigh and lets Claude plan multi-agent workflows, so save it for big measured builds.May delegate less than you want. Say when parallel work is expected and set the concurrency limit in the harness.
VerificationChecks its own work unprompted. Carried-over lines like "include a final verification step" cause over-verification. Define done instead.Tests thoroughly, sometimes more broadly than a small change needs. Say which checks are enough per change.
Instruction filesExisting Opus 5 prompts work. Put stable rules in CLAUDE.md, the brief in the task.More sensitive to skills and AGENTS.md. State that the brief wins over skills, and ask it to name the file when a skill makes it pause. OpenAI now advises short, specific skill descriptions and an AGENTS.md that routes to docs instead of listing required reading.
TimePaces agent teams against a budget line such as elapsed 340s / 1200s.Reasoning effort can change mid-conversation without breaking the cache, in single-agent requests. Opus 5.5 and Sonnet 5.5 can do the same through a beta (see Effort).

Sources: Anthropic's Opus 5.5 prompting guide (unattended runs, time signals, and the note that Opus 5 patterns remain a reasonable starting point), the Opus 5 guide and release notes (subagent caps, over-verification), Anthropic's Sonnet 5.5 guide (extra review rounds, real checks at low effort), and OpenAI's GPT-6 guide (initiative and follow-through, approval after a reviewable result, skills precedence, delegation, test calibration). In Claude Code the subagent caps are the CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH and CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS environment variables.

check_circleContract, not brief

  • How to work: scope, autonomy, reuse, debugging, honesty, limits, report format
  • Changes rarely, so it can sit in AGENTS.md or CLAUDE.md
  • Short enough that no two rules conflict

errorTrim from long contracts

  • Repeated verification checklists and a separate verifier agent for correctness
  • Hard-coded versions in the contract. Pin versions in the brief and the lockfile, and have the agent read that release's notes.
  • Open research lists with no time budget
  • GPU compute rules in projects with no compute-heavy system
  • Quality words with no numbers. Numbers belong in the brief.
  • "Read X, Y and Z before every edit". Say when each file matters and let the model decide what to read.
Contract
# How to work in this repository

Scope: sort each brief into what was asked, what it needs to work well, and optional extras. Build the first two. List the extras you skipped.
Autonomy: work end to end without presenting plans or asking approval for reversible decisions. Ask only when blocked by missing credentials, an irreversible or external action, or an ambiguity that would produce a different product. When approval is needed, finish everything else first so I approve a concrete result. When the brief names a checkpoint ("show me", "stop there"), stop at it. The brief wins over this file.
Reuse: before building a subsystem, check in order: what this project already has, official three.js or browser features, a maintained library, a focused open-source component, an adapted reference, then custom code. Record each dependency, version and licence in THIRD_PARTY.md.
Debugging: when something fails, check docs and issue trackers for known causes, form the strongest hypothesis, and run the smallest test that could prove it wrong. If two similar fixes fail, question the assumption instead of patching again.
Architecture: replace or refactor code when evidence shows it limits correctness, quality or performance. Prefer the smallest change that fixes the cause. Delete the replaced path.
Rendering: choose WebGPU or WebGL by measured need. Feature-gate WebGPU-only work (advanced compute such as atomics and workgroup memory has no WebGL fallback) and test both paths when both ship.
Honesty: no stubs, placeholder features or fake integrations. Never hard-code behaviour for known tests or weaken a valid test to make it pass.
Memory: keep progress.md committed (goal, done, next, blocked, latest evidence). Recover from it after an interruption.
Done: the completion condition in the brief holds in the running build, checked after the last meaningful change.
Quality gaps: for feel and visuals, compare the running build with the brief's reference and fix the largest remaining gap. Stop when the remaining gaps are small or matters of taste, or after [3] passes.
Never without explicit permission: deploy, publish, purchase, change external accounts, delete remote data.
Report: result, what was built, key decisions, evidence (numbers and screenshots), real limitations, changed areas. Keep it short.
Add for Opus 5.5
Use subagents only for large, independent tracks such as a wide investigation or a separate subsystem. Do not use them to double-check your own work. If one agent can do it, use one.
Put status notes in the same message as your next action. The stops I want: nothing can move without me, or the next step is destructive or irreversible.

Harness settings, not prompt text: append elapsed Ns / budget Ns to each message, set effort explicitly (start at medium), and cap subagents with CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS.

Add for Sonnet 5.5
When the work I asked for is done and its checks pass, stop and report. Don't start extra rounds of review or hardening on your own, and don't launch reviewer sub-agents unless I asked for a review. If you think a deeper review is worth doing, say so at the end.
When you change code that can be run, built or type-checked, run a real check that exercises the change before reporting it done: the tests, the type-checker, the build, or the changed command itself. A syntax-only check does not count. If no real check can run here, say which one you did not run and why.

Both lines are Anthropic's, lightly adapted. The first stops Sonnet 5.5 at xhigh or max from running extra review rounds or reviewer subagents, and cut session cost by about a third with no quality change in Anthropic's tests. The second stops it at low from reporting work done without a check. For tool-free reasoning at low or medium, add "Think the problem through before you answer."

Add for GPT-6 Astra or GPT-6.1 Sol
Infer intent and scope from the brief and the repository, bias towards action, and persist until the goal is met or [the turn budget] runs out. Treat "can you" and "I want" as instructions to do the work, not to propose a plan.
When work can run in parallel and that saves time or improves quality, delegate it to subagents.
The brief takes precedence over skills and AGENTS.md. If a skill makes you pause or ask permission, name the file and quote the line.
Run the tests each change needs. Broaden or repeat testing only when new changes or failures justify it.

Harness settings, not prompt text: set max_concurrent_subagents (default 3), and for single-agent runs change reasoning effort with configuration_update rather than per request. OpenAI has published no Sol-specific prompting notes yet, so these Astra lines are a starting point for GPT-6.1 Sol, not a tested fit.

Effort and long runs

speedEffort decides how hard it thinks. Your prompt decides what it does. Do not mix the two.

Keep unattended builds running

Opus 5.5 posts progress as it works, and some of those updates end the turn with text instead of a tool call. A harness that treats that as "done" stops with work left. On the API those notes arrive as thinking blocks that are empty by default, so a text-only client looks silent. Set display: "updates" (beta) to see them, and after about five silent steps add a turn-scoped reminder to report. Anthropic's fix for early stops is to name the ones you do not want:

do_not_disturb_onStops to rule out

  • A summary that announces the next step and then ends
  • An offer to continue "unless you would prefer otherwise"
  • A list of decisions, none of which actually block the work
  • Pausing because a milestone felt like a good place to report

pan_toolStops to keep

  • Nothing can move forward without you
  • The blocker is deliberately protected (keys, paid APIs)
  • Anything destructive or irreversible

For builds that span several sessions, use the feature list and progress file from Multi-session builds. Pair either with a completion condition the harness can check. In Claude Code, /goal does this: a small model checks the condition after each turn. It only reads the transcript and never runs commands, so write a condition Claude's own output can show ("npm test exits 0", "all six screenshots attached and pass the checklist"), keep it under 4,000 characters, and add "or stop after 30 turns". Goals with background work check in every 30 minutes, set by CLAUDE_CODE_GOAL_CHECKIN_MINUTES. If you run your own loop, treat a turn that ends in text as a report, not completion: send one line naming the open items, and stop after two or three automatic continuations so a stuck run gets reviewed. A time signal also helps: Opus 5.5 paces work against lines like elapsed 340s / 1200s, and one sentence saying time matters speeds up agent teams.

Stop rule for creative builds
Keep going through every step that does not need me, and put status notes in the same message as your next action. Stop only when you cannot continue without my input, or before anything destructive. The task is done when [all four screenshots pass the checklist and the console is clean], or after [30] turns, whichever comes first. If you stop early, say which item is still open and what blocks it.

A numeric stop such as "five consecutive iterations with less than 5% improvement" works. Add how quality is measured, for example a per-pixel difference against reference frames under 1%, so "without sacrificing quality" is testable.

Change effort inside a run

Opus 5.5 and Sonnet 5.5 accept a per-message effort change in beta (header mid-conversation-output-config-2026-07-01): send a system message with empty content and output_config.effort, and the new level applies from the next user turn with the prompt cache intact. Changing the top-level effort between requests breaks the cache. Use it to scout at low, build at medium or high, and drop back for re-renders. Sonnet 5.5 with between_tools thinking rejects a mid-conversation change with a 400. It also rejects non-default temperature or top_p.

For long Opus 5.5 builds, Anthropic's 24 Sep advice keeps cached reads, which cost 60% less: pick the model at the start of the session, compact before you step away rather than after, and on an API key set the one-hour cache lifetime.

Which model, and what to add

compare_arrowsSame brief, different habits. Pick by the work, then add the lines that counter each model's tendency. Subagent and verification lines live in The build contract.
Claude Opus 5.5Claude Sonnet 5.5GPT-6 AstraGPT-6.1 Sol
Released22 Sep 202628 Sep 20263 Sep 202629 Sep 2026
Use it forThe hardest long builds, lead agent, criticMost builds and builder agents, at lower cost and higher speedThe hardest reasoning, per OpenAI's 2 Oct family guide. GPT-6.1 Astra was cancelled before release on 28 Sep.Complex coding, research and computer use, at about a fifth of Astra's price ($2 in, $10 out per million tokens)
Default habitGets to work quickly. Posts progress and can end turns with a report.At xhigh and max, adds review rounds and reviewer subagents. At low, can call work done without a real check.Asks clarifying questions more often than earlier GPT models, so it can stop where you expected it to keep going.Delegates to subagents less often than you may want (subagents are in beta in the Responses API).
Line to addName the early stops you do not want. On loose tasks, tell it to look through sources first."Stop and report when the checks pass" and the real-check line (see The build contract).Tell it to infer intent and act. Answer its likely questions up front (art direction, controls, target). Name the palette: GPT-6 models default to muted colour.Keep the brief lean. OpenAI says over-specific guidance now hurts. Say when to use subagents.
Thinking and effortAlways thinks. Effort defaults to medium. Delete "think step by step".Effort defaults to high on the API and medium in Claude Code and the apps, so set it explicitly. Can skip thinking at low and medium, where "Think the problem through before you answer" helps.Reasoning effort from low to max, changeable mid-conversation without breaking the cache. OpenAI: try xhigh or max only when high falls short.low, medium (default), high, xhigh and max. No none. 1.05M context, 128k output.
ImagesReads charts and screenshots precisely.With a crop or zoom tool at high effort, read charts better than with no tools at max.Testers say visuals look finished but in-scene text still reads machine-made.Unverified
Community trickOne-sentence game prompts where it researches the source layout first. Frame-exact JS films built through skills.Builder in a split team: Sonnet builds, Opus critiques blind against a reference (see Iterate like a director).Generate a reference image first, then have it match the image in code. Work district by district against a checklist.Early reports call it a strong auditor with weak visual taste. Use it to find bugs, not to set the look.

Confidence: High for release dates, defaults and prices, taken from Anthropic and OpenAI docs. Moderate for community tricks, which are creator-reported and not independently reproduced. Low for GPT-6.1 Sol's habits, which rest on a few early practitioner reports.

Eight prompt shapes

collections_bookmarkCommunity prompts and the pipelines in this guide fall into eight shapes. Each bar shows roughly where the words go.

Bars are a rough split of each prompt's words across the nine layers, meant for comparison, not measurement.

Techniques worth stealing

  • image
    Reference image firstEarly Astra testers got their best 3D scenes by generating concept art first, then asking the model to match it in code.
  • map
    Area by area with an evaluation listMatt Shumer's Manhattan build worked district by district, refining each against a checklist before moving on. His Gauntlet Loop adds a separate harsh critic per piece.
  • groups
    Cheap builder, strong criticclaude-code-game-builder runs Sonnet 5.5 as the builder and Opus 5.5 as a blind critic that compares unlabelled pairs against the reference.
  • travel_explore
    One sentence plus researchSingle-sentence Opus 5.5 game prompts worked when the model researched the real map layout and the original controls before writing code. Opus 5.5 demo list
  • crop
    Give it a crop toolFor dense screenshots, charts and UV layouts, a crop or zoom tool beat raw effort in Anthropic's Sonnet 5.5 tests.
  • sports_esports
    The one-shot game checklistTheo's widely shared brief asks for a readable objective, responsive controls, coherent levels, hazards, feedback, scoring, restart and performance safeguards. awesome-astra-prompts

Traps and what to write instead

warningMost bad outputs trace back to one of these thirty-eight lines.
You wroteWhy it misfiresWrite this
"Make it AAA / Unreal quality"No observable criteria, so it cannot tell when it has arrived.Three things you would see in a screenshot, plus a frame budget.
"Avoid a generic AI look"Swaps one default style for another."Do not use [glass HUD cards framing the view, purple-pink gradients, cream and terracotta menus, tracked capitals with trailing arrows, glow on everything]."
"Think step by step" / "think hard"Opus 5.5 always thinks. Asking it to write out its reasoning can be declined as reasoning_extraction.Set effort. To read the reasoning, set display: "summarized". On Sonnet 5.5 at low or medium, "Think the problem through before you answer" is the documented exception.
"Iterate until perfect"No stopping point, so it either stops early or polishes forever.A numeric stop, a turn cap, and what to report.
"Use max effort, it's a hard one"On a single-file visual build, Opus 5.5 and Sonnet 5.5 at max can spend the whole 128k output budget thinking and return nothing.Cap visual one-shots at xhigh, set a large max_tokens, and treat stop_reason: "max_tokens" as a failed run.
"Use the best libraries" + "no external requests"Contradictory unless you say how assets arrive."Inline the build of X, generate textures in code, no CDN at runtime."
Adding features mid-runEach one is free until the page stutters."Any new effect must fit inside the current 14 ms frame budget."
"Grab some free models online"Non-commercial, editorial or unlicensed files slip in, and nobody can trace them later."CC0 first, CC-BY with CREDITS.md, never NC. Log URL, licence and hash per file."
"Model it from this concept art"Proportions measured off perspective art drift, and detail hides the drift.Orthographic views for measurement, silhouette gates before any detail.
"Add a cool spell effect"You get a core and some sparks. No beats, no depth, no weight.Name the beats, the layers per beat and a draw-call budget.
"Make the sound punchy"The model cannot hear its output, so it guesses.Envelope in ms, then an offline render with peak, loudness and a spectrogram.
"Build a big, detailed level"Art before play, real-world scale, dead-end trees of rooms, and nobody walks it.Beats, metrics from the controller, a layout graph with a loop, grey blockout, reachability checks, then art.
"Double-check everything" or "use a subagent to verify"Opus 5.5 and Sonnet 5.5 already check their work, so this adds cost, not accuracy. Sonnet at xhigh or max may add review rounds on its own.Name the checks once (frames, console, seam, soak test) and the completion condition. Use a critic only for taste, blind, against a reference.
"Take a screenshot to confirm it works"A frame that is not blank proves pixels arrived, not that the scene is right. Hidden tabs and unsettled exposure make it worse.Freeze state through test hooks, warm up, capture, then check a stated claim against a reference or a number.
"Use the best model available"The agent picks from memory: a retired model, a non-commercial checkpoint, or an unbudgeted API loop.Ask the route, use the named pick for it, confirm the id from the provider list, cap spend, and log terms and cost per file.
"Use the newest version"Newer releases can carry stricter licences or ship API only. Qwen-Image 2.1 went non-commercial where 2512 was Apache 2.0.Pin model and version, read the LICENSE file at download, and log both in the manifest.
"Use Depth Anything 3"One family, two licences. DA3-LARGE and GIANT are non-commercial, while Mono-Large, Metric-Large, Base and Small are Apache 2.0.Name the exact checkpoint and log its licence. A model family is not a licence.
"Make it in Unity" or "Use Unreal, it looks AAA"The agent cannot see the editor. Binary assets and editor-only steps break its build, run and look loop, and the licence changes with revenue.Pick by target platform and by what the agent can build, test and screenshot from a terminal. Name the version and the CLI or MCP route.
"Generate a 12-frame sprite sheet"One image holding a whole grid drifts identity, overlaps poses and falls off the grid. Longer rows add duplicates, not in-betweens.One row per state at 4 to 6 frames, or animate one still with a video model, find the loop, and pack with a manifest.
"Mirror it for the left-facing sprites"A sword, watch or logo on one side swaps hands, and any lettering reads backwards.Mirror only symmetric characters. Draw the left-facing views for anything one-sided and check each item's side.
"Make a showreel, go all out"It tests the engine, not an idea. Many people reused the same line, so the results rhyme.Add a reference, a story or a state list, and a critique loop that scores frames before the full render.
"Narrate this video"The voiceover drifts into the model's tics: short punchy sentences and stacks of numbers.Give the narrator a persona and pace, and have a critic compare the transcript with the script.
"Auto-rig the character"Learned riggers get the body mostly right and break at fingers, shoulders and clothing, and nobody checks.Auto-rig as a first pass, then weight gates and an extreme-pose sheet, with Rigify as the fallback.
"Keep the character consistent"Adjectives pile up and the face still drifts.Climb the ladder: reference, style reference, control map, LoRA. Keep the baseline prompt byte-identical.
"Put the title in the image"Garbled or restyled lettering baked into the art.Leave a quiet zone and set every word in code.
"Build it from scratch"A hand-rolled camera, particle system or controller with the bugs a library fixed years ago.Name the library to start from (see each section's reuse list), pin the version, log the licence.
"Make a fun game"Feature lists with no loop, and nobody decides what fun means.A fun target from MDA, a one-sentence core loop, three grey prototypes, bot and human playtests.
"Draw a nice illustration"Centred clip art with outlines and a purple gradient.Composition on thirds, a palette with roles, value pass first, and a render the model looks at.
"Make it look amazing"No reference, so the model picks its default style and hue-only contrast.A reference board, a style frame, a palette with roles and greyscale checks.
"Use physics for the player"A dynamic body that tips, slides and changes with frame rate.A kinematic controller on a fixed timestep, jump set by height and time to apex.
"Make it run faster"Guessing, so effort goes into the wrong cost.A benchmark path, p95 frame time, one change at a time, before and after numbers.
"Add bloom"One NaN pixel from a bad normal or Fresnel term spreads through the bloom blur into a black block, and it may show only after deploy.Clamp non-finite pixels before bloom, fix the source term, and soak-test long enough to cross a day-night cycle.
"Make the enemies smart"You get perfect aim, instant detection and no way to tell why they act.Name the decision model and states, add perception limits, a telegraph, barks and a debug overlay.
"Generate infinite random levels"Unseeded, unvalidated, and every output feels the same.Seeded PRNG, structure before geometry, reject-and-regenerate checks, and a contact sheet of many seeds.
"Make it feel juicy"Every effect at maximum on every event, nothing stands out, and there is no off switch.A feedback list per event, intensity scaling, starting numbers, and reduce-shake and reduce-flash toggles.
"Use a tween library for the shake"It runs on its own clock and ignores pause, hitstop and slow motion.Springs and trauma inside the fixed timestep, or drive the tween engine from the game loop.
"Screen-record the animation to MP4"Busy machines drop and repeat frames, and audio drifts.Seek every frame (HyperFrames, Remotion, or a seek(t) page), then encode.
Pasting someone's prompt as contextInstructions inside pasted text can get followed.Wrap it in tags and say which parts to borrow.

Prompt builder

buildFill in what you know. The builder writes the layers in the right order and marks what is still missing.
Your prompt

Pre-send checklist

checklistThe first twelve apply to every brief. The rest apply when the brief includes that kind of work. Your ticks are saved in this browser.
0 of 25

    Sources

    Copied