Skip to main content
Multi-scene games need the same character to show up in scene after scene. The world model carries a character’s identity in pixels, not prose: if the character appears in a scene’s seed image, the model holds them steady. So the way to keep a protagonist consistent across levels is to generate each new scene’s seed from a reference image of that character, not from prose alone. Character coherence is the same idea under a different name — this guide uses “character consistency” and “character coherence” interchangeably. This is exactly what the hand-authored worlds do by hand — the Stormcaller tutorial→fight seed reuses the same knight image so the character doesn’t change between scenes. The subject_ref + /scenes API automates it, and the same mechanism threads through book-to-game chapters.
subject_ref is the pixel counterpart of a world’s prose subject lock. Canonical references work best as rear or three-quarter views — the rear-chase camera hides faces, so identity rides on hair, build and clothing.

Define the character once

Create a world with a subject_ref — either an inline image (image_b64) or an already-hosted image_url, plus an optional prose descriptor. The opening seed is painted from the character, and the reference is stored on the world as subjectRef { imageUrl, descriptor } for every later scene to reuse.
An image_b64 is hosted to a durable URL before the world is stored, so no inline blob is ever persisted. image_url must be an already-hosted URL: a data: URI is rejected 400 (host it first, or send the bytes as image_b64), and if a supplied image_b64 cannot be hosted the request fails closed with 502 — no world is created rather than one that silently dropped the reference you paid for.

Pin a specific seed frame

subject_ref locks who is in the scene; frame_url locks what the opening frame is. Pass an already-hosted image as frame_url (or inline bytes as frame_b64) on POST /v1/worlds and the world boots from that exact frame instead of one the model paints from the premise. Combine the two — a pinned opening frame plus a subject_ref — and the character rides in coherent from the very first frame and stays that way scene-to-scene. This is the trick the hand-authored Stormcaller world pulls off by hand: a deliberately chosen entrance frame with the same knight, reused so nothing drifts.
Pass frame_url as an already-hosted, fetchable image URL — it becomes the world’s opening seed, so the model must be able to load it. To send raw bytes instead, use frame_b64.
Don’t have a frame yet? POST /v1/seed-frame paints one from a prompt and returns a hosted url you can hand straight back as frame_url — the supported way to author a deliberate opening frame without leaving the API.

Generate the next scene with the same character

POST /v1/worlds/{id}/scenes reads the stored subjectRef and paints a new seed from it plus your scene prose. The result is a hosted image; with pin:true it also becomes the world’s entrance seed (a versioned set_entrance write that keeps the current entrance state).
The scene prose is the “new scene” description; the character rides in from the reference pixels. The descriptor reinforces identity in words and defaults to the world’s subject when the reference has none. /scenes is metered image (reserve-before-spend, fail-closed); a pin failure still returns the generated image so a paid render is never lost. A world with no stored subject_ref returns 404 — attach one first (below).

Attach or rotate a character later

Already have a world without a character, or want to swap it? Use the set_subject_ref batch op — metadata-only, no re-generation:
After the attach, POST /v1/worlds/{id}/scenes works on that world. The create-time subject_ref field and the set_subject_ref op are the two write surfaces for the reference, and they agree: both take a hosted imageUrl/image_url and both reject data: URIs.

Status codes