seedance-anime-drama: anime storyboard shots with image-based character consistency
Turns one shot — or a short sequence — of a novel/script excerpt into an anime-style video clip, using an image of the character as the frame each shot starts from, not just a repeated text description.
This is the first scenario skill in this repo that orchestrates two execution-layer skills rather than one:
ofox-image-coregenerates the character as an image (text-to-image).ofox-video-coregenerates each shot, with that image passed in as--frame-first-image.
Neither core skill's request-building, error-mapping, or download/reporting logic is duplicated here — this skill owns only the anime-specific prompt craft, the pre-generation brief, the two-step orchestration order, and the two approvals. Read both core skills' safety contracts before using this one — neither is restated here.
Three shared references from ofox-video-core are load-bearing and are
linked, not copied:
../ofox-video-core/references/creative-brief.md— what to ask the user before a prompt exists: the three tiers, one round of at most four questions, the "Let the AI decide" discipline, the skip rows, and the anti-patterns. Read it before the brief section below, which adds this scenario's question set and the one axis a two-phase flow must settle before the first image is paid for.../ofox-video-core/references/prompt-structure.md— the vendor's formula, the header-manifest → timeline → closing-block skeleton, timestamp formats and segment lengths, transition and camera vocabularies, consistency locks and negative lists, the two meanings of an attached image, endings. Load it before writing a prompt; this file adds only what is specific to anime.../ofox-video-core/references/approval-gate.md— never spend before an approved cost table; this skill is its two-phase example.
The mechanism — the whole point of this skill
The character exists as an image before any video is paid for, and every
shot starts on an image of that character (--frame-first-image) rather
than on a description the model interprets fresh each time. That is what
separates this skill from seedance-short-drama's text-only consistency —
and it is available here because an anime character is not a photoreal
person, so Seedance 2.5's real-person refusal does not apply.
How many images that means depends on the shot count (the brief's first question, and Step 1):
- one shot — one opening frame, fed to that shot;
- several shots continuing one moment — one opening frame for the first
shot, then
chaincarries each job's closing frame into the next; - several shots cutting to new setups — one opening frame per shot,
written from the same character description word for word, each fed to its
own shot; by default a design sheet comes first and is shown to the user to
confirm the design (the brief's
Sheetquestion can skip it). The sheet itself never goes to--frame-first-image(see "Two different images, do not confuse them").
A second, different way for an image to enter a shot — as an identity
reference that locks no frame (input_references) — is described under "Two
ways an image can enter a shot". The two are mutually exclusive per job.
Before generating: two availability checks
Run each once per session (not on every request):
bash ../ofox-image-core/references/ofox-image.sh check
bash ../ofox-video-core/references/ofox-video.sh check
If either fails, follow that core skill's own guidance (install curl/jq,
or get an OFOX_API_KEY at https://app.ofox.ai) — don't dead-end the
conversation, and don't re-run either check on every subsequent request once
both have passed.
Shots, cuts and jobs
One job is one clip of 4–30 seconds, and a clip can hold several shots joined by hard cuts. The gallery's animation prompts do this routinely — case 11 asks for ten shots in 24s, case 18 for eight segments in 30s, official case 29 for four shots in 15s. Write the timestamps as cut boundaries and keep 2–5 seconds per shot.
The measured envelope is up to 10 shots in 30 seconds, and separately
up to 6 hard cuts among one job's boundaries, at 480p and 720p, with cuts
landing within about ±1.5 seconds of their stamps. Job ids and the frame-by-frame readings are
under "Several shots in one job" in
../ofox-video-core/references/prompt-structure.md.
The item that used to matter most here is now closed: a multi-cut job
that also carries a --frame-first-image — this skill's normal shape — has
been run twice, at 15s/5 shots/4 cuts and 20s/7 shots/6 cuts (jobs
7ae7d49e-7eb9-4165-9d95-09cd525d53ed and
ac927785-92ef-4e28-97b9-ff8172ec5554, both seedance-ad-creative product
clips). Every cut happened and the attached frame held across all of them,
so the two do not trade off. What still has no measurement in this skill's
own shape is a multi-cut job on an anime frame — the frame-lock run here
was a single continuous take (16023efe-48d6-45fe-8fd8-f5c6fbfe6519) — but
the mechanism is the same, and the remaining gap is the art style, not the
cutting. Past 10 shots or 6 hard cuts, or at 1080p, treat a first attempt as
an experiment and price it as one.
One warning that comes with the one-take run: 16023efe was rejected for
being static — a 20-second single take whose only movement was a very slow
push. If you pick one shot, make the camera cross space; the measurement
is under "Shot density, measured per case" in the shared file.
Three ways to lay a sequence out, and they compose:
| Route | What it gives | When |
|---|---|---|
| Timestamped shots inside one job | several cuts; one approval; one bill | the sequence fits in 30s and one seed and resolution suit every shot |
chain (ofox-video-core) |
each job's closing frame becomes the next job's opening frame; the results are joined into one file | consecutive shots that continue one moment; sequences past 30s; each shot priced and approved on its own |
Separate generate calls |
independent jobs | shots that cut to unrelated setups, each started from its own opening frame (Step 1) |
chain works in this scenario, and that is not a given: Seedance 2.5
image-to-video refuses frames containing a real person, so a live-action
sequence cannot be chained, but an anime character is not a photoreal person.
Continuity is strong on the run ofox-video-core recorded — the next shot
opens on very nearly the frame it was fed, then follows its own prompt (that
run was a static object, not a character).
Shot count is the user's call, not the skill's — it is the brief's must-ask question, because it decides how many images and how many approvals follow.
Before writing the prompt: the creative brief
The shared rules are in
../ofox-video-core/references/creative-brief.md
— the three tiers, the one-round limit, the shape of a question, the "Let the
AI decide" discipline, the generic skip rows, the order with the approval
gate, the fallback for a runtime without AskUserQuestion, and the
anti-patterns. Read it before writing a prompt. This section adds only what
is specific to anime — including this scenario's instance of the shared
file's last anti-pattern, an axis a paid step freezes: the aspect ratio has
to be settled before the image is paid for.
Read the user's message and attachments first, and mark every axis of the clip settled or open. Zero questions is common here: "just this one shot, 9:16, in a 90s hand-drawn look, keep her lines" has settled every axis — write the prompt.
| Tier | Anime axes |
|---|---|
| must-ask | how many shots this round; the aspect ratio before any image exists (the clip's shape follows the image); whether a character image the request implies actually exists |
| ask-if-open | the animation look; dialogue or no dialogue |
| never-ask | resolution, video model, image model, provider, duration once stated |
The anime questions
| # | Tier | Header | Question | Options — first is recommended; "Let the AI decide" comes last wherever it appears, and never on a must-ask row | Ask when |
|---|---|---|---|---|---|
| 1 | must-ask | Shots |
How many shots this round? Each shot is a video job, and several shots also mean several opening frames. | One shot first (recommended) — see the character move before committing to a sequence / <N> shots — one row per shot in Approval 2; timestamped inside one job when they fit in 30s, otherwise chain or separate jobs / Not sure — propose one — the agent names N with the per-shot price and says why. This is not a "Let the AI decide" option: a must-ask axis never gets one, and the proposed count is only settled by the user's yes on Approval 2's rows |
No shot count in the input. "Just this one shot" / "these three beats": skip. |
| 2 | must-ask | Aspect |
The clip's shape follows the image (adaptive), so the image has to be made at the target ratio. Where will it be watched? | 9:16 vertical (recommended) — mobile feeds / 16:9 landscape — web, YouTube; the gallery's anime cases that state a ratio are 16:9 (cases 9, 18, 44) / 1:1 square — grid feeds |
No platform word and no ratio. Before Approval 1, and with no "Let the AI decide" — this is the axis a paid image freezes, so it is the one thing a blanket "you decide" does not cover. If the user still declines to choose, take 9:16, mark it (AI's pick) in the recap, and say in the same message that changing it later means paying for a second image. |
| 3 | ask-if-open | Style |
Which animation look? It goes into the image and into every shot. | Modern theatrical cel-shaded (recommended) — clean line, flat vibrant colour, soft glow; the safest match for a contemporary excerpt, and the closest to the gallery's cel-shaded hybrid (case 18) / Hand-drawn 90s TV anime — fine ink lines, dramatic shadow, soft VHS grain, teal-and-orange (case 61) / 3D-stylised anime — rounded appealing designs, sparkle and particle glow (case 10); swap in Pixel 8-bit (case 29) or American retro cartoon, halftone dots (case 11) when the story suggests it / Let the AI decide |
No style word in the input. No school dominates the gallery — the recommendation is a convention, not a measured winner. |
| 4 | follow-up | Sheet |
Several shots — confirm the design on a sheet before the opening frames? | Sheet first (recommended) — one extra image; catches a wrong design before N frames and N shots are paid / Straight to shot 1's opening frame — later frames copy its description word for word / I have a character image — give the path |
Only when Q1 answered several shots. |
| 5 | ask-if-open | Sound |
Lines, or ambience only? | Dialogue in the excerpt's language (recommended) / No dialogue — ambience and keyed sound effects, with any score added afterwards in an editor / Let the AI decide. Neither option asks the model to generate music: that has failed output moderation on audio copyright here (unbilled) |
Only when the excerpt is narration without quoted speech. Quoted lines present: dialogue on, no question. |
If more than four are open, ask Shots, Aspect, Style, Sound; Sheet
is the follow-up. Never asked: the language of the lines, resolution, video
or image model, provider — all rows in the tables.
Skip rows specific to anime
On top of the generic rows in creative-brief.md:
| Signal in the input | Axis | Value |
|---|---|---|
| A style word — "90s anime", "like Ghibli", "pixel", "Saturday-morning cartoon", "cel-shaded" | style | map to the nearest school in the Style options; do not ask |
| Quoted speech in the excerpt | sound | dialogue on, in the excerpt's language — the language is never asked; see "Prompt language follows the audio" |
| A character image attached | asset question | settled: skip the sheet, the image is the design; see "Two ways an image can enter a shot" for which route it takes |
Every answer lands somewhere
| Answer | Where it goes |
|---|---|
| Shots | the number of video jobs and of rows in Approval 2; whether a sheet is generated |
| Aspect | the image is generated (or cropped/padded) at that ratio; the video inherits it through adaptive |
| Style | the style sandwich — first sentence, STYLE block, closing quality line — in the image prompt and every shot prompt |
| Sheet | the shape of Step 1: sheet first, or straight to shot 1's opening frame |
| Sound | the AUDIO block, and --generate-audio |
Where the brief sits in the two-phase flow
This scenario pays twice, so the shared order runs once per phase:
read input → fill the brief → [open axes] one AskUserQuestion (Shots, Aspect, Style, Sound)
→ [Shots = several] one follow-up (Sheet)
→ write the image prompt → image --dry-run
→ one message: brief recap (AI's picks and inferred values marked) + image prompt + Approval 1 table, with the phase-2 preview
→ wait for an explicit yes → generate the image → show IMAGE_PATH
(the second participation point: the user may send the design back here — that is a revision, not a new question round)
→ write the shot prompt → video --dry-run
→ one message: recap carried over + full shot prompt + Approval 2 table
→ wait for an explicit yes → generate → report the real bill
Everything that must be settled before an image exists — aspect ratio, style, shot count — is asked before Approval 1; the ratio is must-ask for a mechanical reason, not a matter of taste ("The opening frame decides the output's shape"). Nothing is asked between Approval 1 and the image; the image itself is the question.
The recap, in the same message as the table:
Brief
- Shots: one shot first (your choice)
- Aspect: 9:16 (inferred from "for Reels") — the image will be generated at 9:16
- Style: hand-drawn 90s TV anime, fine ink lines, soft VHS grain (AI's pick)
- Sound: dialogue in Japanese, as written in the excerpt (inferred from the quoted lines)
- Image: quality high, chain default model — row 1; video 8s 720p — row 2 (defaults)
Prompt template
Load these sections of ../ofox-video-core/references/prompt-structure.md
first: "Prompt skeleton: header manifest, timeline, closing block",
"Segmenting the timeline", "Transitions", "Camera language", "Pacing",
"Consistency locks and the negative list", "Dialogue and sound", "Reference
assets as visual anchors", "Endings". The vocabulary lives there and is not
repeated. What follows is the anime shape laid over that skeleton.
Four subsections in those pages carry most of what makes a fight or an action
beat read, and all four are measured on this skill's own jobs: "The cause
chain" (inside "Segmenting the timeline"), "Rules that travel with the
vocabulary" (inside "Camera language"), "What a prohibition cannot buy:
timing and behaviour", and "The plastic look is designed out, not
forbidden" (the last two both inside "Consistency locks and the negative
list"). The plastic-look one matters here even though nothing in this scenario
is photoreal — for animation the plastic read is the 3D-CG read, and the positive
form is drawing vocabulary rather than a longer AVOID list.
Gallery evidence for the shape: all eight animation-adjacent prompts (cases 9, 10, 11, 18, 29, 44, 61, 63) name their style school in the first sentence; five of the eight are timestamped; seven carry a negative list; the two fight scenes (11, 44) share a cause-chain rule; four layer an analogue texture (VHS grain, 35mm colours, 90s imperfections) over the school. Case 44 is in that set for its continuity and cause-chain writing, not its look — it asks for live action and forbids 3D and game CG outright. Chinese-language cases are quoted in translation.
15–30 seconds: a manifest and timestamped segments
Slots in <angle brackets>; optional lines in [square brackets]. Two to
five seconds per shot for action, six to nine for a held emotional beat. As a
count rather than a length: this category's densest collected prompt is case
11 at 10 shots in 24 seconds (2.4s each), case 18 runs 8 in 30s, and case
9's shot chain is six sizes in 30s — while the worked example below, adapted
from case 10, is the quiet end at four segments in 30s. Both ends are real;
the per-case measurements are in "Shot density, measured per case" in the
shared file. An action or fight beat written as four 7-second segments is
below every action prompt in the gallery.
[FORMAT: <ratio>, <T> seconds, <N shots, hard cuts on the timestamps | one continuous shot>] — optional; must match the flags
STYLE: <school: cel-shaded modern theatrical anime | hand-drawn 90s TV anime, fine ink lines | 3D-stylised anime, rounded appealing designs | pixel 8-bit | 1969 American TV cartoon, thick outlines, halftone dots>, <texture layer: soft VHS grain | faded 35mm colours, gate weave | none>, <light: golden hour | neon | teal-and-orange | flat overcast>.
[image1 provides <tag>'s identity only: face, <hair>, <signature accessory>, <outfit>. Ignore its background and pose.] — identity-reference route only; omit when the shot starts on a frame
<TAG>: <age range, build>, <eyes>, <hair colour + style + signature accessory>, <clothing item by item, colours>, <bearing>. Referred to as "<tag>".
SCENE: <place, time, weather, light, palette>.
[CONTINUITY (sequel): the same <tag> as in PART 1. The first frame continues PART 1's final image exactly: <position, pose, action in progress>. No re-positioning, no re-facing, no slow preparation — the action continues on frame one.]
RULES — action: each shot is one continuous camera take, no jump to a new position inside a shot. Every strike runs visible target → body entry → strike motion → clear contact → immediate body reaction → balance change → next action; no reaction before contact; no effects in place of body motion. Effects allowed: SPEED LINES, SMEAR FRAME, IMPACT BURST, SHOCKWAVE RING, WOBBLE LINES — sparingly, only on <the decisive hits>. Onomatopoeia allowed: THWACK! POW! WHAM! — only on those.
RULES — quiet: one action per segment, long enough to read. No fast cutting, no time-lapse, no jump cuts.
[<segment title>, 0–<a>s] <shot size, camera position, movement>. <tag> <action A → B → C>. <the environment answers: petals lift, the light brightens>. [<Tag>: "<line>"]
<TRANSITION — name a kind on purpose; a hard cut is one of nine, and an unnamed boundary becomes one by default: HARD CUT. | Without cutting, <a sleeve / a banner / a passing body> sweeps across the lens and the camera comes out of the occlusion on <the next view>. | Without cutting, the camera pushes through <the doorway / the torii / the gap in the hedge> into <the next space>. | <an element inside the frame moves and carries the change — case 29's four shots inside one declared continuous take>. | <a speed ramp past the lens into the next beat — case 11>. | Without cutting, …>
[<segment title>, <a>–<b>s] … (each segment raises the stakes or the feeling one step)
[Ending, <x>–<T>s] <terminal pose: faces the lens | freeze | slow pull-back to a wide | arm raised>; hold one second.
AUDIO: <ambience> / <character sounds with a qualifier: laughter (pure joy, not mocking)> / <keyed sfx> / <what remains at the end> — or: No BGM, no narration, no subtitles. <Music only if the user accepts the risk: a prompt asking the model for a scored cue has failed `output_moderation_failed` on audio copyright, unbilled — see "Asking for music can fail output moderation on copyright" in the shared file.>
CONSISTENCY: <tag>'s face, facial proportions, skin tone, body type, hairstyle and colour, <accessory>, <clothing items> identical in every shot; strictly no random character changes; never change the visual style.
AVOID: subtitles, watermarks, logos; fast cutting and jump cuts (quiet scenes); photorealism, 3D game CG, plastic skin <or whichever school you are not making>; identity drift.
<Closing quality line: restate the school, expressive facial animation, <camera texture>, character design consistent throughout.>
What each anime slot is for, and where it comes from:
| Slot | Why it is here | Cases |
|---|---|---|
Style sandwich — school in the first sentence, a STYLE block mid-prompt, a quality line at the end |
All eight open with their school; 9, 18, 61 and 29 close by restating it | 9, 10, 18, 61, 29 |
The schools seen (the Style question's vocabulary) |
dreamlike cinematic anime aesthetic … anime 3D-stylised (rounded, appealing designs) · modern retro-anime 3D cel-shaded hybrid … soft VHS grain, synthwave colour glow · hand-drawn Japanese anime, highly detailed ink lines, expressive eyes, dramatic shadows … the slight imperfections of 1990s animation · pixel wuxia, 8-bit · hand-drawn 2D character inspired by 1969 American TV cartoons … thick black outlines, halftone dots, print misregistration · painterly anime illustration, cel-and-gradient shading |
10, 18, 61, 29, 11, 34 |
| Cause chain (action) | The chain itself, its two attached prohibitions, and a frame-by-frame reading of it landing on a real job now live in "The cause chain: ordering what happens inside a segment" in ../ofox-video-core/references/prompt-structure.md — load it rather than re-deriving it here. Its short form: visible target → body entry → real strike motion → clear contact → immediate body reaction → balance change → next action |
44, 11; measured on c192dbe6 |
| Escalation curve | each segment title raises the stakes (REDIRECT → RUSH → PRESSURE WAVE → VORTEX BREAK → HYDRO DRILL → MAXIMUM FINISH); reactions grow louder after major punches; the heaviest effects only on the decisive blow |
44, 11 |
| Effects allow-list with a frequency rule | SPEED LINES, SMEAR FRAME, IMPACT BURST, IMPACT FLASH, SHOCKWAVE RING, WOBBLE LINES — use effects sparingly; onomatopoeia THWACK! POW! SMACK! WHAM! CRACK! |
11 |
| Terminal pose | the referee raises the arm; faces the lens, serious and resolute; freeze; slow pull-back showing how small she is | 11, 9, 10, 29 |
| Environment answers the emotion (quiet scenes) | the garden responds to her joy — the flowers glow brighter |
10 |
| One action per segment (quiet and process scenes) | Show only one salon action at a time … No fast cutting. No time-lapse. No jump cuts. |
18 |
| Consistency sentence with invariants | face, facial proportions, skin tone, body type, hairstyle, hair colour, all visible accessories, clothing; strictly no random character changes; keep the stylist and the customer consistent throughout |
44, 61, 18 |
| Sequel block | must be the same … continuing the fight from PART 1; PART 1's final frame re-described in words as this clip's first; no re-positioning, no re-facing, no slow preparation — the text-level complement to chain across sessions |
44 |
AUDIO block |
itemised: ambience / character sounds with a qualifier / keyed sfx / what remains at the end; or No BGM, no narration, no subtitles. The gallery's music lines (case 10's music box, case 11's score) are the one part not to copy — an ad prompt asking for a cello note and a bell chime failed output moderation on audio copyright here, unbilled |
10, 44, 11 |
AVOID |
subtitles, watermarks, logos; fast cutting, jump cuts; never make him realistic, no face swap, no AI plastic skin, no 3D, no game CG; random character changes |
18, 44, 61, 11 |
Choosing a transition, not defaulting to a cut
The shared "Transitions" section holds nine kinds with the phrasing to copy for each: hard cut; one continuous shot with cuts forbidden; occlusion; pass-through; morph; flash; match cut; speed ramp; narrative ordering words. Load it and pick one per boundary — animation is the category where the in-frame options are cheapest, because nothing has to stay photoreal across the change.
| Kind | Animation-adjacent cases |
|---|---|
| Hard cut | 18 (eight timestamped segments, while forbidding fast cutting and jump cuts), 11 (ten numbered shots), 63 (four scene stamps in about 8s) |
| One continuous shot, cuts forbidden | 29 (four shots declared as one continuous take), 44 (no jump cuts, no flicker) |
| Speed ramp | 11 (Return to normal speed as the human staggers backward) |
| Narrative ordering words | 9 (close-up → medium → tracking shot → low-angle foot shot → corridor wide → close-up) |
| Morph | 54, 13 — outside this category, but the mechanism is case 29's in-frame element move |
Occlusion, pass-through, flash and match cut have no animation instance among the 63; borrowing one is a deliberate choice rather than a documented convention, and the phrasing to borrow is in the shared table.
Worked example — adapted from case 10 (translated): 30 seconds, four segments, no dialogue
Case 10's own sound design is a music-box melody with strings and bells. This version keeps everything else and replaces the scored cue with diegetic sound only, because asking this model for music has failed output moderation on audio copyright here (unbilled; shared file, "Asking for music can fail output moderation on copyright"). A score can be laid over the delivered clip afterwards, which is where case 10's melody would have to come from anyway.
STYLE: dreamlike cinematic anime, 3D-stylised with rounded, appealing designs; continuous sparkle and magic particles; golden-hour light, warm palette, bright cheerful colour.
THE GIRL: early teens, small and light; large round amber eyes, a soft round face; chestnut hair in two low bunches tied with pale-yellow ribbons; a cream sundress with a sky-blue sash; open, delighted. Referred to as "the girl".
SCENE: a magic garden at golden hour — tall glowing flowers, drifting motes of light, soft grass, a distant hedge in haze.
RULES — quiet: one action per segment, long enough to read. No fast cutting, no time-lapse, no jump cuts. Single character, no dialogue.
[Opening, 0–6s] Wide shot of the garden, light motes hanging in the air. The girl sits alone on the grass, looks up at the sky, and a bright smile breaks. The camera slowly orbits her.
[Delight, 6–15s] Medium shot. She springs up and turns once with her arms out; the garden answers — the flowers glow brighter, petals lift and circle her. She laughs (pure joy, not mocking; subtle, not over the top). The camera follows her.
[Wonder, 15–24s] Close-up. A small glowing bird lands on her fingertip; she goes still, eyes wide, then breathes out a smile. Behind her the light deepens toward gold. The camera drifts in a few centimetres.
[Ending, 24–30s] The camera pulls back slowly, showing how small she is in the vast garden. Freeze on this moment of quiet joy.
AUDIO: petals rustling, grass under her feet, a faint chime as the flowers brighten / her laughter (pure joy) / the bird's small trill and wingbeat / at the end only a light breeze remains. No music, no score, no instruments, no humming, no singing.
CONSISTENCY: the girl's face, proportions, skin tone, hair bunches and ribbons, cream sundress and blue sash identical in every segment; strictly no random character changes; never change the visual style.
AVOID: subtitles, watermarks, logos; fast cutting, jump cuts; photorealism, game CG, plastic skin; identity drift.
Dreamlike cinematic anime, expressive facial animation, soft cinematic depth of field, character design consistent throughout.
8–15 seconds: one shot, starting on the frame
This is the prompt that goes with --frame-first-image: it opens on the
image, so the first sentence says so and the character block can be short —
the frame carries the design. No manifest; the vendor's formula order in
three or four sentences, and a one shot declaration so any beats read as
performance, not cuts.
Start exactly on the opening frame. <Tag>, <appearance in one clause>, <place and light>. <School>, <texture layer>.
One shot, <T> seconds. <Shot size and movement>. <Tag> <action A → B → C>; <the environment answers>. [<Tag>: "<line>" — <delivery>.]
<Ending: faces the lens | freeze | the camera settles>; hold one second.
AUDIO: <ambience> / <keyed sfx> / <what remains at the end> — no music, no score, no instruments. CONSISTENCY: <tag>'s face, hair, <accessory>, <outfit> unchanged. AVOID: subtitles, watermarks; <the school you are not making>; identity drift.
Adapted from case 10's opening (translated), 8 seconds, from an opening frame of the girl on the grass:
Start exactly on the opening frame. The girl — chestnut hair in two low bunches with pale-yellow ribbons, cream sundress, blue sash — sits alone on the grass of a magic garden at golden hour, light motes drifting. Dreamlike cinematic anime, 3D-stylised, rounded appealing designs, soft glow.
One shot, 8 seconds. Wide shot; the camera slowly orbits her a quarter turn. She looks up at the sky, a bright smile breaks, and the nearest flowers glow brighter in answer; two petals lift and drift past the lens.
The camera settles as the smile holds; hold one second.
AUDIO: petals rustling, grass shifting, a faint chime as the flowers brighten / no dialogue / no music, no score, no instruments. CONSISTENCY: her face, hair bunches, ribbons, sundress and sash unchanged. AVOID: subtitles, watermarks; photorealism, game CG; identity drift.
Step 1: generate the image the shot will actually start from
Extracting the character description is this skill's calling agent's own reasoning to do — not something a script performs. Read the user's story/script excerpt and write a precise, reusable character description covering:
- age and build
- hair (colour, length, style) and one signature accessory
- clothing (exact garments, colours)
- distinguishing features (scars, eye colour, etc.)
Carry the brief's Style answer — the school, its texture layer, its light —
into this prompt and into every shot prompt, so the image and the shots
stay consistent with each other, not just shot to shot.
Two different images, do not confuse them
--frame-first-image is the literal first frame of the video, not a
style hint. That makes the classic "character reference sheet" the wrong
thing to feed it:
| Image | What it is for | Prompt shape |
|---|---|---|
| Character sheet | Locking a design and showing it to the user before several shots are paid for | multi-view, labels, plain background |
| Opening frame | The frame the shot animates away from | one in-scene illustration, no text, no panels |
Asking for a "character reference sheet" gets you exactly that: a real
multi-panel sheet with front/side/back views, an expression row, a palette
swatch and printed labels — and models will happily invent a name and letter
it across the top. Fed to --frame-first-image, the clip opens on that
grid of thumbnails and text and animates out of it. Verified on a real
run: a sheet generated from that wording came back with four views, three
expressions, a colour palette and the caption "HANA TANAKA", and had to be
thrown away and regenerated as a single in-scene image.
So pick by the brief's Shots and Sheet answers:
One shot (the common case) — you need an opening frame, and nothing else. There is no second shot to stay consistent with, so a sheet buys nothing.
bash ../ofox-image-core/references/ofox-image.sh generate \
--prompt "<character description>, <the shot's opening moment: setting, pose, camera angle>, <school + texture layer from the brief>, <the brief's ratio as a composition instruction, e.g. vertical 9:16 composition>, cinematic composition, no text, no panels, single illustration" \
--quality high \
--target-aspect <the brief's ratio, e.g. 9:16> \
--out-dir <a directory for this project's generated assets>
The no text, no panels, single illustration tail is what keeps the model
from drifting back into sheet mode — it is not optional padding.
--target-aspect is not optional on an opening frame, and it is why the
hand-crop this section used to describe is gone. The ratio goes in the prompt
as a composition instruction because it changes how the character is framed
— but the delivered pixels are settled by the flag, which since
ofox-image-core 1.7.0 measures the written file and centre-crops it to
exactly that ratio, failing loudly rather than delivering something close.
The size enum this API accepts contains no 16:9 or 9:16 entry at all
(1792x1024 is 1.75, 1024x1792 is 0.5714), so the crop is structural, not
a fallback for a model that misbehaves — and an attached frame forces
aspect_ratio: adaptive, which means a wrong-ratio image is charged at the
price of the clip it opens. IMAGE_PATH is the cropped file, so Step 2
attaches it unchanged; the API's untouched bytes stay alongside as
IMAGE_PATH_UNCROPPED. Needs ffmpeg/ffprobe, checked before anything is
spent. Detail: ofox-image-core's "The size enum cannot express 16:9 or
9:16".
Several shots, Sheet first — generate the sheet once, show it to the
user, and get the design confirmed. Then write each shot's own opening
frame with the exact same character description, and feed each shot its
own frame. The sheet is a checking artifact; it is never passed to
--frame-first-image.
bash ../ofox-image-core/references/ofox-image.sh generate \
--prompt "<character description>, <school + texture layer>, character reference sheet, plain neutral background, front-facing full body" \
--quality medium \
--out-dir <a directory for this project's generated assets>
Why the two commands pass different --quality values. The opening frame
is the clip's first frame, so its fidelity carries into the deliverable —
high is what the one real run of this step used. A sheet is a checking
artifact that never reaches a video and is discarded once the design is
confirmed, so medium is enough for a human to read a wrong wardrobe or a
missing accessory off it.
The sheet command also passes no --target-aspect, and that is deliberate
rather than an omission: the sheet is never attached to a video job, so its
ratio decides nothing. The flag is mandatory only where the frame's ratio
becomes a clip's ratio.
Neither is standard, which this skill passed until 1.9.1 and which the
chain's current head refuses outright: openai/gpt-image-2 accepts only
low, medium, high and auto — its own enumeration, read off an HTTP
400 on 2026-09-04, Invalid value: 'standard'. Supported values are: 'low', 'medium', 'high', and 'auto', nothing billed. Since ofox-image-core 1.7.0
that combination is rejected locally instead, exit 1 with no network call,
so a --dry-run catches it for free. That is not a change in this skill —
microsoft/mai-image-2.5-flash accepts standard, and these commands worked
verbatim until ofox-image-core made gpt-image-2 the chain head on
2026-09-04. Pass one of the four accepted values, or pin --model microsoft/mai-image-2.5-flash when that model's look is what you want.
Costs, and which of them is measured, are in Approval 1 below.
Several shots, Straight to shot 1 — generate shot 1's opening frame as
in the one-shot case, show it, and write the later frames from the same
description. When consecutive shots continue one moment, only the first needs
a frame at all — chain carries the rest.
I have a character image — the user's file is the design. Whether it
becomes an opening frame or an identity reference is the next subsection.
The opening frame decides the output's shape
bytedance/seedance-2.5 forces aspect_ratio: adaptive whenever an image is
attached, so the clip comes out at the image's aspect ratio, whatever
--aspect-ratio says. That is why the brief asks for the ratio before
Approval 1: the image has to be delivered at the target shape, which is what
--target-aspect on the Step 1 command is for. There is no video flag that
fixes it afterwards, and fixing it by regenerating is a second image bill —
followed by a second video bill, since the clip already came out the wrong
shape. A user-supplied image is the one case you crop yourself, and it is
cropping only, never padding.
Don't pass --model here. ofox-image-core resolves one from its
cheapest-first priority chain — defined in exactly one place, its
MODEL_CHAIN — and prints the id it settled on, before it prints any
estimate. Pass --model only when the user named a model themselves.
This skill used to hardcode google/gemini-3.1-flash-image, the
sixth-cheapest image model Ofox serves and 2.3x the chain's preferred rate,
with no recorded reason for the choice. That is what a scenario skill holding
its own model id buys you: prices move, the copy doesn't, and nobody notices
because nothing is wrong — it just costs more than it needs to.
Whichever model runs, don't promise the user a specific output resolution,
and don't trust the printed SIZE line for the ratio. Since
ofox-image-core 1.7.0 you do not have to do the measure-and-crop by hand
either — --target-aspect, on every command above, measures the written file
and crops it — but the underlying mess is worth knowing, because it is what
the flag exists to absorb and what SIZE_ACTUAL in the output reports.
How far off SIZE lands depends on which model the chain resolved, and
both cases are measured:
microsoft/mai-image-2.5-flash, the chain's head until 2026-09-04, on three runs whose frames then went into video: a request for1792x1024came back with the API reporting1354x774while the file on disk was1344x768— three numbers, none of them matching, all three times. Cropping that file to1344x756(cropping only, never padding, so nothing is invented at the edges) is what produced an exact1280x720clip; feeding it uncropped delivers 1.75:1, which then sits letterboxed in a 16:9 frame.openai/gpt-image-2, the head since then, on one run at the same requested size: the request, the response'sSIZEecho and the file's real pixels all read1792x1024. One run, so do not read it as a guarantee.
Honouring the request is not the same as a usable ratio, which is why the
crop step survives either way: 1792x1024 is 1.75, not 16:9, so that frame
still had to be cropped to 1792x1008 before it was attached. The size enum
has no 16:9 or 9:16 entry on any model, so no --size value avoids it. Read
SIZE_ACTUAL rather than SIZE, and if you are cropping by hand for some
reason, use sips -g pixelWidth -g pixelHeight <file> or
identify <file> — cropping only, never padding. More in the failure table's
SIZE row and in ofox-image-core's "The size enum cannot express 16:9 or
9:16".
The video that came out of the first bullet's 1344x756 crop is also the
proof the lock works: job
16023efe-48d6-45fe-8fd8-f5c6fbfe6519's first delivered frame
matched the fed image on composition, both characters, wardrobe, the fence,
the sunset and the falling petals — and the two later product jobs show the
lock holding for a full 20 seconds and across six hard cuts ("What a frame
lock actually holds, measured" in the shared file). This is what
--frame-first-image buys over a repeated text description.
Take the printed IMAGE_PATH (an absolute path) and show it to the user
as its own standalone line — say whether it is the shot's opening frame or
a design sheet, since those get used differently. ofox-image.sh also prints
IMAGE_COST; relay it the same way you relay a video's cost.
Show the image to the user before spending on the shot. A wrong opening fr
…(truncated)