A video engine for coding agents
motion.
A film is a Markdown screenplay plus one code file per scene. The engine checks the code against the script and shows the agent its own frames, so Claude Code can write and render a whole film on its own.
A product explainer for Redline Takeoff, written and rendered with motion in Claude Code. The score is mine, made in Ableton from the engine's stems and MIDI, and synced back to the picture.
01 · How a film is written
The script is the source of truth
Timing lives in one human-readable file. Scenes are plain code that read their cues by name, so moving a scene moves its cues, and a typo throws instead of drifting silently.
--- title: Redline explainer size: 1920x1080 fps: 60 bpm: 120 --- ## 01 · cold-open 0:00 → 0:06.5 > It's late. The bid closes at 9. | cue | at | what | sound | |----------|-------------|---------------------------|-----------| | tubes-on | +0.9 | four clock tubes ignite | ignite ×4 | | night | +2.5 → +5.1 | clock races 22:48 → 02:13 | ticks |
export default defineScene({ setup({ cues, motion }) { // components + anime.js timelines at cue times return { bank: NixieBank("22:48") }; }, draw(g, t, s, { cues, W, H }) { // pure function of t: same t, same frame s.bank.draw(g, t, { glow: cues.p(t, "tubes-on", 0.4) }); }, sound({ cues }) { return [{ at: "tubes-on", sfx: "ignite" }]; }, });
02 · The agent's loop
Write, check, look, render
Every step is a command the agent can run and read the result of. It never has to guess whether a scene looks right.
- 1
Write
Edit the screenplay and the scene files.
- 2
Check
mo checkGaps, overlaps, unknown or unused cues, missing sounds, unlicensed clips.
- 3
Look
mo stillsPNGs and a contact sheet of any scene, so the agent can see its frames.
- 4
Draft
--draftA 540p30 render of one scene in seconds.
- 5
Render
mo renderThe full film at 1080p60 with mixed audio.
03 · Design decisions
Built for an agent to drive
Deterministic frames
Everything is a pure function of time. No clocks, no unseeded randomness, nothing carried between frames. Any frame can be rendered alone and checked.
Mistakes fail loudly
Unknown cue names throw. Cues the code never reads get flagged. Scenes must butt up exactly, so timing bugs show up in mo check, not in the final cut.
A visual feedback loop
Stills and contact sheets turn "does this look right?" into something the agent can answer itself. When its timestamps drifted, it added mo scout to fix them.
Known traps have tests
Rendering pitfalls the agent hit once, like canvas replay and a library transform bug, now have regression tests so they can't come back.
Humans stay in the loop
mo handoff exports six stems, a mix, every sound event as MIDI, and a cue sheet for a DAW. Finished audio drops back in with one line of front matter.
No browser in the pipeline
Frames are drawn natively with Skia and piped raw into the Mac's hardware encoder. No headless browser, no PNG sequences.
04 · Frames from the film
Contact sheet
Click a frame to jump the film there.
05 · Under the hood
Specs
- Output
- 1080p60 H.264 + AAC; renders at 70–90 fps on one process
- Drawing
- skia-canvas, with Clay flexbox layout through a 146 KB WASM shim
- Animation
- anime.js, run headless: timelines never autoplay, the renderer seeks them
- Encoding
- Raw RGBA frames into Apple VideoToolbox
- Audio
- Synthesized sound design, Strudel patterns on the film's bar grid, bus mixing with reverb and kick-ducking
- Footage
- Clips listed in
clips.mdwith source and licence, fetched by section, decoded frame-exactly - Runtime
- Node, about 2,200 lines of engine and tests