Some wilds.ai games are not just narrated by an AI. they ARE the AI. their entire React component tree, gameplay loop, enemy AI, bullet patterns, and HUD are written by an LLM agent in response to your prompt. We call these **AI-built games** (internally: "vibe-coded"). This guide explains how they work, what the AI can compose with, and how to read your bundle's quality verdict.Some wilds.ai games are not just narrated by an AI. they ARE the AI. their entire React component tree, gameplay loop, enemy AI, bullet patterns, and HUD are written by an LLM agent in response to your prompt. We call these AI-built gamesAI-built games (internally: "vibe-coded"). This guide explains how they work, what the AI can compose with, and how to read your bundle's quality verdict.
When the AI runs, by family. Narrative, TTRPG, visual-novel, and crawler games stream new AI-written prose every turn — the LLM is in the loop as you play. Arcade, platformer, roguelike, board-game, survival, realtime-3D, and strategy-sim games are AI-built once at compile time and run as deterministic engines after. Every level, enemy, backdrop, palette, and asset is picked when the world is generated, then locked in for replays. That's why arcade games run at a smooth 60fps without a "thinking…" delay between actions, while narrative games can take a moment to write the next paragraph. Optional AI enhancement layers on classic and retro games — scene art, ambient music, voices, smart suggestions — run outside the game loop and are part of paid plans; they are off unless you turn them on, and the base game never waits on them.
#What "AI-built" actually means
When you create a world in a family that supports AI codegen (currently arcade, with platformer and realtime-3d in the pipeline), wilds.ai runs an agent loop that builds a working game bundle for you. The agent has tools to:
- Generate a top-level React component (the "entry component") that becomes your viewport.
- Generate bespoke TSX widgets used inside that component (custom HUD, particle effects, score panels).
- Compile the generated TSX through esbuild and report errors back so the agent can retry or remove broken imports.
- Run the bundle in a V8 sandbox for N simulated turns and read back state diffs.
- Score the bundle against playability tracks that check whether the game is actually playable.
- Decide whether to regenerate (with a patch hint) or finalize.
The agent exits when every launch-blocking track is GREEN and polish tracks are acceptable. The runtime then mounts the finalized bundle as your game viewport. nothing in the loop is a static template. every game is hand-written by the LLM against the prompt and judged for quality.
#The codegen loop in 6 steps
- Compile context. The orchestrator builds a system prompt with the blueprint, the family contract, the track contracts (what GREEN/YELLOW/RED look like), and the primitive library (next section). Capped under 10000 chars so per-step cost stays predictable.
- GenerateEntryComponent. For arcade family blueprints, the agent emits the top-level
ArcadeGameReact component. This is the viewport the runtime mounts. The agent can use@wilds/component-sdkhooks (useGameState,useGameAction) and import any primitive listed in the system prompt. - RunSandboxTest (game-script families only). For arcade entry-component bundles, GenerateEntryComponent itself performs the TSX compile gate. For templated families, RunSandboxTest compiles a deterministic GameScriptModule and simulates
turnCountturns (default 5), returning per-turn state diffs and any uncaught errors. - JudgeTextual. A judge model reads the runtime log and renders verdicts for every track. Stub-visual tracks auto-pass; real tracks get green/yellow/red with reasoning. The judge prompt embeds the per-track
intendedBehavior+examplePass+exampleFailso its verdicts are grounded. - ReadCurrentBundle. The agent can inspect current verdicts + cost + entry-component presence without re-testing. Used to decide the next move.
- FinalizeBundle. Signaled when every launch-blocking track is GREEN. The runtime persists the bundle and mounts it on next session start. If the agent exhausts its step budget without finalizing, the runner persists whatever it has — partial bundles can still play, they just may have unresolved YELLOW or RED tracks.
#The primitive library (14 families)
Rather than reinventing particle systems, camera math, enemy AI, and game loops every time, the AI composes from shipped primitives. Every family below is available in both render paths (Path B = iframe DOM/SVG, Path A = host R3F) unless noted.
#Visual atmosphere
- Sky (
@wilds/game-primitives/sky).<ProceduralSky2D biome="..." timeOfDay={0..24} />. 9 biome palettes (temperate-forest, arctic-tundra, desert-dunes, tropical-jungle, volcanic-archipelago, underwater-coral, alien-crystal, urban-rooftop, subterranean-cavern). Stars render automatically at night. - Weather (
/weather).<Weather2D mode="rain|snow|fog|lightning|storm|mist|dust|clear" intensity={0..1} />. Biome-tinted particles. - Volumetric clouds (
-r3d/clouds, Path A only).<VolumetricClouds coverage={0..1} timeOfDay={0..24} biome="..." />. Raymarched fragment shader on a sky-dome interior. Density floor per biome (volcanic has 0.15 haze, arctic has 0). - Terrain (
/terrain).<Terrain2D mode="parallax|heightmap" biome="..." />. Parallax mode: 5 layered SVG silhouettes auto-scrolling. Heightmap mode: Path A renders a real noise-displaced mesh; Path B falls back to a CSS-gradient ground.
#Effects + juice
- Particles (
/fx).<ParticleBurst2D x y count color />,<ParticleTrail2D />,<ParticleSparkle2D />. Burst = one-shot impact, trail = follow-projectile, sparkle = ambient depth. - Post-processing (
-r3d/postfx, Path A only).<PostFX bloom={0.4} vignette={0.3} grain={0.1} />. Bloom for energy, vignette for focus, grain for retro tone, chromatic aberration for analog feel. - Combat juice (
/juice).<ScreenShake2D>{children}</ScreenShake2D>provider +useCameraShake2D()+useHitStop2D()hooks. Shake on hit, brief frame freeze on impact, screen offset for weight.
#Gameplay AI
- Enemy archetypes (
/enemies).useChase2D/usePatrol2D/useOrbit2D/useFlee2D/useSwarm2Dhooks plus pure step functions (stepChaseetc.) in types. Cap swarm at ~30 agents; O(n) iteration. One movement primitive per agent. - Boss patterns (
/boss).useHealthPhases2D(HP threshold transitions) +useTelegraph2D(idle → charging → firing → recovering cycle) +useBulletPattern2D(spiral / radial / aimed / sweep / ring) +useBossFight2Dorchestrator composing all three. - Enemy spawner + bullet lifecycle (
/spawner).useEnemySpawner2Ddrives waves with gentle/medium/punishing curves or a custom(wave) => { count, speed, archetypes }function.useBulletLifecycle2Dfilters projectile arrays per frame by bounds + max-bullet cap + lifetime. - Behavior trees (
/behavior-tree). Full BT spec: Sequence + Selector + Parallel composites; Repeat / Invert / TimeLimit / RetryUntil / Succeeder / Failer decorators; Action / Condition / SetBlackboard / Wait leaves; Ref for sub-trees; tick budget cap of 256 visits per frame. 8 pre-built leaves (BTChase,BTPatrol,BTOrbit,BTFlee,BTSwarm,BTBossPhase,BTSpawnWave,BTWaitForHpThreshold) bridge to 1D-1F primitives via blackboard keys.
#Game systems
- Cameras (
/cameras). Path B:<FollowCamera2D>+<ParallaxScroll2D>+<ParallaxLayer2D>. Path A:<FirstPerson>/<Isometric>/<ThirdPerson>/<TopDown>R3F cameras. - Cursors (
/cursors). Path B:<CustomCursor2D>+<Reticle2D>+<HoverState2D>+useHoverable(id). Path A:<Crosshair3D>+<WorldCursor>+usePointerWorld. - Controllers (
/controllers). Platformer + FPS + third-person input controllers wired through@wilds/input(keyboard + gamepad + touch).
#The judge tracks (30+ per family)
Every AI-built bundle is scored on a checklist before it ships. Tracks have three severities:
- launch_blocking. Bundle does not finalize until this track is GREEN. Bugs, crashes, runaway loops, missing HUD.
- polish. Bundle can finalize with YELLOW or RED here, but the score is lower. Visual cohesion, juice, atmospheric depth.
- visual. Read from captured screenshots (in the visual-judge pipeline). Stub-passed when the visual judge is offline.
| Track | Severity | What it checks |
|---|---|---|
no_runtime_errors | launch_blocking | Compile succeeds + every simulated turn completes without uncaught errors |
hud_renders | launch_blocking | finalState is serializable and HUD visible in captured frame |
controls_intelligible | launch_blocking | Every enabled verb has a handler or visible affordance |
verb_manifest_consistent | polish (advisory) | Referenced platform verbs are a subset of the manifest + family baseline; extra affordances yellow but do not gate launch |
componenttree_valid | launch_blocking | Generated component tree validates; custom references resolve |
custom_components_compile | launch_blocking | Every generated custom TSX widget compiles cleanly |
style_scope_compiles | launch_blocking | Generated SCSS compiles into scoped CSS |
layout_legible | launch_blocking | HUD + controls + playfield readable, no overlap or clipping |
tree_no_infinite_loops | launch_blocking | BT ticks complete within the 256-visit budget; Repeat(-1) over always-success child trips RED |
palette_coheres | polish | Rendered palette matches blueprint style; no clashing colors |
control_affordances_visible | polish | Players can see what actions are available |
world_atmosphere_present | polish | Sky / weather / lighting matches declared biome + time-of-day |
weather_state_consistent | polish | Declared weather mode is stable across frames |
environment_depth_layers | polish | At least 2 depth cues present (fog falloff, parallax, particles, etc.) |
postfx_polish_applied | polish | Bloom / vignette / grain / color grading visible |
combat_juice_present | polish | Hits register with 2+ of: shake, hit-stop, particles, popup |
terrain_ground_consistent | polish | Ground surface visible and matches biome palette |
sky_atmosphere_coupled | polish | Sky + clouds + weather agree on biome + time-of-day |
enemy_movement_distinct | polish | 2+ enemy types use distinct archetypes |
enemy_difficulty_curve | polish | finalState shows wave/level counter + enemy stats scaling |
enemy_telegraphed_attacks | polish | Visible windup before damage applies |
enemy_spawn_pacing | polish | Waves arrive at clear intervals; difficulty scales |
bullets_culled_offscreen | polish | Bullet count stays bounded; no unbounded growth |
boss_distinct_phases | polish | Boss visibly changes behavior at HP thresholds |
boss_telegraph_clarity | polish | Boss attacks have readable charge → fire → recovery cycles |
boss_minion_summons | polish | Boss phases summon minion waves at transitions |
bullet_pattern_readable | polish | Bullets form geometric patterns (spiral, radial, aimed, sweep, ring) |
enemy_behavior_compounded | polish | Enemies exhibit multi-step behavior (chase → flee, patrol → attack) |
boss_phase_tree_transitions | polish | Boss BT switches sub-trees per phase visibly |
camera_modes_switch_cleanly | polish | Mode switches show valid framing without geometry clipping |
cursor_state_changes_on_hover | polish | Cursor variant changes when hovering interactables |
Track counts may drift as new primitive families ship. Your bundle's verdicts live on the play lobby page under "Build quality" once the loop finishes.
#Reading your bundle's status
After you submit a prompt, the codegen loop runs in the background. The lobby shows you:
- Build quality. A roll-up of every track's verdict (GREEN / YELLOW / RED). Launch-blocking failures explained inline.
- Iteration count. How many GenerateEntryComponent calls the agent made before finalizing or hitting its step budget.
- Total cost. Token spend across the loop. Typical arcade build is $0.10-0.30.
- Bundle revision. Each revision is a frozen snapshot. Rolling back to a prior revision is one click.
If a track is RED, the agent either retried (logs in the AI Codegen panel under "Iterations") or ran out of step budget. You can manually re-trigger the loop from the studio.
#Tips for prompts that vibe-code well
Be specific about genre + verbs. "An arcade shoot-em-up where you dodge spirals" gives the agent a clear archetype and tells it which primitives to reach for (useBulletPattern2D with pattern: 'spiral'). "Make me a cool game" gives it nothing to anchor on; the loop spends iterations exploring.
Name your enemies + bosses. "Crystal cultists swarm in clusters; a giant prism boss with three phases" is easier to vibe-code than "enemies attack". The agent can map "swarm" → useSwarm2D, "three phases" → 3 entries in bossFightConfig.phases.
Reference real games sparingly. "Like Geometry Wars but with biome-tinted particles" is fine. "Make me Geometry Wars exactly" is not — wilds.ai isn't trying to clone shipped games and the judge tracks penalize derivative work.
Declare biome + atmosphere upfront. volcanic-archipelago biome + storm weather mode → the loop knows to mount <VolumetricClouds coverage={0.8} /> with sulfur-tinted density floor. Vague atmospherics → loop picks defaults that may not match your vision.
Pick a difficulty curve preset in the prompt. "Gentle wave ramp for casual players" vs "punishing scaling, all 5 archetypes by wave 5" maps directly to useEnemySpawner2D({ curve: 'gentle' }) vs { curve: 'punishing' }. Custom curves are possible but presets cover 80% of cases.
Avoid telling the agent which primitives to use. "Use ParticleBurst2D for hit effects" is over-specified — the agent already knows the library. Describe what should happen ("hits explode in colored sparks"), not the implementation. The tracks check for the effect, not the technique.
#What you can't vibe-code (yet)
- Non-arcade families. Platformer, roguelike, realtime-3d, board game, ttrpg, narrative, survival, crawler, visual-novel families currently use templated game scripts or curated content. The codegen path opens up family-by-family as the orchestrator routes are wired.
- Multiplayer logic. The codegen loop generates single-player bundles. Multiplayer turn arbitration lives outside the bundle.
- Cross-session persistence. Generated bundles read from blueprint config but don't write to the world's canonical state. Player progress lives in session/character runtime rows, not in the bundle.
- Voice / TTS integration. The bundle renders the viewport; voice playback is the runtime's job.
#See also
- Retro mini-games — pico-8 / gameboy / c64 / arcade-cab themes plus the grid + paddle + endless-scroller + fruit-merge primitives for retro arcade prompts.
- Customizing an AI-built game — studio walkthrough for editing, rerolling, and forking
- Writing great prompts — prompt patterns for narrative AND arcade games
- Editing worlds in the creator studio — every panel, every field
The vibe-coding stack is the most active area of wilds.ai right now. New primitive families ship most weeks; the judge tracks tighten as we see real generated bundles. Watch this guide for updates.