Describe what happens on screen.
A film is a sequence of scenes. Each scene places a product surface, schedules changes, and tells the camera where to look.
One plan controls the film.
- Scene
- A beat with one visible change and enough time to understand it.
- Rig
- A reusable product surface, such as a terminal, editor, or your own React screen.
- Event
- A change to a named rig, such as typing a command or clearing an error.
- Camera
- A view of the stage that follows the relevant product detail.
- VO-sync
- A shared timeline for the picture and your measured voice recordings.
Describe a scene.
After installation, replace src/film.ts with this five-second example. Run npm run studio and open ProductFilm.
import { defineFilm } from "./system/production";
export const filmSpec = defineFilm({
id: "first-film", fps: 30,
stage: { w: 1600, h: 900, bg: "#eceeea" },
scenes: [{
id: "build", min: 5, narration: "",
claim: "The build finishes successfully.",
rigs: [{
id: "shell", rig: "terminal",
slot: { x: 100, y: 100, w: 1400, h: 700 },
init: { cwd: "~/product" },
}],
events: [
{ id: "run", target: "shell", action: "cmd", at: 1.4,
args: { text: "npm run build", typedOver: 1 } },
{ target: "shell", action: "out", after: { event: "run" },
args: { segs: "Build complete." } },
{ target: "shell", action: "exit", at: 3,
args: { code: 0 } },
],
camera: { moves: [] },
holds: { settled: true },
}],
});See the complete film’s first scene
{
"id": "the-failure",
"claim": "The release check points to the wrong retry value.",
"min": 6,
"rigs": [
{
"id": "terminal",
"rig": "terminal",
"slot": {
"x": 100,
"y": 100,
"w": 1400,
"h": 700
},
"init": {
"cwd": "~/product",
"title": "Check the release"
}
}
],
"events": [
{
"id": "run",
"target": "terminal",
"action": "cmd",
"at": 1.5,
"args": {
"text": "npm run check",
"typedOver": 1
}
},
{
"target": "terminal",
"action": "spin",
"after": {
"event": "run",
"gap": 0.2
},
"args": {
"label": "Validating the release",
"dur": 1,
"ok": false,
"doneLabel": "Retry limit must be a number"
}
},
{
"target": "terminal",
"action": "out",
"at": 3.3,
"args": {
"segs": [
{
"s": "src/settings.ts:1",
"c": "cyan"
},
{
"s": " expected number, received string",
"c": "red"
}
]
}
},
{
"target": "terminal",
"action": "exit",
"at": 4.1,
"args": {
"code": 1
}
}
],
"camera": {
"moves": [
{
"to": "terminal",
"at": 0.3,
"over": 1.1,
"s": 1.04
}
]
},
"narration": "The release check catches a retry limit stored as text.",
"holds": {
"settled": true
}
}Change the film, then preview it.
The starter’s src/film.ts contains the complete film shown above. It starts with a failed check, fixes its source, and ends with passing checks. Replace that workflow with one your product supports.
How timing works
Times use seconds within the scene. at marks when an action lands. after follows another event’s landing time; its default gap is 0.7 seconds.
A command with at: 1.5 and typedOver: 1 starts typing at 0.5 seconds and finishes at 1.5 seconds. The compiler checks that actions and camera moves fit their scene.
Use your own React screen
A rig connects initial data, timed actions, and a React surface. The included portrait example shows a complete custom rig.