series.json, the
series config, and epNN.md, the script. This document is the whole format. It is written to be
useful to a person, and to be pasted into an AI assistant’s instructions — prompts/ holds
generated copies for that.
The script and the series config describe the film, not a model. Each shot renders on a
video target (a model plus its ComfyUI workflow): MiniMax H3 Ref2VA unless the series
config, the script or the editor says otherwise. The build writes each target’s prompt for
you, from the same script. Sections that only hold for some targets say which.
Your first episode
Two files in one folder — andseriesmith new Shows\ep01 writes both of them for
you (so does New episode… in the editor’s project folders). This is what it writes,
and it is also examples/starter/, so you can read it before you run anything.
Shows\ep01\series.json first. audio.mode: generate means the model invents the
voices from each character’s voice line, so nothing has to be recorded first. The
pictures are named ../refs/..., one level up: that way every episode of the show
shares one refs folder while each keeps a series config of its own (a config in the
episode wins, the one beside it is the fallback), which is what lets episode four add
a character without touching the first three.
The folder can be called anything — ep01 here, but s2ep01, s3ep07 or pilot
just as well, which is how a show with seasons keeps them apart. Name the script
after the folder (s2ep01\s2ep01.md) and everything finds it: that is the only
name that still works when the episodes share one series.json in the folder above
them, and it is what lets seriesmith build Shows --each pick up every episode
under a show at once.
Shows\ep01\ep01.md:
seriesmith check Shows\ep01 and then seriesmith build Shows\ep01; INSTALL.md has the rest of the commands, and
docs/SCRIPT_CONVERSION.md works a real screenplay scene through to
shots if you are starting from one (the script-writing skill bundles it as
references/script_conversion.md).
The one thing that shapes every decision
A screenplay is read once, front to back, by someone who remembers. A shot list is consumed once per shot, independently, by a model with no memory. Shot 94 knows nothing about shot 93. So:- Every shot’s action must stand on its own. “He keeps walking” means nothing — write “Riley walks down the dirt path, already halfway along.”
- Never write “as before”, “same as the last shot”, “still holding the ball”. State it fresh or it does not exist.
- Character descriptions live in the series config, written once, injected into every prompt they appear in. Never repeat a character’s appearance in the script.
Choosing a video target
- Leave the target out unless the choice is a decision about the film. Shots with no
target:render on the episode’s target (set in the editor) or the series config’sseries.target, so a whole episode can be moved to another model without touching the script. - Name it (
target:on a shot, or under a#header for its sequence) when a shot needs something only one model does: a silent insert on Wan, a shot whose length you want LTX to choose (dur: model). Acontinuous: firstshot moves to H3 FL2VA by itself (see Continuous shots). - Dialogue needs a target with sound, and lip sync to a recording needs one of the H3
workflow targets (
minimax_h3_ref2va,minimax_h3_fl2va). Wan acts the lines silently. - On a target that takes no reference pictures (
ltx2,minimax_h3_fl2va,wan22_i2v,wan22_ti2v;wan22_vacetakes the sheets but not the plate), thedesignand locationdescriptionsentences are what the model knows about the look, apart from any keyframe. Keep them complete. - A keyframe is a picture: plan
first:/last:lines (see Keyframes) for the targets that read them.
seriesmith targets says
which ones your ComfyUI can render. A hosted model sends one call per take through Comfy
Router: its prompt is the same prose the LTX and Wan targets get, its seed is the
provider’s (reproducible: false), and seriesmith backends says whether this machine
has the API key for it. A show can add its own models too: another Router model, or a
workflow saved in ComfyUI (the editor’s Models window; seriesmith target-from-workflow), named in target: like any other.
The series config: series.json
style.lookopens every shot’s description (“The target video is …”), so it sets the photography of the whole series. See Writing thelookline.kindischaracter,proporvehicle. Only characters speak.- A character’s
sheetis a four-panel strip (three-quarter body, side, back, face), and a shot gets one panel of it: the three-quarter body, or the face on a one-character close-up. A picture you supply that is one image of the character (a portrait, a full-length shot on white) needs"sheet_panels": 1, or it is cut into quarters and the model gets a strip from its left edge. With it the picture is sent whole on H3 Ref2VA. - No picture yet. A location with a
descriptionand noplate, or a subject with adesignand nosheet, is described in words on H3 Ref2VA: it takes no Picture slot and nothing waits for a picture. That’s fine for a one-off clip or a first try, but a series stays consistent through its pictures: without one, each shot imagines the place or the person its own way. Add theplate/sheet(and make the picture) when it should look the same every time. membersmakes a character a group: one picture of that many people (2–12), cast like any character and costing one slot. See A group: the same extras every shot.ofmakes the subject a wardrobe variant of another one — the same character in different clothes, the same prop in a different state. See A wardrobe change is a new subject.audio.modesets how dialogue shots sound:clone(the model speaks the written lines in each character’s sampled voice),source_track(the default: you supply a recorded mix,audio.track, and shots dub to it; seeRECORDED_DIALOGUE.md) orgenerate(the model invents the voices from eachvoiceline; no recordings or samples needed).proxy.audio_modecan use another mode for the animatic (generateis the usual one),audio.default_policyforces one policy for every dialogue shot, andaudio.retentionsets the dubretention:default. A target that can’t do a mode says so and generates.upscale.save_latentsdecides which renders keep their latent for an upscale later:"final"(the default: the final pass is what gets upscaled; a proxy take can still be, through the VAE),"always"or"never"(to save the disk space, a few MB a take; an upscale then goes through the VAE).- Resolution must be a multiple of 32 on both axes for H3. 1280×720 is illegal, because 720 is not. 1344×768 is H3’s native canvas. The other targets snap it to their own sizes. Whether the final pass renders at the size you deliver, or smaller and is upscaled, is Final resolution below.
steps,loraandmodelare optional per pass.loratakes one LoRA or a chain, as the script’slora:line does ("lora": "turbo_8step.safetensors, soft_light.safetensors:0.6"); see COMMANDS.md, Steps, model and LoRA.series.targetnames the video model the episode renders on:minimax_h3_ref2va(MiniMax H3, the default: leave it out),ltx2(LTX-2.5 distilled),ltx2_ingredients(LTX-2.3 with your character sheets and plates),minimax_h3_fl2va(MiniMax H3 from first/last keyframes), one of the silent Wan 2.2 models:wan22_i2v(14B, from a first frame),wan22_ti2v(5B, text or a first frame) orwan22_vace(14B with your character sheets), or a hosted model (seedance_2_5,kling_v3_omni, …).series.backendsays where its jobs run (local,cloud,deployment:<target>,router), else each target’s own. Single shots or sequences can render on another one; see Rendering a shot on LTX-2, Rendering a shot on H3 from keyframes and Rendering a shot on Wan 2.2 below."simple": truemarks a project the editor’s Simple mode made (Clips, or + New project): its project picker lists it. It changes nothing about how the episode builds or renders.
Final resolution: render at size, or render small and upscale
series.width / series.height is the size every final take renders at, and
proxy.width / proxy.height the proxy pass’s. The usual setups:
(Measured on an RTX 5090 with the 8-step turbo LoRA; the 1024×576 time is estimated from
its 13% more pixels than 960×544, since attention grows a little faster than the pixel
count.)
A proxy smaller than 480p is too small to judge a shot by: faces, hands and small props
blur into each other. 864×480 is the default for a new series; 896×512 is the same 7:4 shape
as 1344×768 exactly, if a proxy take will stand in for a final one in a cut (a proxy of
another shape is scaled to fit there). 448×256 renders quicker, for a rough check of timing
only.
The shape matters as much as the size. 1344×768 is 7:4 (1.75), not 16:9
(1.78): H3 sizes are multiples of 32, and 1344×768 is the model’s native size. A 7:4 take
delivered at a 16:9 size is either cropped (1344×768 to 4K loses 18 rows top and bottom,
1.6%) or padded (30 px of black each side); the upscale’s Output size does either
(
--deliver 4k --fit crop|pad; the dialog’s Crop to fill / Pad with bars). 1024×576 is the
16:9 size on H3’s 32 grid (512×288 its proxy), so nothing is lost at 1080p or 4K, at the
cost of a slightly smaller frame than 1344×768. The LTX and Wan targets snap a size down to
their own grid (LTX-2’s is 64: a 512×288 proxy renders there at 512×256, a little wider than
16:9); the H3 targets refuse a size off theirs, naming the nearest.
- Render small and upscale when the episode renders on
minimax_h3_ref2vaorminimax_h3_fl2vawith the latent upscaler installed (INSTALL.md, The upscaler), onltx2, which upscales with its own second stage and needs nothing extra, or onltx2_ingredientswith LTX-2.3’s latent upsampler installed (INSTALL.md, For upscaling;seriesmith targetssaysupscale readyfor each). Every take you try costs under half as much, and only the ones the cut keeps are upscaled, once, after the cut is locked. The upscale re-samples the take from late in its schedule under its own prompt, references and seed, with its audio held, so the performance and the lip sync are the take’s; it adds detail a 960×544 frame is short of (hands, small props, texture). It can’t add a face the render didn’t draw: at 960×544 a face in a medium-wide or wider is a few of H3’s 16-pixel cells, and the re-sample sharpens what’s there (see Faces need room). A live-action series that lives on faces and dialogue renders at 1344×768 (Delivering 1440p below). - Render at size when shots render on Wan (
wan22_i2v,wan22_ti2v,wan22_vace: they re-sample, a pixel model then their own sampler, but slowly: minutes a shot), when the upscaler isn’t installed, or when 1344×768 is the delivery. Upscaling a 1344×768 take to 2688×1536 works but adds little: that frame already holds most of what the model can draw. - Pick one per series. A single take can still render at another size: the New take
dialog’s Size (that take only;
seriesmith render --size 1344x768), or the shot’s override (the inspector’s Size,seriesmith override --size 1344x768: every later take of that pass). A master with"scale": "auto"re-samples each take by its own size, so a cut that mixes 960×544 and 1344×768 takes delivers one 1080p master. Switching the series size later only changes the takes rendered after the switch.
seriesmith upscale <ep> --only sh100 --redo --detail 2 (two steps earlier: more change, check
it).
Takes on a show’s own targets (and any take, by choice) can still be upscaled by the
pixel method: an upscale model (RealESRGAN, UltraSharp, from
ComfyUI’s models/upscale_models) over the frames, with the take’s audio copied on. It is
fast and needs nothing but the model, but it only sharpens what’s there; it draws no new
detail the way a re-sample does. seriesmith upscale <ep> --method pixel uses it for any take.
On an NVIDIA RTX card, RTX Video Super Resolution is offered among the upscale models
(--pixel-model rtx_vsr; INSTALL.md says how to add it): no model file, and about 15 s a
5 s shot at 2x against RealESRGAN_x2’s two minutes (SeedVR2 7B: seven to nine). It is a
little softer than RealESRGAN and a little steadier frame to frame, and likewise draws
nothing new. Its default level (ULTRA) is the one for generated takes; HIGHBITRATE_ULTRA
leaves a clean take nearly as it was. It goes wherever an
upscale model goes (the pixel method, --then-pixel rtx_vsr, a Wan re-sample’s start, a post).
SeedVR2 is the third method, for any take too: a one-step video restoration model
(ComfyUI’s own nodes; files in INSTALL.md). It gives the sharpest single frames of the three,
in about a minute a shot, with no prompt (so nothing ties it to the take’s performance but
the picture); its frames change a little more from one to the next than a re-sample’s, and
the colour finish after it halves that. seriesmith upscale <ep> --method seedvr2 (the 7B;
--seedvr2-model 3b for the smaller one). It can also follow a re-sample in the same job,
in place of an upscale model: seriesmith upscale <ep> --then-seedvr2 --deliver 4k (the dialog’s
Then: SeedVR2), so the take is redrawn under its own prompt with its lips held, then
restored to the output size.
--scale is any number above 1, up to 4 (a pixel upscale lands on even sides, an H3
re-sample on the 32 grid, so 1.5x, 2x, 3x of 1024×576 all work; the LTX targets’ is 2x
only). For 4x with generated detail, re-sample then upscale in one go:
seriesmith upscale <ep> --then-pixel RealESRGAN_x2.pth (re-sample 2x, then the model 2x more).
The editor’s Upscale dialog offers the same, and shows the size each choice makes. An
upscale you already have can be taken further later with the pixel method alone:
seriesmith upscale <ep> --only sh100 --method pixel --from-upscale (the dialog’s “On top of the
existing upscale”).
A pixel model has a fixed factor of its own (RealESRGAN_x2 makes 2x, RealESRGAN_x4 4x), but
the upscale is resized to whatever scale you ask for: RealESRGAN_x2 at 1.5x is the model’s
2x shrunk to 1.5x, which is sharp and cheap. So pair a 2x model with 1.5x or 2x and a 4x
model with 3x or 4x (a 4x model at 1.5x does four times the work to throw most of it away).
Output size (--deliver 1080p|1440p|4k|WxH, --fit crop|pad; the dialog’s Output
size) makes the upscale exactly that size instead of a multiple: the last step that can
make any size (the upscale model, SeedVR2) is scaled to cover it (crop) or fit inside it
(pad), and the rest is trimmed or barred. A 4K master from a 1344×768 take: seriesmith upscale <ep> --then-pixel RealESRGAN_x2.pth --deliver 4k (re-sample 2x to 2688×1536, the model to
3840×2196, 36 rows cropped); from 1024×576 the same makes 3840×2160 with nothing cropped. A
re-sample alone keeps its own scale and is resized to the output size (a downscale is fine;
a stretch up is noted, and an upscale model after it is the better way). Every upscale of a
cut at the same output size assembles without resizing. Past 4K the output is heavy to make
and to play: up to 4096 wide upscales encode on the GPU (NVENC); past it they’re written
with x264 on the CPU, which takes a couple of minutes but plays in the editor (the GPU
encoder can only write HEVC that big, which browsers often show as black).
A pixel model’s output is finished before it’s saved. By default its colour and tone come
from the original frames and only its fine detail from the model (upscale models shift
colour a little; this keeps an upscaled clip matching the cut around it). Two more, off by
default: keep soft areas soft fades the detail the model invents where the original was
out of focus, so shallow depth of field stays shallow (--keep-soft 1), and grain puts
back the film grain the model scrubbed away (--grain 0.02 is light).
Masters: one recipe for every shot
A master is the locked cut delivered at one size, every shot upscaled the same way. The series config says how, once, inupscale.master (the recipe):
deliver(1080p, 1440p, 4k or WxH),fit(crop or pad) andquality(master: x264 CRF 12, for delivery;reviewis quicker) are the whole master’s: one size, one encoding.targetshas a section per video target (an id or a glob; the exact id wins, then the most specific glob, then"*"). A take is always upscaled through its own target: an H3 shot re-samples with H3, an LTX shot with LTX. A section takesmethod(latent, pixel, seedvr2),scale,detail,pixel_model,seedvr2_model,then(an upscale model file, or"seedvr2", after a re-sample),then_scale, and the finish (keep_soft,grain);finishsets those for every section."scale": "auto"(a re-sample alone) picks, per take, the smallest scale on the target’s grid that coversdeliver: 2x for a 960×544 take, 1.5x for a 1344×768 one (2016×1152, scaled down to 1920 and cropped), so an episode that renders some shots at 1344×768 masters with no wasted pixels.window(seconds) is for a long H3 re-sample. A take longer than one window is sampled in overlapping windows along time (5.5 s with 1.25 s of overlap by default: a usual 4–5 s shot still re-samples in one pass), so a 2x re-sample of 1344×768 (2688×1536) fits a 32 GB card at any length. Shorter takes are sampled in one pass, as before. Set a longer window if your card holds it, or0to turn windowing off. It needs thecomfyui-obvpm-timelinenode pack (its H3 Context Windowing); without it, a long shot’s upscale says so instead of running out of memory.- A continuity shot (its first keyframe the previous shot’s last frame) starts its
upscale from the previous shot’s upscaled last frame, so the two meet on one picture.
Re-sampling each from the same low-res frame gave two different 2x pictures of it, which
shows as a colour jump at a cut that should be seamless. Every upscale keeps its last
frame (
<take>.up_last.png). The master queues a source before the shot that continues it, and makes either upscale again when it was made before this (never a Keep). - A
continuous: latentshot does the same in latent space: its re-sample holds its first frames on the previous shot’s upscaled latent, which that upscale keeps (<take>.up.latent.safetensors, about 60 MB for 5 s at 2x) only when the next shot in the cut is such a shot. The master queues the source first and makes an upscale again when the source kept no latent, or the chained shot wasn’t held (it ran first). - A shot can have its own recipe over its target’s (a dialogue close-up kept light, a wide
given
detail: 1, a shot SeedVR2 got wrong sent to the pixel method): the editor’s Upscale dialog, Choose for this run, then Save as sh020’s recipe.
seriesmith master Shows\ep05 --wait (or the cut menu’s Master…) goes through the cut:
- a shot with no upscale, one made from an older take, or one that failed is upscaled by the recipe;
- a fresh upscale made with the recipe’s settings is used as it is;
- a fresh upscale made with other settings (an older recipe, or before upscales
recorded theirs) is kept, not redone:
--conform(the dialog’s Conform) redoes those; - an upscale marked Keep (the take menu’s Keep upscale,
seriesmith upscale --only sh020 --keep) is never redone by Master, even with--conform; - a shot with no usable pick, or a kept upscale at another size, is a gap: no master is
made until it’s fixed, unless
--allow-gaps.
Shows\ep05\master\
(ep05_master_3840x2160.mp4, with --prores a ProRes 422 HQ .mov too; a master already
made gets its .mov without assembling again from --prores-only, or the dialog’s
ProRes from this master) and writes
ep05_master.md / .json: every shot’s take, target, recipe and status. It never changes
the cut: lock the picks first. Several episodes, or a whole show folder, master in one go
(seriesmith master Shows); an episode with gaps is skipped, not half-made. --check shows the
plan without queueing anything.
The upscales are queued in cut order by default: watch them land, and if one is off you
can stop there knowing everything before it is good. For a batch you’ll leave running
(overnight, over lunch), --order target (the dialog’s Queue: Grouped by target) runs the
shots that load the same model together, so ComfyUI loads each model once instead of at
every change of target; the dialog remembers the choice.
Writing a new series config, add an upscale.master block for the delivery they named
(ask once if they didn’t: 1080p is the usual; 1440p for a series rendered at 1344×768; 4K
when they say so). The patterns below are
the best value in time and quality we’ve measured; say which you chose and why.
Delivering 1080p
Render small and re-sample 2x; nothing after it. Per picked take the re-sample costs about as much as one 960×544 render, and it redraws detail at full size under the take’s own prompt, references and seed with its audio held, which no pixel upscale of a bigger render matches. Rendering at 1344×768 costs every take ~53 s instead of ~20 s and still needs an upscale to reach 1080p. With about 4 takes a shot, a 100-shot episode is roughly 3 hours this way against about 7 at 1344×768 (extrapolated from 3–5 s shots: master one real episode before planning a season on it).- 960×544 (proxy 448×256) when the shots are mostly H3: the re-sample makes 1920×1088, cropped by 8 rows (0.7%, invisible).
- 1024×576 (proxy 512×288) when many shots are on LTX, or for a touch more crispness: it’s on both H3’s 32 grid and LTX’s 64 (LTX snaps 960×544 to 960×512, whose 2x is stretched about 5% to fill 1080), and the 2048×1152 re-sample is scaled down to exactly 1920×1080. About 15–25% more time a take and an upscale.
- Wan shots: SeedVR2 7B (about a minute a shot), or a pixel model (about 40 s) when time matters more; Wan’s own re-sample takes minutes and isn’t worth it at 1080p.
- Some shots at 1344×768 (dialogue-heavy mediums the small render doesn’t hold): give
the H3 section
"scale": "auto". Those takes re-sample 1.5x to 2016×1152 (about the pixels of a 960×544 take’s 2x), scaled down to 1920 wide and cropped by 18 rows; the 960×544 takes still re-sample 2x. A fixed 2x would take them to 2688×1536 only to throw most of it away.
save_latents: "final" (the default) lets the re-sample start from the take’s latent
instead of re-encoding its video. A wide shot without dialogue that looks soft can take its
own recipe with detail: 1; don’t raise detail for every shot, it can change a speaking
mouth.
Delivering 1440p
Render at 1344×768 and re-sample 2x; nothing after it. The take holds faces and mouths a 960×544 render can’t (see Faces need room), and the 2x re-sample to 2688×1536 is scaled down about 5% to 2560×1463 and cropped by 23 rows, so the master is slightly supersampled. Measured on an RTX 5090: about 75 s a shot, and cleaner than re-sampling 1.5x and finishing with RealESRGAN, which took 210–230 s (the upscale model’s pass at 1440p is the slow part). Uploaded to YouTube at 1440p, it also streams better to viewers watching at 1080p than a 1080p upload does.- Proxy at 960×544, on the 8-step LoRA at 8 steps (
"proxy": {"width": 960, "height": 544, "steps": 8, "lora": "minimax_h3_ref2v_turbo_8step_v1.0_768p_comfyui_bf16.safetensors"}): a proxy then looks like a final, so a good one can stand in. Its 2x is only 1920×1088, stretched to 1440p: give such a shot its own recipe at"scale": 2.75(960→2640), on a short shot only. - Long shots: a 2x re-sample of 1344×768 is heavy. Up to about 6–7 s it fits a 32 GB
card; a 10 s shot at 2x ran out of VRAM and stalled. Give long shots their own recipe at
"scale": 1.5with"then": "RealESRGAN_x2.pth". - Keep
"scale": 2, not"auto": auto would also choose 2x for a 1344×768 take, but takes at other sizes would re-sample differently.
Delivering 4K
The same small render, the same 2x re-sample, then an upscale model the rest of the way:"then": "RealESRGAN_x2.pth" with "deliver": "4k". From 960×544 the model makes an
exact 2x of the 1920×1088 re-sample (3840×2176, 16 rows cropped), so it runs at its own
factor with no resize; from 1024×576 it takes 2048×1152 to exactly 3840×2160. Measured (RTX 5090, 3 s shots,
master quality): about 3 minutes a shot on H3 (the re-sample ~30 s, the model’s pass at
4K ~2 minutes, the encode ~11 s), nearer 4 on LTX, about 2 for a Wan shot through
RealESRGAN_x4, against well under a minute a shot for 1080p. For a 100-shot episode that’s
some 5 hours of upscaling at 4K against under an hour at 1080p: master 1080p as you go and
4K when it’s asked for.
- Don’t re-sample 4x in one go: a single refine step on a 4x latent is unmeasured and heavy on VRAM. Re-sample 2x, then a model.
- The model after the re-sample is the steadiest frame to frame. SeedVR2 there
(
"then": "seedvr2") gives the sharpest stills but is several minutes a shot at 4K: give it to the shots that earn it, as their own recipe, not the whole series. - Rendering at 1344×768 for 4K works (re-sample 2x to 2688×1536, the model the last 1.43x) but costs every take more and the re-sample more, for little.
- Wan shots: a 4x model (
RealESRGAN_x4.pth, about 3x from 1280×704), or SeedVR2 for the few that need it.
deliver makes the 1080p upscales the wrong size for a 4K master, and --conform replaces
them).
fit: crop unless they’d rather keep the whole frame with bars (pad).
Post-process: the post block
A post finishes a shot’s upscale, at the same size: a clean-up pass over the whole
frame, then motion blur. It is for what H3’s latents leave behind even after the re-sample:
blocky edges and shadows, and moving things that smear in blocks instead of blurring.
enhance:"production"is SeedVR2 7B at the upscale’s size, the one to use. It was chosen on Porchlights ep01 against the upscale alone, an earlier re-sample start, SeedVR2 3B, an upscale model and SUPIR. It cleaned edges, lettering, hairnets and faces in motion best, and took about 4.5 minutes a 5 s shot at 1080p. At 1440p it’s about 100 seconds per second of footage (11 minutes for a 6.6 s shot, against 4 for its 2x re-sample), so post the shots that need it, or plan an overnight run."draft"is an upscale model at 1x: a quick sharpen that also sharpens the blocks."cinematic"is SUPIR: about 30 minutes a shot, frame by frame."none"skips the clean-up.
motion_blur: a fraction of the frame interval, 0 to 1. 0.3 smooths blocky motion; 0.5 is a 180° film shutter. Still areas are left alone.- A shot can have its own over it in overrides.json:
"post": {"sh040": {"motion_blur": 0}, "sh050": {"enhance": "none"}}. - Face detailing (redrawing faces with an image model) was tried and dropped: it changed who the characters were (docs/POST_PROCESSING.md).
seriesmith post Shows\ep05 posts every upscaled shot of the cut by the recipe (--only,
--redo, or --enhance / --blur for a one-off), and the editor’s take and cut menus
have Post-process…. The Master dialog’s Post-process says what the master is made from:
- Off: the upscales.
- Where present (
seriesmith master Shows\ep05 --post present): each shot’s fresh post where it has one, its upscale otherwise; nothing is post-processed and nopostblock is needed. The way to post only the shots that need it: upscale, scrub the cut, Post-process… the ones that need it from the take menu, then master. - All by recipe (
seriesmith master Shows\ep05 --post --wait): every shot by thepostblock; a shot without an upscale gets its post queued right behind the upscale.
post block with "enhance": "production" and
"motion_blur": 0.3 when the master is 1080p or 1440p. Leave it out if they haven’t asked
for it, or if the episode will be mastered at 4K: a post at 4K hasn’t been measured.
Series intro and outro: the publish block
The show’s opening and closing are two clips made once for the whole series, not shots
in each script: every episode then opens on the same picture, and a model never has to
spell the episode’s name. Put them in the show folder as _titles\INTRO.mp4 and
_titles\OUTRO.mp4, and every master (seriesmith master, or Master in the editor) is made
with them: the intro, the episode, the outro, with the episode’s title from its = line
written under the series title the clips carry, in one font, size and colour for every
episode. Without the files a master is made plain. seriesmith publish Shows\ep05 does
the same to the review cut, into ep05\publish\ (the editor’s Publish button).
The cut’s picture is copied, not re-encoded: only the two title clips are encoded, to
match it, and the result is checked frame by frame at each join (a cut that can’t be
matched is re-encoded whole, and publish says why). To use other clips, name them in the
series config, relative to the episode folder:
subtitle object sets font,
size and y (fractions of the frame height), color, glow, and the fades in seconds:
intro_in, outro_in, outro_out (see seriesmith/publish.py for the defaults).
Render profiles
A profile is a named render setup for a kind of shot, so you set it once instead of repeatingmodel: / lora: / steps: on every shot. Declare profiles in the series config
and pick one with profile: under a # sequence header or on a ## shot:
- Every key is optional:
target,model,loras(a list of LoRA names;name:0.6sets a strength,"none"means no LoRA) andsteps. - A profile applies to both passes, like a shot’s own
model:line. - What wins, from weakest to strongest: the series config’s
series/proxyblock → the sequence’s profile → the sequence’s ownmodel:/lora:/steps:lines → the shot’s profile → the shot’s own lines. Soprofile: dialogue_closeplussteps: 9on a shot renders the profile’s model and LoRAs at 9 steps. Alora:line replaces the profile’s whole LoRA list. - A profile name that isn’t in the series config is an error.
Model files: model_families
Every model file a shot loads is checked against the model family its target needs
(LTX 2.5 for ltx2, H3 Ref2VA for minimax_h3_ref2va, …) when it is queued. A file
named like the family passes. Any other name is identified from the file’s own header
(the tensor names and shapes of a .safetensors file; the weights aren’t loaded). If the
header says it’s the right family, it renders with a note. If it says it’s another
family, the shot is skipped (“wan2.2_i2v_low_noise_14B_fp8_scaled is Wan 2.2 I2V 14B
low-noise, but this LTX-2 target’s model must be LTX 2.5”) unless you render anyway.
A header can’t tell every family apart. H3 Ref2VA and FL2VA files are identical inside, and
so are Wan 2.2’s high- and low-noise experts and the LTX 2.3 and 2.5 upscalers. For
those, the name decides. If you rename or merge such a file, add its name to the series
config so the pipeline knows which one it is:
- Keys are family ids:
minimax-h3-ref2va,minimax-h3-fl2va,ltx2.5,ltx2.3,ltx2.5-latent-upscaler,krea2,wan2.2-i2v-14b-high,wan2.2-i2v-14b-low, … (targets/modelid.pylists them all; each target’starget.jsonmodelsblock says which one each of its model settings needs). - Values are file-name patterns:
*matches anything, case doesn’t matter. They add to the target’s own patterns; they don’t replace them. - A matching name is trusted without reading the file, so keep the patterns specific.
Which model? Readiness and downloads
Runseriesmith targets (with ComfyUI running) before you pick a target. It prints one
line per target, ready, degraded, not_ready or unknown (ComfyUI didn’t answer),
and under it every file that target is missing, with the models folder it goes in and
where to download it:
seriesmith targets Shows\ep05) to use its series config (the pass
blocks’ model and LoRA, model_families) and mark the episode’s target. --json prints
the same as data.
- Required files (the model, text encoder, VAEs): without one the target can’t render. Its shots are skipped when you queue them, and the message names the file, the folder and the download link.
- Accelerators (the turbo LoRAs, LTX 2.3’s distilled checkpoint): without one the
shot still renders, on the pass’s slower
basesettings (more steps, no turbo LoRA), and the take says so. - Optional files (the LTX duration head): only their feature is off (
dur: modelrenders the estimate).
- the render request (the redo dialog,
render --target); - the shot’s override (the editor, or
seriesmith override Shows\ep05 sh020 --target ltx2); - the script: a
target:line, or a profile’s target, on the shot or its sequence; - the episode target set in the editor, or with
seriesmith override Shows\ep05 --episode-target ltx2(builtclears it). It is kept in the episode’soverrides.json, not inseries.json. While it is set, a shot can be pinned to its built target from the editor (or--target built). series.targetinseries.json;minimax_h3_ref2va.
"target": "<id>" in series.json’s series block and rebuild.
Reference images and voices: the refs block
Reference images (character views, props, plates) and shot keyframes are made by an
image model; a character’s voice sample is made by an audio model. The series
config can say which:
A variant’s view (a subject with
of:) is generated as an edit of the same view of the
character it is a variant of, on any target that reads reference images — so its back panel
is drawn from their back panel, and the face carries. On a text-to-image target there is
nothing to edit from, so it falls back to drawing the variant from its design on the
base’s seed; write that sentence as close to the original’s as the change allows, because
there the wording is all the identity there is.
An image workflow of your own (a show’s model made from a workflow saved in ComfyUI) is an
image target too. The editor can choose per episode (kept in overrides.json, not here) and
per ref, and a generate request can name one; most specific wins. seriesmith targets --kind image
(or --kind audio) says which are installed and what to download for the rest. A ref is
worded the same whichever model makes it.
A character with no voice_sample still has a voice ref: generating one and picking it
writes refs/voices/<id>.wav and adds the voice_sample line to series.json for
you (the only thing the editor writes there). seriesmith refs <ep> --voices does the
same from the command line, and --from-take sh020:3:1.2-6.4 makes a sample out of a
line the model already spoke in a take, with no model at all.
Negative prompts
Targets that take a negative prompt (LTX-2, Wan 2.2 and the image models; not H3) use, most specific first: the render request’s, the shot’s override (the editor, per pass), the episode’snegative.txt (a text file beside the script), the series config’s
"negative": "...", then the model’s own. The take records which one it used. Turbo and
distilled models sample without guidance (cfg 1): there a negative does nothing, and the
take says so.
Writing the design sentence
This is the highest-leverage sentence in the pipeline. It is injected verbatim into every
prompt the character appears in, and the model sheet is generated from it.
Describe what a model sheet artist could draw. Age and build, silhouette, hair, wardrobe
with specific colors, one or two distinctive accessories, line quality. Concrete nouns.
Weak: “a mischievous kid with boundless energy who never sits still” — none of that is
drawable, and it crowds out detail that is.
Location descriptions work the same way and must include the light: time of day, direction,
quality. The plate is generated from that sentence. Name the sources: the pendant lamp
over the table, the chandeliers, the TV’s glow, the streetlight through the blinds. A room
lit by things you can point at renders as a lit set, with pools of light and shadow
between them; “warm lighting” renders as an evenly lit showroom.
Writing the look line
style.look is the first sentence of every shot’s description, so it is the series’
photography. Write it the way a director of photography would brief a crew: what the lens,
the focus, the light and the film stock do. Adjectives about quality (“cinematic”,
“beautiful”, “high quality”) give the model nothing to draw.
Weak: “a cinematic prestige drama with moody lighting”.
Strong: “a naturalistic live-action prestige drama shot on 35mm anamorphic lenses: shallow
depth of field with the background falling into soft bokeh, low-key light from the practical
lamps in each room, deep soft shadows with lifted blacks, muted desaturated color and fine
film grain”.
Each clause is something the model can see: shallow focus and bokeh separate the subject
from the room and soften what the model draws worst, low-key practical light gives the frame
contrast and shape, and grain gives the image the texture of film. Keep it to one sentence;
the per-shot light belongs in the location descriptions and the action.
A location is one angle, not one place
One plate per location means every cut rebuilds the same view, and characters appear to pop into an unchanged picture instead of being discovered by a camera. Author two to four angles per place and let each shot name its own withplate::
street_day and street_night are two entries with
two plates, because the plate carries the light.
Write the angles as one place. Each plate is drawn from its own description, so unless
those sentences share fixed features they describe several rooms with the same name rather
than one room from several sides. Anchor every angle to the same things: “the kitchen from
the hallway door, sink under the window on the left, the living-room arch behind camera” and
“the kitchen from the sink, the hallway door on the right, the arch beyond it”. That is what
makes the geography hold together across a cut.
Tie the angles to one master with of. Words alone still give each angle its own
walls and furniture. Give one entry the plate you like (the master) and mark the others as
angles of it:
- An angle inherits nothing. It keeps its own
descriptionandplate, and shots still name it withplate:. - On an edit model (Klein, Qwen, Rapid AIO, H3 still), an angle’s plate is generated from the master’s plate: the same building, materials and light, with only the camera moved. On a text-to-image model (Krea 2) it is drawn from its words as before.
- The Refs tab lists the angles under their master.
- An angle’s master must be a location that isn’t itself an angle.
- The Refs tab can also make an angle’s picture from the master’s plate in two other ways: a 360 panorama of it (Make 360), whose viewer saves any view you turn to; or an H3 camera tour through it, whose held frames (and any frame you stop on) become candidates. Both keep the master’s room exactly, and a picture made this way is picked into the angle like any other. Qwen’s multi-angle LoRA (a character’s Turn) isn’t used on plates: it turns a room into a diorama.
Two people talking need an angle each
This is the one that spoils scenes most often, and the build warns about it:A wardrobe change is a new subject
The same idea for people. A character’s clothes live in theirdesign sentence and in their
model sheet, so a character who changes clothes is a second subject with of: — a
variant — not a note in the action line:
of: and its own design. Everything else — kind,
name, voice, voice_sample — is inherited, so one character still has one
voice, and a sheet path is derived from the original’s (refs/gina/gina_sheet_4panel.png
becomes refs/gina/gina_towel_sheet_4panel.png). Give it its own sheet line to put it
somewhere else. Generate that sheet like any other reference; starting from the original’s
approved views holds the face far better than generating it cold.
In the script, name the variant where it is on screen and go on calling the character by
their name:
who: takes the variant; GINA: still speaks, and the line is given to whichever of her is
in the shot. A shot names one or the other, never both, and never two variants of the same
subject — cut the shot where the change happens.
Why not a wear: line on the shot? Because the reference sheet would still show the old
clothes, and the prompt would have to argue with the picture. H3 preserves a subject as a
whole — its fully_preserved marker covers face, hair, proportions and wardrobe — so the
only way to contradict the sheet is to weaken the whole subject, which loosens the face in
order to change the clothes. A variant keeps the identity lock and swaps the picture. It also
costs nothing on the other targets: LTX-2 and Wan have no reference images and read the
design sentence, which is already the variant’s.
A variant is for a state a shot is in, not a change it makes.
Never show the change itself
No video model today can take a hat off, pull on a glove or shrug out of a jacket and keep it off. The item comes back, doubles, or melts into the hands, and the next shot puts the sheet’s version straight back on him. So a shot’s wardrobe is fixed from its first frame to its last, and it is what the subject’s sheet shows. Don’t write dressing or undressing into an action line: not taking off a hat, gloves or glasses, not hanging up a coat, not stepping into coveralls or tying on an apron. Small things matter most, because they are the easiest to forget. A mesh glove pulled off in one shot is back on in the next, because nothing told the next shot it was gone. When the story needs the change, cut around it:- Start it, then cut. Show only the beginning (his hand going to the brim, fingers on the zipper) and end the shot there. The next shot is already in the new state.
- Land on an insert. Cut to the item or the hands, not the face: the hard hat held against
his chest, framed below the chin, or a bare forearm hanging the navy jacket on a locker hook.
Make the item a prop (
with: hard_hat) and keep the character out ofwho:, or frame it tight enough that only the hands show. An insert has no face to drift and needs no new sheet. - Cut away. Go to the other character’s line or reaction, then come back to the variant.
- Change off screen. End one scene in the old clothes and open the next in the new ones.
Luis walks into the locker room in his jacket, and the next scene finds him on the line as
luis_plant. - Don’t change at all. The gesture is often not needed. Glasses can be looked over or pushed up instead of taken off, and a man can fold his hands and wait with his hat still on.
luis_plant_bareheaded too.
The script: epNN.md
Any other line is action prose. Prose under a
# header before its first shot is a
scene-setting note and is ignored. A line under a # header (model:, lora:, steps:,
profile:, target:, first:, last:, overlap:) is the default for every shot in the
sequence (continuous: for every shot after the first); a shot’s own line beats it.
Rendering a shot on LTX-2
target: ltx2 on a ## shot, under a # header, or in a profile renders that shot (or
sequence) on LTX-2.5 instead of the series target; a name that isn’t a target is an error. One episode
can mix the two: the build writes the LTX shots to their own shotlist, and the editor, the
render command and the review cut treat the episode as one. What changes for an LTX shot:
-
Your refs are used when they are there. Everyone in
who:/with:is described in words from theirdesignand the place from the location’sdescription, so the sentences carry the look on their own — and when the shot’s subjects and plate have picked refs on disk and the LTX-2.5 ingredients IC-LoRA is installed, those refs are also drawn onto one reference sheet that conditions the clip, exactly astarget: ltx2_ingredientsdoes (see below for the sheet’s layout). It is decided when the shot is queued, never at build time, so nothing in the shotlist changes; the take says which panels it used, keeps the sheet as<shot>_tNN_refsheet.png, and re-picking a view marks it stale. Without the refs or without the LoRA the shot renders from the prompt alone, as it always did. No panel is ever required: a missing one just leaves that element off the sheet. To turn the sheet off for a shot, sequence or profile, writelora: none("loras": ["none"]in a profile) — the opposite ofltx2_ingredients, where the IC-LoRA is put back because the target is pointless without it. A first- and/or last-frame keyframe (refs/shots/<shot>/first.png,last.png, imported in the editor’s Refs tab) pins the picture when you have one; without keyframes and without a sheet the shot is text-to-video. -
Its own grid:
8k + 1frames (9, 17, 25, … 73 = 3.04s, 97 = 4.04s at 24fps), up to about 20 seconds. The samedur:snaps to a slightly different length than on H3. -
Sound is always generated with the picture. LTX takes no voice sample and no recording:
a shot the series would
cloneordubrenders withgenerateinstead, and the build and the take say so. Each speaker’svoiceline is what shapes the voice. -
One paragraph of prose, written for you: the look, then the framing and the camera,
then who is in frame and what they do, the lines with who says them and how, then the
sound and music. Write
camera:for a move you want; without it the camera stays still. - Size comes from the series config’s pass blocks, snapped down to a multiple of 64 and kept under 1 MP (1344×768 stays; a 480×272 proxy becomes 448×256). Its model, LoRA and steps are the target’s own: a series written for H3 doesn’t hand them H3’s.
-
Two transformers: fast by default, or a quality pass. The default is the distilled
LTX-2.5 transformer, which was distilled for a fixed 8-step schedule at guidance 1 — a
steps:line can’t change that, and the take says so. Name the dev (non-distilled) transformer as the model and LTX-2 renders the quality profile instead: 30 steps with real guidance, for crisper lines and steadier faces. It costs very little — the extra steps run on the half-size base pass, and a 4-second 768×512 shot measured 39 s either way. Set it wherever a model is set — a profile for a kind of shot, amodel:line on a shot or sequence, the series config’sseriesblock for the whole episode, or the editor’s model picker for one shot:Thenprofile: qualityon a##shot or a#header. Asteps:line on such a shot wins over the profile’s 30. The dev file is optional: without it installed,seriesmith targetssays the feature is off and everything else still renders.
seriesmith override <ep> sh040 --target ltx2 (--target built undoes it).
Rendering a shot on LTX-2 with its refs: target: ltx2_ingredients
target: ltx2_ingredients renders on LTX-2.3 with the “ingredients” IC-LoRA, which keeps a
recurring character looking like its sheet (and a prop like its picture, the set like its
plate). Everything above about LTX-2 holds (generated sound, camera:, retargeting), except:
- Your refs are used, and required. Each shot gets a reference sheet, made when it is
queued from the picked refs: one panel per element, tiling the frame, in order: each character in
who:(one panel of its 4-panel sheet: the face on a one-characterclose/cushot, the three-quarter body otherwise, as on H3), then each prop and vehicle inwith:, then the location’s plate. A shot whose ref is missing is blocked, as on H3. Rendering anyway leaves that element off the sheet (it is still described in words); a shot left with no refs at all renders text-only, without the IC-LoRA. The sheet is kept beside the take (<shot>_tNN_refsheet.png), and re-picking a view marks the take stale. - Give important things their own panel. The model only reproduces what is on the
sheet, and bigger panels carry over better: a crowded shot (many
who:/with:) gets small panels. Keep the plate clean. - The shot’s own length, on LTX’s
8k + 1grid from 2 s (49 frames) to 20 s (481 frames) at 24 fps. The IC-LoRA was trained on 121 frames (5.04 s), so any other length gets a soft warning in--check(identity may weaken); it still renders. Longer than 20 s is an error: split the shot. - Size is the model’s: 768×448 for the final, 512×288 for the proxy, whatever the series config’s pass blocks say.
- A two-part prompt, written for you:
Reference sheet:names each panel in order (the character’snameanddesignand which view, the prop’s, the location’sdescription), thenGenerated video:is the LTX-2 paragraph, where someone on the sheet is only named. - A
lora:line or profile written for another model doesn’t remove the IC-LoRA: it is put back first in the list, and the take says so.
Rendering a shot on H3 from keyframes: target: minimax_h3_fl2va
target: minimax_h3_fl2va renders on MiniMax H3’s first/last-frame model. It is H3 (same
grid, same sizes, same turbo-LoRA presets and speaker tags), but it takes no reference
pictures: what pins the look is the shot’s keyframes. What changes for such a shot:
- Keyframes instead of sheets.
refs/shots/<shot>/first.pngis the first frame andlast.pngthe last. Both are optional; with neither the shot is text-to-video. They come from the previous shot (continuous: first, see Continuous shots; or by hand,seriesmith keyframe <ep> <shot>, or--lastfor the next shot’s first frame as this one’s last; the editor’s Refs tab does the same), from a still (first: generate) or from an import in the Refs tab. The render adds the model’s alignment line for whichever it has, so there is nothing to write for them. - Subjects in words. No
<Picture N>slots: everyone inwho:/with:is described from theirdesign, and the place from the location’sdescription(all of it on a wide, what is behind them on a medium, a shallow slice on a close-up). A keyframe wins where it and the words differ. - The H3 prompt, without the picture sections. Written for you in H3’s three fields:
integrated_multimodal_description(the look, the framing, who is in frame, the action,camera:, then each line as<d>[English] …</d>with a speaker id), thenoverall_soundscape(sound:) andnon_diegetic_music(music:). - Sound:
generateas usual.dubanddub_keep_foleywork: the shot’saudio:window of the recording (audio.track) is cut and anchored at the start of the shot, so the mouths follow your recording;dubmakes it the whole soundtrack,dub_keep_foleylayssound:under it.retention:has no effect here.clonehas no voice-sample slot on this model: those shots render withgenerate(each speaker’svoiceline shapes the voice), and the build and the take say so. - Length: H3’s
17k + 5grid. The model is trained on about 5 to 15 seconds (124 to 362 frames); longer shots render with a warning. A shot continues the one before by its first keyframe:continuous: first. - Size comes from the series config’s pass blocks (multiples of 32). Model, LoRA and steps are the target’s own unless it is the series target.
seriesmith override <ep> sh040 --target minimax_h3_fl2va.
Rendering a shot on Wan 2.2: wan22_i2v, wan22_ti2v, wan22_vace
Three Wan 2.2 targets, for pictures without sound:
wan22_i2v(label “Wan 2.2 14B I2V”): the 14B image-to-video pair (a high noise model, then a low noise one, each with its 4-step turbo LoRA). It animates a picture you give it: a first frame is required (refs/shots/<shot>/first.png: generated from the shot’s description, cut from the previous shot withcontinuous: first, or imported; see Keyframes). A shot without one is blocked, and rendering anyway can’t help: “Wan 14B I2V needs a first frame: generate one, import one, give the shotcontinuous: first(the previous shot’s last frame), or retarget to wan22_ti2v”. Alast.pngtoo makes it a first/last-frame shot.wan22_ti2v(“Wan 2.2 5B TI2V”): the small 5B model, text-to-video, or from a first frame when there is one. Nothing blocks it: the fast, cheap choice for proxies, and where an I2V shot without a first frame can go.wan22_vace(“Wan 2.2 14B VACE (refs)”): the 14B VACE pair, which keeps your characters looking like their sheets. When the shot is queued, one reference picture is made from the picked refs: one panel per subject on white (each character inwho:, the face panel on a one-characterclose/cushot, else the three-quarter body; then each prop and vehicle inwith:). The plate isn’t used: the place is described in words. A missing sheet blocks the shot, as on H3; rendering anyway leaves it off. First and last keyframes are optional and pin the ends of the shot. No turbo LoRA exists for it here, so it renders at 10 steps for a proxy and 20 for a final: slower than the other two.
- No sound at all. Wan makes none. Every shot renders a mute mp4 whatever its
policy:says (the take’s notes say so), and the review cut lays silence under it. A dialogue shot gets a--checkwarning (“no audio or lip-sync on Wan”): the lines are acted silently (the prompt says who talks and how, mouth moving), so the recording or another take’s sound goes on at the edit. Keep dialogue shots on a target with sound if you need lip-sync. - Its frame rate, and keeping shots short. All three render at 24 fps. The 14B
models (
wan22_i2v,wan22_vace) are specified at 16 fps, but their motion is paced for 24: at 16 a take plays as slow motion, so seriesmith times and saves them at 24. Lengths are on a4k + 1grid: 3 s is 73 frames. The 14B models were trained on 81 frames, 3.4 s at 24, and their prompt adherence falls off after that: a longer shot renders with a warning, and past 161 frames (6.7 s) it must be split. Write Wan shots of 3 s or less, and cut a longer action into two shots. (A take rendered before this at 16 fps keeps its own rate: assemble and Play all time it by what it recorded.) - Prose prompts, written for you: the look, the framing and
camera:, who is in frame from theirdesign, the action, on-screen text, then the lines as silent acting. Nosound:ormusic:: they are ignored. Wan’s standard (Chinese) negative prompt is added for you. - Size is the model’s own (Wan is trained at 480p and 720p, far above H3’s proxy):
wan22_i2vandwan22_vace832×480 final, 640×352 proxy (multiples of 16);wan22_ti2v1280×704 final, 640×352 proxy (multiples of 32). A cut mixing sizes is scaled to the episode’s size when assembled. - A
lora:line or profile replaces the preset’s LoRAs. On the 14B models there are two chains, one per stage: a LoRA whose name sayshigh_noise/low_noisegoes to that stage, any other to both.
seriesmith override <ep> sh040 --target wan22_ti2v.
Keyframes: first: and last:
Some video targets start (or end) a shot on a picture you give them: its keyframes,
refs/shots/<shot>/first.png and last.png. Which shots need one follows from the target
each shot renders on:
wan22_i2vrequires a first frame (it animates it);ltx2,minimax_h3_fl2va,wan22_ti2v(first only),wan22_vaceand the hosted video models (first and last on most;runway_gen4_turboandwan_2_7_r2vfirst only) use them when they exist (optional; a hosted model given a first frame is sent the keyframes instead of the refs);minimax_h3_ref2vaandltx2_ingredientsdon’t read keyframes.
# header for all its shots:
A first frame cut from the previous shot isn’t a
first: value: the shot says
continuous: first (see Continuous shots). The old first: continuity still reads that
way, and seriesmith check says how to write it.
A render keeps continuity current, and a whole chain queues at once. A
continuous: first shot’s first frame is cut when its render starts, from the take
the cut uses at that moment for the shot before it, and sent with the job. Each such job
waits for the one it continues, so queue sh080, sh090 and sh110 together and each starts on
the new last frame of the one ahead of it, on any backend. The take’s sidecar records what it started from (continuity). A chain is queued in
cut order whatever order it was asked for. Before queueing, a keyframe that doesn’t exist
yet is cut from the previous shot’s current take so the graph has a frame to wire; a
continuity shot whose previous shot has no take at all and none coming is an error. The
Refs tab marks a keyframe out of date when the previous shot’s take has changed since
it was cut; a keyframe you imported or generated is left alone. “Before” is the cut’s
order, not the script’s: move a shot on the timeline and its continuity comes from its new
neighbour.
Continuity is for a shot that picks up the previous one’s picture: the same framing
carrying on, or a match on action. After a real cut (a new subject, a new angle, a
different size) the previous shot’s last frame is the wrong opening picture: leave
continuous: off that shot (or write continuous: none under a header that sets it).
Continuous shots: continuous:
A shot that carries straight on from the one before it (the same moment, the camera still
running) says so, and how:
first: it opens on the previous shot’s last frame, as its first keyframe. That needs a target that reads a first frame (minimax_h3_fl2va,ltx2, the Wan targets, the hosted models). A shot on H3 Ref2VA (which doesn’t) builds on H3 FL2VA instead, by itself, unless the shot names its owntarget:(then it’s an error that says which targets can).latent: it carries on from the previous take’s last frames and their sound, on H3 Ref2VA, keeping its own reference sheets. The render holds the end of the previous take at its head and generates the rest from there, so motion, sound and the camera carry across the join; the held frames are cut off again, and the take starts where the previous one ended. Use it for one action running across a cut in framing that the same reference sheets can draw (a camera that keeps moving, someone walking into the frame of the next shot). See How much a latent shot holds below.- Only the shot that continues says it. “Previous” is the previous shot in the cut, so moving a shot on the timeline changes what it continues from.
- Under a
#header,continuous:covers every shot after the first in that sequence (it stops at the next#). A shot breaks the chain withcontinuous: none. A shot can also say it on the first shot of a sequence, continuing the last shot of the one before. - Old scripts:
first: continuityreads ascontinuous: first, andcontinuous: yesunder a header ascontinuous: latent.seriesmith checksays how to write each.
overlap:. The number of frames of the previous take
held at the head of the render. Leave it alone: 39 frames (1.6 s), the default, is what
was tested. Fewer frames give H3 too little motion to carry on: at 22, with the sound not
held, someone walking in popped into frame and was then drawn twice. More frames cost
render time without a better join. H3 can only hold certain lengths (22, 39, 56, 73, …:
17 more each time), so any other number is rounded up to the next one, and
seriesmith check says so (overlap: 30 holds 39). Set it on a shot, under a # header for its
shots, or for the whole series in the series config:
dur: asks, like any H3 length. It continues whichever take the cut uses for the
previous shot when its render starts: a whole chain can be queued at once, each shot
behind the one it continues. The previous take’s kept latent is used when it has one (the
final pass keeps them, upscale.save_latents); otherwise its last frames and sound are read
back through H3’s VAEs, which works for any take, even one from another target. Both kinds
of continuous shot render on any backend (your ComfyUI, Comfy Cloud, a deployment): what
they need from the previous take is sent with the job.
Generating a keyframe writes a still from the shot: the look, the framing and the
location, who is in frame (their design), and the action at that moment: for first how
the shot opens (the action’s first sentence, about to happen); for last how it ends (its
last sentence, finished). Write the action as a short sequence of sentences and both ends
come out right. Dialogue isn’t drawn. The keyframe model (the series config’s
refs.keyframe_target, else FLUX.2 Klein edit when it is installed) also gets the picked
character views (the face on a one-character close-up, else the three-quarter body), the
props and the plate as reference images, so the characters look like their sheets; the
prompt names each one (“image 1 is Ada: draw this character exactly as in image 1”).
seriesmith keyframe Shows\ep05 --missing fills every required keyframe and every one the
script asks for (a continuous: first shot’s from the previous shot’s take when it has a
usable one, else a still);
seriesmith keyframe Shows\ep05 sh030 --generate makes one still; --clear takes a keyframe away
(the shot renders without one, and nothing puts it back until you pick one).
Letting the model time a shot: dur: model
dur: model hands the shot’s length to the video model: LTX-2.5 reads the prompt and
predicts how long the shot naturally runs, then renders that. dur: model 3-8 keeps the
prediction between 3 and 8 seconds (without a range: 1 to 20).
- The build still needs a length for the cut and the runtime, so it writes an
estimate: the
dur: autolength when the shot has dialogue, else 5 seconds, inside your range. The take records the real length it came out at, and the editor’s timeline and Play all use that once it’s rendered. - Only
ltx2can predict, and only once its duration head is installed (the fileltx-2.5-duration-head-bf16.safetensorsin ComfyUI’smodels/model_patches). Until then, and on every other target (H3,ltx2_ingredients, Wan), the shot renders at the estimate:--checkwarns and the take’s notes say so. - Use it for silent action and establishing shots whose length you don’t care to pick. A
dialogue shot is better with
dur: autoor anaudio:window, which keep the lines their room.
Durations land on a grid
Every video model takes only certain frame counts, and adur: between two of them rounds
up, so you pay for frames you throw away. The grid is the target’s: 17k + 5 frames on
the H3 targets, 8k + 1 on LTX, 4k + 1 on Wan (at 24 fps; best kept to 3 s), whole
seconds in each model’s range on a hosted one. The build
snaps each shot to its own target’s grid, and --check warns about wasted padding.
Write for H3’s grid, the default; the other grids are fine-grained enough that these
lengths land close on them too. At 24fps these are free on H3:
Render cost scales as roughly
duration^1.29, so long shots are less efficient per second
than short ones. Cartoon pacing, 2 to 5 seconds, is both better filmmaking and cheaper.
Dialogue has to fit the shot
This is the easiest way to wreck an episode, and it does not announce itself: a model that speaks (H3, LTX) will fit any line into any window by speeding the delivery up. The words are all there, the lip sync is fine, and the performance is gone. On Wan, which acts the lines silently, the recording laid in at the edit still needs the room. A 2.33s shot holds about seven syllables. Never guess — the compiler measures it:- Split it. A line needing six seconds usually wanted a reaction cut in the middle anyway, and the split buys the second angle the scene was missing.
- Cut words. Over-packed shots are usually over-written.
- Lengthen it.
dur: autoderives the length and snaps it to the grid.
pace: fast marks a rush that is deliberate and silences the warning.
Camera moves use H3’s vocabulary
Every target inserts thecamera: line after the words “The camera”, so write the verb
phrase only. Without one, the camera holds still. The vocabulary below is H3’s training
vocabulary; the other models read it as plain English.
Compose from motion + amplitude + speed; the last two are optional.
Motion: zooms in / out · pushes in / pulls out · pans left / right · trucks left / right ·
tilts up / down · pedestals up / down · arcs around · tracks · holds a static shot · shakes
slightly / strongly · takes the subject’s POV · rolls clockwise / counterclockwise
Amplitude: with small amplitude · with large amplitude
Speed: at slow speed · at fast speed
“Arcs around them with large amplitude at fast speed” beats “swoops around dramatically”,
because it names a move the model was trained on.
Film terms translate into that vocabulary:
Staging (where people stand, who faces camera, how a scene’s angles cut together) is the
director’s craft and is best learned from a book like Christopher Kenworthy’s Master
Shots; this guide covers only how to say the result to the model.
On a wide full of big architecture (a plant, a street front, a church), prefer holding still,
a pan or a slow push over a track, truck or arc. A camera that moves through the space makes
the model redraw the buildings as it goes, and they build and unbuild themselves on screen.
Breaking a scene into shots
A scene with three paragraphs of action is six to ten shots, and deciding where they fall is the job. Cut when the subject changes, a new beat lands, someone new speaks, time skips, or the framing must change materially. Don’t cut when only the distance shifts a little — use a camera move. A cut should bring new information; a cut to the same thing slightly closer is a jump cut, and it will render as one (see Cutting within a location). A workable rhythm for a dialogue scene: wide establishing → medium two-shot for the exchange → close on the reaction that matters → back out. Keep the wide short and empty of anything that has to read on a face (see Faces need room). Open every shot on movement. The model has no memory of the previous cut, so a shot whose action describes a position renders that position and then looks for something to do with it. Write the state change: “Dex swings his boots onto the desk and settles back”, not “Dex sits with his boots on the desk”.Faces need room
size: is written into the prompt as the shot’s framing (A close-up frames <Subject 1>…,
A medium shot frames…, A wide shot takes in…), so it is what the model frames, not a
label. Choose it by what the shot has to show:
The full names work too (
size: medium close-up), and so do ls (long shot) and els. The
in-between sizes put what the frame holds into the prompt (“from the chest up”), so a model
that doesn’t know the term still frames it. For the plate and the sheet, ecu/mcu act like
a close-up, cowboy/mws like a medium, and fs/ews like a wide.
A face needs pixels to have a face. H3 draws in cells of 16×16 pixels. On a wide of a
standing person, the face is a few cells across, too few for eyes and a mouth: it comes out
soft and smeared, and an upscale sharpens the smear rather than finding the face. At 960×544
it is worse than at 1344×768. Measured on a 1344-wide full-body walk, the face was 50 pixels
tall: three cells.
- Dialogue, reactions, and anything the audience must read on a face:
mcu,cu, orms. A medium close-up gives the face a few hundred pixels at 960×544; a close-up fills the frame with it. - Wides (
fs,ws,ews) carry geography, entrances, crowds and big physical action, where nobody’s expression has to read: a figure crossing a room, a back to camera, two people seen from across a lot. Don’t hold a wide on a face and expect the face to be there. - Cut in for the face. A fall, a collision or an entrance plays as
fsfor the action →cuon the face that reacts →mwsormsfor the result, not one wide shot that holds the face at a distance.
Cutting within a location
Every shot is generated on its own, so a shot never continues the one before it: it poses everyone from scratch. Cut between two shots that look alike and the eye reads it as a glitch, with people jerking into new positions or appearing out of nowhere. That’s a jump cut. Two consecutive shots with the same people on the same plate need one of these between them:- A new angle. Give the second shot another
plate:of the place. A real change of camera position (film’s 30-degree rule) makes the new pose read as a new view. This is the cheapest fix and why a location wants several angles. - A size two or more steps away, along
ecucumcumscowboymwsfswsews:mws→mcu,ms→cu,ws→ms. One step (ms→mcu,fs→ws) reads as the camera twitching. - A cutaway, then back: the other character’s reaction, an
ecuinsert of hands or a prop, what she’s looking at. Under a second is enough (H3’s shortest take is 0.92 s), and after it the return can be in any pose. - A cut on action. Open the second shot mid-movement (“already turning to the door”), not at rest: movement across the cut hides the change of pose. It helps the other three; on its own it seldom saves a cut.
- Continue the picture when the second shot really is the same moment carrying on:
continuous: firstopens the shot on the previous shot’s last frame, so nothing re-poses (on H3 FL2VA, which the shot moves to by itself; see Continuous shots). Its upscale starts from the previous shot’s upscaled last frame, so the two meet on one picture. When the action itself runs across the cut (someone walking into the next framing),continuous: latentcarries the motion and sound too, on H3 Ref2VA.
seriesmith check warns about consecutive shots that do none of the first two and don’t continue:
the same people, the same plate, sizes less than two steps apart, the second not
continuing the first (continuous:). It can’t see a cutaway or a cut on
action in the action text, so treat it as a question to answer, not an error.
Worked through: Ada at the counter, then closer for her line. As written, a jump cut:
Every shot starts from an empty plate
Plates are drawn empty, and the model sees one shot at a time. Whatever the scene established three cuts ago — who is in the car, the diners at the other tables, that Harold sat down — is gone unless this shot says it again.- Everyone physically in frame is in
who:, even mostly unseen: the driver of a two-shot in a car is both people, the passenger’s shoulder included. Leave one out and the plate’s empty seat is all H3 gets, so they vanish for a shot and come back on the next. The same goes for anyone the action touches or looks at in frame: “Harold reaches for Cora’s elbow” with no Cora inwho:gets an invented stranger. - Repeat
extras:on every shot of a populated room, closes included (“diners at the far tables, blurred behind him”). It does not carry over from the previous shot, and without it the room is empty on the cut. - Say the posture. A plate of a kitchen table is an empty table, and the sheet shows the character standing. Open on the posture plus the movement: “Seated at the kitchen table, Harold turns his head slowly…”, not “Harold turns his head slowly…”.
- Give every moving object a hand. “The briefcase opens” opens by itself; “Mills lifts the
lid of the briefcase” puts Mills in
who:and in frame. - Settle carried props. If a character’s
designhas a bag on the arm and the shot seats them, set the bag down in the action (“her handbag set beside the ledger”), or H3 draws a second, standing copy of them to carry it. - Write to the plate’s angle. A plate shot from the visitors’ side sees the back of the monitor; if the screen matters, have someone turn it.
- One or two physical steps per shot. Crossing a lot, climbing steps and knocking is three shots, not one 4-second shot; crammed motion smears into interlace-like lines. Start the shot where its plate is.
- Pick people up where the last shot left them. If sh160 parks the truck by the building, sh170 doesn’t walk him across the lot. Name the spot in the first shot (“parks at the far end of the lot”) so the next one can start from it.
- The crowd is already there. On an empty plate, people written as arriving materialise in the middle of the shot. Write them as present from the first frame: “the line already running, a worker at every station”.
Vehicles in motion
A moving vehicle with a loose description wanders: it swerves toward the people in frame, speeds up when it should stop, and smears.- Give it one clean path: direction across frame, lane and speed. “The pickup rolls slowly left to right in the near lane, never leaving the road.”
- Arriving and getting out are separate shots. One shot drives in; the next opens with the door already opening.
- Parking is its own beat, and the shot starts with the vehicle already slowing. Say where it stops, so the next shot can pick up from there.
camera: holds a static shot for reactions where stillness is the point. On a wide
you have just cut to, a slow push gives the space depth, and costs nothing extra.
Shot IDs go sh010, sh020, sh030, leaving gaps so you can insert sh015 later. Renumbering
changes seeds and invalidates renders. An ID is unique across the whole episode, not just its
sequence: continue the numbering (sh110 in the next sequence, or keep counting) rather than
restarting at sh010.
A shot’s ID is its identity, beyond its seed: its takes, its overrides and everything the
cut says about it (the pick, trims, lock, audio source, and whether it’s left out of the cut)
are kept by ID. So when revising a script:
- the same shot, rewritten: keep its ID. Its takes are flagged stale where the prompt changed, and the cut’s decisions about it still apply;
- a different shot: give it a new ID, and never reuse an ID you removed; the old one’s takes and cut decisions (a pick, trims, “left out”) would land on the new shot;
- a shot added between two others: an in-between ID (
sh065betweensh060andsh070), so every other shot keeps its ID; - a shot removed: just delete it; its takes stay on disk, and its cut entry is skipped. To try the cut without a shot, leave it out of the cut in the editor instead of deleting it.
Reference slots (H3 Ref2VA)
This section is about the default target,minimax_h3_ref2va. The other targets take no
slots (their limits are under Rendering a shot on …), but the three-subject rule is a
good habit everywhere: a shot about more than three things is usually two shots.
Every shot hands H3 four images. Slots 1–3 are the subjects — characters first, then props
and vehicles, in the order who: and with: list them. Slot 4 is always the location
plate.
That caps you at three subjects on screen, and a fourth is an error, not a silent drop.
When a scene has four characters, stage one out of frame, split the shot, or describe the
extra in the action text without referencing it. Crowds cost nothing that way — they just
won’t look the same from shot to shot, unless they are a group (one slot for all of them;
see A group: the same extras every shot).
A (V.O.) or (O.S.) speaker costs no slot, is never drawn, and needs no sheet — only a
voice in the series config. A shot may have no who: at all: an establishing plate with narration
over it.
Crowds and extras
On H3 Ref2VA a shot’s prompt states that exactly one person appears in it per referenced character, which is what stops H3 drawing the same face twice. The moment the action puts someone else in frame — a dance partner, a mob, a crowd at a door — that sentence contradicts the action, and H3 resolves the contradiction by duplicating the referenced character, often with interlace-looking smearing where the copies overlap.extras: names those people, so the prompt keeps identity locked for the subject and allows
everyone else:
A group: the same extras every shot
extras: people are invented fresh every shot, so they change sex, size and colour from
cut to cut. When the same few people recur — the ladies watching from the edge of the
ballroom, a family at the next table — make them one group subject: a character with
members, whose picture holds all of them.
who: or with:). It takes one slot however many people it
holds, which is how a shot gets more than three people who stay the same: two named
characters and a group of four is three subjects. The prompt defines it as a picture of N
different people and counts its members in the shot’s headcount (“Exactly six characters
appear in this shot: <Subject 1>, <Subject 2> and the four members of <Subject 3>”), which
is what keeps H3 from drawing the same woman twice. Put where they are in the action text
(“the ladies watch from the far wall, soft in the background”).
- The picture is one whole image of all of them (
sheet_panels: 1is implied; a group is never a four-panel sheet). Generated, it is a row of everyone head to feet, apart and facing the viewer, at the plate’s size. A picture you supply works the same way; keep every face and outfit visible, since a person half-hidden in the reference is one the model invents. - Describe each member in
design, with differences in age, build, hair and colour. A group of four identical gowns is read as one person four times. - It works on every target. H3 Ref2VA defines it in the headcount. LTX-2, Wan and H3 from keyframes call it “N different people, each appearing once” in their prose, and their reference sheets carry its picture whole, never cut to one panel.
- A group can speak (
voiceis one voice for all of them: a murmur, children giggling). - Twelve is the limit. A crowd bigger than that belongs in
extras:.
extras:: men and women, different ages and builds, hairnets instead of hard
hats, faces turned away or soft in the background.
On H3 Ref2VA, size: also decides what the plate means (besides the framing words; see
Faces need room): on a wide or medium the room’s layout
is kept, and on a close-up the background is a zoomed-in crop of the plate — the part of the room
right behind the subject — and never the plain backdrop of the character sheet. A close-up
still leaves the room’s layout to the shots around it, so stage the space on a medium first.
Add a prop to with: only when its exact design matters and recurs. A generic mug is better
described in the action text, because every referenced prop spends a slot.
Sequences
A sequence is one location, continuously. A new place — or the same place at a different time of day — starts a new# sequence. Intercutting is just alternating sequences: # sq03 kitchen, # sq04 phone_room, # sq05 kitchen.
Keep a sequence intact and vary the shots with plate: rather than splitting a scene into
one-shot sequences, which re-seeds every shot in it.
continuous: under the # header makes every shot after the first carry straight on from
the one before (see Continuous shots).
What goes on which line
These map to different fields in the generated prompt, and mixing them dilutes all three.- action — what is visibly happening, present tense, concrete and physical. Not motivation, not backstory, not what a character feels.
- camera — the move only.
- sound — ambience and physical action sounds: footsteps, fabric, doors, wind, impacts. Not dialogue, not score.
- music — audience-only score. Omit it on most shots; scoring is usually a conform decision.
Finish by validating
seriesmith check <episode folder> runs both.) The check compiles every shot for the
target it renders on, so it also reports each target’s limits.
Errors name the line and quote it. Common ones: a name in who: that is not in the series config; a
location that isn’t in the series config, or one with no description; an ALL-CAPS NAME: line for someone who cannot speak (usually a typo,
which would otherwise become action prose); more than three subjects on H3 Ref2VA; a shot
with neither dur: nor audio:; dur: auto on a shot with no dialogue; a dur: model
range that isn’t min-max seconds with min below max; a target: or profile: name that
doesn’t exist; a first: / last: that isn’t a method or an image path; a continuous:
the shot’s own target can’t render (latent off H3 Ref2VA, first on a target that reads
no first frame). Warnings cover
crammed dialogue, wasted grid padding, and what a target can’t do (a dialogue shot on Wan,
a clone shot on LTX).
A script that does not compile is not a draft, it is a bug. Fix and re-run until it is clean.