Scenes are organizational boundaries, not animation boundaries
This is the rule that separates a motion graphic from a slideshow. Nothing is cleared at a scene edge. A component that exists on both sides of a boundary keeps its identity and transforms across it. Only components that are genuinely leaving get an exit, and only genuinely new ones get an entrance.Writing a storyboard
Declare the scenes, then put objects in them.start, and a scene with no
duration takes an even share of whatever canvas time is left. You never author
absolute time: reordering two scenes is a list move, not a retiming pass over
hundreds of delays.
If the storyboard is longer than the canvas, the canvas is extended to fit it.
Scene properties
Why a scene has no window by default
A scene root is given astart — the time origin its children are measured
against — and deliberately not a duration. The engine culls a child once its
ancestor’s window closes, so writing the scene length onto the element would clear
the composition at every edge and put the slideshow back.
The length still exists; it lives on the storyboard, where the strip, the pacing,
and the boundary planner read it. It just is not a cage. Components that genuinely
leave are animated out at the boundary; components that persist simply persist. Add
clear when you actually want the old behavior.
Membership
scene NAME on any object — text, image, component, layout, showcase —
puts it in that scene. An object that already declares a parent (a layout slot, a
group, a showcase part) keeps it; the scene is then its ancestor.
Timing inside a scene is scene-local. A delay of 0s on a member of the third
scene means the start of the third scene, not the start of the film.
Shared components
Give a component that recurs the sameidentity:
identity exists so a component can change name, size, and role and still be
recognized.
Scene relationships
Every scene knows itsprevious and next. That is what lets Motionly plan a
boundary from both sides, and it is why continuity does not need to be hand-wired.
Boundaries and participation
At every boundary each component is classified:Transition kinds
There is no
fade. Fading the frame is what makes generated video feel like a
slideshow, and the doctrine forbids it: transform between shots, never dissolve.
Inference is usually right, because the storyboard already knows whether something
is shared. Override only when it is wrong.
Beats inside a scene
Scenes organize; beats change focus. A scene long enough to hold several turns of attention can carry beats inside it — the camera reframes the persistent composition without clearing anything.AI generation order
The AI is directed to build structure before animation:- Storyboard — how many scenes, what each is for, how long
- Scenes — one
sceneblock per storyboard entry - Contents — the components in each scene
- Shared identity — which components recur
- Boundaries — how each cut is crossed, derived from step 4
- Animation — only now, and only inside a scene
src/ai/storyboard-director.ts derives steps 1-5 deterministically from the
project’s duration and assets and hands the model compilable scene blocks, so the
two things it gets wrong most often — absolute timing and membership — are removed
from its job.
Migrating an old project
A project written before scenes existed is one long composition.migrateToScenes
lifts it into a storyboard without touching a single animation:
auto picks beats, then segment, then single. The migration is idempotent and
returns an AST, so the user reviews an ordinary .motion diff.
Old projects still compile untouched: the storyboard pass only engages for a project
that declares scene membership or storyboard intent.
Auditing a storyboard
npm run inspect:motion reports structural problems at the level they now live at:
Where the code lives
Scenes lower to the engine’s existing
scene element kind, which already owns a
background, a per-scene camera with depth parallax, an enter/exit envelope, and
parent-local time evaluation. The renderer, the evaluator, and the .motion format
are unchanged.