Contents

M7 Re-direction

Re-direct an episode on a timeline, by hand or by chat. Every edit is a change set on the EpisodeIR, proposed, previewed and approved like any other, with undo and redo from the ChangeStore.

What exists

  • Edits (core/src/director/edit.ts, the edit_episode tool): move a cut, re-frame a shot (a size, or a named setup), hold a pause before a cue, delete a shot. The edited episode is compiled before it is proposed; the answer gives the running time before and after and the film-grammar findings, and a broken cut is refused.
  • Storyboard (render_preview storyboard): one still per shot, a row per scene, of an episode or of a proposal.
  • Poses keyed by hand (set_pose_key, EpisodeIR 1.63; docs/design/m6-performance.md Part 5): one of a character's poses keyed at a moment, over what the director made, anchored on the word, line or beat there. Directing the episode again keeps each pose whose scene still says what it was keyed by there, on someone still in the scene, and drops any other with a plain warning (core/src/director/kept-poses.ts), as it keeps a sung line's melody.
  • Re-directing from a moment (docs/design/redirect-episode.md): direct_episode from and to direct a stretch again and keep everything before it, and after it, as it was. Every edit marks what it changes (EpisodeIR 1.66 Scene.edited), and any re-direction keeps it.
  • OpenTimelineIO export (reelwright export otio).
  • Titles (docs/design/m7-titles.md): an opening title card and end credits in the show's style, which set_titles adds, re-times or removes.
  • The timeline (engine/addons/reelwright/ui/timeline/), as designed below, with tools/timeline-watch.sh running the watch-it against the real daemon. Two core additions keep it free of timing logic: a Timeline caption names its line (cue, as audio clips do), and pause_before takes bySec, the change a dragged line makes, so the core works out the pause the line had. (implementation) A cue with no timing of its own follows the cue before it in the scene's list, so after any edit a cue timed after one later in the list moves just after it, with what is placed with it: the twenty-fourth watch-it re-timed the tape's slap after its rip, and the Chief's "There.", following the rip, came before it.

Protocol additions

  • episode.timeline {episode, change?} → {timeline, episode, diagnostics}: the compiled Timeline of an episode (or of a proposal's version of it), with estimated takes for unvoiced lines, and the EpisodeIR it came from, both as canonical JSON text. The UI draws tracks from the Timeline and edits by the IR's scene, shot and cue ids.
  • tools.call {name, input} → {summary, proposals, previews, data?}: read and propose tools only (decisions keep their own methods: tool.decision). input is the tool's input as JSON text, like every free-form payload in the protocol. The timeline's direct manipulation is a tool call, the same one the showrunner makes from chat, so both paths produce the same change sets.

The timeline component (addons/reelwright/ui/timeline/)

Hosted in Studio's Timeline rail and the editor's bottom dock.

  • Tracks: Shots (one block per shot, its id and size or setup; cuts between them), Dialogue (one block per line, speaker and first words), Effects and Music (from the Timeline's audio clips), Captions. A ruler in seconds, scenes marked.
  • Playhead: clicking the ruler shows the still at that frame (previews.get still, cached); the shot block under the playhead highlights.
  • Playing: (implementation) Space (or the play button under the picture) plays the episode as it is now, live, with its sound, from the playhead: K pauses, L plays, J goes back three seconds, Left and Right step a frame (a second with Shift), Home and End go to either end. episode.playback {episode, change?} → {job, audio?, frameCount, fps, unvoiced, diagnostics} compiles it as episode.timeline does and writes a frames job over the whole Timeline at 540 px high (.reelwright/playback/<job id>/job.json, the newest four kept) and the program's sound beside it, mixed in one pass as 16-bit stereo without the loudness pass. Studio plays the job's Timeline with RwTimelinePlayer in a SubViewport (RwLivePlayer), the frame being the one the time played has reached, so a slow machine skips frames and keeps to the sound. Once it has played, the playhead shows every frame live, with no still to render; an edit reloads it. Lines with no take are timed from estimates and play silent; the play button's tooltip counts them, and "Voice N lines" in the header (episode.timeline now says unvoiced) voices them with episode.voice: the show's voices on this computer (Kokoro, free), into the take store every compile reads, so no document changes. The episode then compiles with their real timing and plays with them. A Studio audit found no way to watch an edit short of rendering the episode.
  • Edits:
    • drag a cut → edit_episode roll_cut to the frame it is dropped on (see Cuts);
    • a shot's menu → set_camera (sizes for framed shots, the set's setups for any), split_shot at the playhead, the cut in removed either way, or delete_shot;
    • drag a line → pause_before with bySec;
    • drag someone's business or a sound → set_timing with bySec, its end → set_timing with durationSec (see Retiming);
    • (implementation) a line in the inspector → "Record a take" (counting in at once) or "Takes…" opens the booth on it (docs/design/m6-recording.md), Studio's buttons through add_block_button. A line an actor recorded has a small mic before its words (episode.timeline recorded); its tooltip says whether a recording or the synthetic voice plays;
    • double-click a caption → set_caption (its text with the person's breaks, and how much later it shows and longer it stays), sending only what changed;
    • an effect's or music cue's menu → set_gain in steps from its gain, back to 0 dB, or muted. Sound blocks show their gain;
    • (implementation, product audit 2026-10d finding 10) the Mouths row, under Dialogue, folded away until the arrow before Dialogue's name or a line's "Draw its mouths" opens it (Studio remembers which; folded, every row keeps its place): each line's mouth shapes while its take plays, a block a run of one shape, lettered as Rhubarb letters them (from the Timeline's visemes), those drawn by hand in the accent. A mouth selected, the inspector says its shape in words and offers A to X: a shape chosen → set_mouth over it, and the shape is kept to draw with: a drag along the row → set_mouth over the frames it crosses, on each line spoken there. Esc puts the shape down; Delete or "Back to Rhubarb's" on a drawn one → set_mouth rhubarb. Each edit is a change set like chat's. (implementation) Made in Studio, it is the person's own (author user) and applied as made, with no ghost to review: Ctrl+Z undoes the last change applied while the show is open and Ctrl+Shift+Z (or Ctrl+Y) applies it again (RwStudio.undo/redo, the change store's undo and redo). A Studio audit found every trim credited to the showrunner, each one dragged, ghosted, reviewed and approved. The showrunner's proposals still show as a ghost over the current cut until approved or rejected in the proposal view, and the storyboard of the change renders. A block whose words or gain change is outlined like one that moves.
  • Inspector (implementation): click a block to select it (Shift- or Ctrl-click to add one or take it out); the inspector beside the picture (RwTimelineInspector, its close button and the header's sidebar button fold it away, and Studio and the editor remember which) says what it is in plain words and shows every property an edit can change. A shot: its camera, size (set_camera, framed or insert), setup, whom a framed shot frames, its turn, and its cuts in and out (roll_cut); a line: its speaker and words, emotion, intensity, pace, volume and a note to the actor (set_delivery), the pause before it (pause_before), its caption ("Edit caption…") and the take it plays; a sound: which, from where (set_sound), its gain (set_gain), a music cue's fade (set_fade); an action: what it is, whose, its own settings (a gesture's gesture, target, hand and intensity, a face's emotion, a look's target, turn and speed, a walk's destination, gait and speed, a posture, an effect, the lights…, each with its kind's op), when it starts against what it is timed from ("as “kid” in l04 starts", "0.3 s after l03 ends"), and how long it lasts where it has a length. (implementation) A gesture is picked from its character's rig's library (the rig read with docs.get of the character, the library from RwGestureLibrary, as the engine plays it, so a name the rig lacks cannot be typed), each with what it does as its tooltip and "(held)" where it can be held. What a cue is timed from is picked too ("Timed": after a cue ends, with a cue, or at a time; "From": the scene's cues by id and what they are; "On word": a line's words, for with), each one set_timing at: a new anchor keeps the cue where it plays (its gap, offset or time worked out from the blocks as drawn), a word puts it on that word, and another word of the same line keeps the offset it had. Each change is one edit, the person's own, applied as made and undone with Ctrl+Z; a number is sent once it rests, a word on Enter. Several selected: what they are, to nudge or delete together. A host adds a button for a kind of block (RwTimelineInspector.add_block_button): Studio's "Record a take" and "Takes…" on lines, which open the recording booth (docs/design/m6-recording.md). Everyone's looks are on their Action lanes now, so they can be selected too.
  • Retiming (implementation): drag someone's business, or a sound, along time to move it, or the end of one with a length of its own (a held gesture, a posture change, an effect, a shake, a float, a drift, a flight) to make it last longer or shorter. A drag lands on whole frames and snaps to cuts, the playhead, and where lines and their caption cards start and end (a card starts on a word); Alt places it freely. Drag a line, an action or a sound that is one of several selected (Shift- or Ctrl-click) and they all move by as many frames, each drawn where it goes as it moves, snapping by any of their edges (their own are not targets), dropped as one edit undone with one Ctrl+Z; a click on one of them, not dragged, selects it alone, and the end of one with a length or a cut still drags on its own. A group moves as a nudge does, by its leads: a block timed from another of them (a gesture on a word of a selected line, a line after one, a cut on a selected line's word, however far back) moves with it and has no edit of its own, or it went twice as far (a nudge of a line and its gesture did, before). With a block selected, comma and period nudge the selection a frame (ten with Shift) as one edit, Left and Right walk the blocks of its row, Up and Down the nearest on the row above or below, Delete removes it (a cue with its kind's remove, a shot with delete_shot; never a line, which goes from the script), Enter goes to the inspector and Esc lets it go. A move is set_timing: any cue re-timed against what it is timed from, the director's anchor kept (an after's gap, a with's offset from the same word, an atSec; a cue with no timing of its own is timed after the cue it follows, by name), and what is timed from it moves with it, the answer naming it ("e01, l04 move with it"). at times a cue afresh (after or with another cue, or at a time), refusing one timed from itself or from what waits on it; a cue that followed another still follows it. durationSec sets a length: a gesture's hold (0 lets it go), a posture's, an effect's or a float's (instead of until a cue), a shake's, a drift's, a flight's or a beat's; a line, a look, a walk or a sound has none of its own and says why. Before this, a gesture timed with a word could only be moved by giving it a new offset with set_gesture, which dropped the word.
  • Cuts (implementation): shots cover one continuous performance, so a cut is where one shot hands it to the next, and an edit of a cut never moves the performance. What an editor calls each edit comes down to that:
    • Roll (drag a cut): roll_cut to toSec (seconds into the scene) or bySec from where it falls now. The shot before gets longer and the one after shorter. The cut lands on that very frame (snap: frame), anchored the way the director anchors one, on the word, the cue start, or the end of the line or beat nearest it, with the offset to that frame; a line re-timed later takes its cut along on the word. A drag snaps (Alt off) to where lines and caption cards start, where lines end, where anyone's business or a sound starts, and to the playhead. A roll stops a frame short of the neighbouring cuts, and says how far it can go. move_cut still moves a cut against the anchor it has (chat's "half a second later", an OTIO import), and snaps to a pause if the cut did; a drag used it before and a cut snapped to silence did not land where it was dropped.
    • Trim and ripple: trimming a shot's head or tail is rolling its cut in or out, because the shot beside it takes or gives the time; nothing else can, as the performance runs on under every cut. "Ripple" means here that later shots keep their anchors: they stay on their words while one cut moves, which an anchored cut does of itself. With a shot selected, [ trims its head and ] its tail to the playhead; the inspector's "Cuts in" and "Cuts out" roll them by number, each with what it is anchored on.
    • Slip (drag a shot by its body): an animated performance cannot be shown at another time than it plays, so showing a later or earlier part of it in a shot moves the shot along the performance: slip_shot rolls both its cuts bySec, the shot keeps its length, and the shots either side give and take the time (what an editor calls a slide). The scene's first and last shots are held by its ends and roll instead.
    • Split (S, the shot's menu, the inspector): split_shot at atSec cuts the shot under the playhead there, anchored as a roll is; with no camera given the new shot frames what the split one does, without its move (a razor cut). A keyed shot's camera keys are split at the cut so the picture is the same frame for frame (splitKeys): the part before keeps the keys before the cut and the first after it, at its time past the new end (the camera is on its way there); the part after gets the keys after the cut and the last one before it (on a framed shot, with the keys before that a key staying in place hangs on), shifted to start at the cut, so the first ones are before 0 (where the camera comes from).
    • Remove a cut: delete_shot takes the cut between two shots away. The shot before runs on over the other's time, or with fill: "after" the shot after starts where the deleted one did ("Remove cut in" in the menu and the inspector, keeping either). These ops place a cut by when it plays, so edit_episode times the episode (as the edits before it leave it, episodeTiming in compile.ts, no framing) and hands applyEpisodeEdits that timing.
  • Transitions (implementation): a shot's inspector says how it comes in ("Comes in"), among the transitions its style allows (camera.transitions.allowed, read with docs.get of the Timeline's style), and over how long ("Over", not for a cut). set_transition sets the shot's transitionIn; a blend keeps the length it had unless given one, a cut has none. A transition the style does not use is refused by film grammar as the edit compiles, and a blend into the episode's first shot by the edit (nothing comes before it; the inspector does not offer one). The Shots row draws a transition over its shot's first frames, where the shot before still plays under it: a diagonal across the overlap, dark for a dip to black, named where it fits. The player renders every TransitionType: a cut and a smash cut cut, a dissolve, wipe and iris blend, a dip to black fades through black, and a whip swings both pictures left as one strip, smeared along the swing and fastest halfway (a dissolve stood in for it before).
  • Camera moves (implementation): a shot's inspector chooses its move from the style's (camera.moves.allowed; "None" holds still), with its own amount (the size a push or a zoom reaches, the degrees a pan, tilt or orbit turns, the meters a truck, dolly or crane travels, whom a follow rides with, how hard a shake goes), its easing, when it starts in the shot and how long it lasts. For a framed shot it also keys the framing the move ends on: a size, whom, a turn and a height, each the shot's own until changed, so the start key is the shot's framing (its size, subjects and turn above) and the end key is to (Move.to, EpisodeIR 1.41, the only addition the IR needed: the move types already said how a camera moves, but not that it ends on another subject, angle or height). Each change is set_camera with the whole move. The easing is picked from every Easing the schema has, each named in plain words (Linear, Ease in, Ease out, Ease in-out, Back in and out, Elastic, Bounce, Hold, then jump) with its curve drawn beside it and what it does as its tooltip and under the field, or "Style's own", named and drawn as the curve the style gives it (none for a shake or a follow, which do not ease from one framing to another). A posture change's easing is picked the same way (set_posture easing). Under the Shots row the Camera strip draws each move: a line where the camera holds, and between two diamond keys the curve it plays, read from the compiled camera keys (RwTimelineModel.move_curve: each key read as numbers that change in step with the move, where it looks, its lens and roll, its turn round that point, how far out and how high, set against the change from first key to last), so it is the move's own easing or the style's, overshoot and all, and right for a swing round a subject keyed every frame; a shake is drawn as a jitter that eases off; a key drags along time (snapping as a cut does, Alt for none) to start the move earlier or later with its end kept, or to end it sooner or later; clicked, the playhead goes to it and the picture opens live there (RwTimeline.preview_live), so dragging the playhead scrubs the move as it plays. The compiler solves both framings and eases between them at every frame (docs/design/m1-compiler.md, Moves).
  • Camera keys (implementation, EpisodeIR 1.50, product audit #12): a framed shot can be keyed instead of moved (camera.keys; a move with to is the two-key case, and either takes the other's place). The strip draws a keyed shot's keys where they are, and between each two the curve the camera plays there (RwTimelineModel.span_curve, the same numbers as move_curve plus the focus's inverse), rising from the foot to the head and falling back on the next span, so a push in and pull out reads as one rise and one fall and a span where only the focus changes still shows its ease; a held span is flat. A key drags along time (set_camera_key toSec); clicked, it is lit, the playhead goes to it, the picture opens live there and the inspector opens it with its shot (RwTimelineInspector.camera_key): when it is, its size, whom, turn, height and lens (each "The shot's" until changed), its focus and aperture, how the camera comes to it (by what changes, holding, or a move the style allows) and its easing, and "Remove key"; Delete removes it too. The key chosen is held by its time (RwTimeline._chosen_key_sec): an edit that moves it (a drag, "Key at") finds it again at its new time when the episode is read again, and one that removes it leaves none chosen. A key outside its shot (a split leaves the one the camera comes from before its start and the one it heads for past its end) sits at the shot's first or last frame on the strip. A key is added at the playhead with A then K, the Add menu's "Camera key" or the shot inspector's "Add camera key" (on a setup's or an insert's shot a key has only its time, focus, aperture and easing: a rack focus with the camera kept): the shot's first brings one at 0 s with it (the shot's own framing, for the camera to come from), and a new key holds the framing of the key before it until changed, so adding one changes nothing until it is. Every shot's inspector has its focus (all sharp, on one of the cast, or at a distance), aperture (f/1.4 to f/16) and handheld (the style's, or the shot's own from locked off to running).
  • Depth of field (implementation, Timeline 1.27): a focused shot view draws RwDepthOfField, a quad over the picture in its camera that blurs each pixel over the circle a thin lens of the camera's focal length and aperture spreads it into (f² / (N (s − f)) · |d − s| / d on the 36 mm film back, at most 2% of the width), read from the depth buffer: a fixed golden-angle spiral of 48 taps on mip levels as wide as their spacing, nearer blurred things spilling over what is sharp behind them (12 probes find them), and what is sharp kept clear of what blurs behind it. It is drawn first among the see-through things, so they draw over it sharp; a character's card is one of them, so off the focus it blurs itself (rw_character_card_blur.gdshader): its picture, grown by the blur, spread over the circle a point at its eyes blurs into, colour weighted by cover so its edge softens into what is behind it. The blur runs in a viewport of the card's own, over its drawing's, with no blending, and the card shows the result see-through with the standard material: a see-through 3D material that read the picture 24 times or more crashed lavapipe (Mesa 25.2.8), where the service and CI render (2026-10-14; 16 reads did not). Forward+ and Compatibility read their depth each their own way and otherwise draw it alike, so the browser blurs as a render does; a view makes it the first time a shot focuses and hides it while all is sharp, so a Timeline without focus draws the very pixels it did (the goldens).
  • Markers (implementation): a note pinned to a moment of a scene ("music hit", "fix the look"). They live in the EpisodeIR (Scene.markers, EpisodeIR 1.42), not in Studio's own per-show state, for three reasons: anchored to a cue or a word as a cut is, a marker stays on the moment it marks when a line is re-timed, which a time stored apart from the episode cannot; each change is an edit like any other, the person's own and undone with Ctrl+Z, and in the web edition it needs no storage of its own; and the showrunner reads and makes them in chat ("what's at the music hit?"). They change nothing that plays: the compiler resolves each to a frame (Timeline 1.19 markers, only when there are any, so every other Timeline is as it was). set_marker adds one at atSec with a name (mk01, mk02…, anchored by roll_cut's rule), renames, moves (atSec, or bySec from where it is) or removes one; a cue removed with a marker on it leaves the marker where the cue was, as it does a cut. On the timeline a marker is an amber flag on the ruler with its name and a faint line through the tracks: M marks the playhead ("Marker N"), Shift+M goes to the next marker and Alt+M (or Ctrl+Shift+M; not that alone, which a browser may keep) to the one before, a click puts the playhead on it, a drag moves it (snapping as a block does, Alt for none), a double-click names it, and its menu names or deletes it.
  • Stage: (implementation) A showrunner reading the cut could not see where anyone was. Beside the picture, or instead of it (the header's Picture / Stage / Both, V cycles them, kept in the timeline's view per show), the stage draws the scene's set from above at the playhead, upstage at the top (RwTimelineStage): the floor, each piece's footprint as a quiet shape with its name along it (a kit piece's from its recipe's footprintM, as core/src/generate/set/footprints.ts reads it; pipes overhead and screens on consoles left out), the walls with their doorways and windows, marks as small rings named on hover, entrances, the set's setups as faint cameras; each character as a disc in their timeline lane's color with a wedge the way they face and their name; props as small squares (in a hand, in the air or on their place); the shot's camera as a frustum in the accent color (its lens's horizontal field of view, RwLens); the scene's axis of action as a dashed amber line (its own axis, else its first exchange, as compile.ts reads it); and the shot's walks as faint arrows. Nothing is solved for it: positions, facings and the camera are the compiled Timeline's, sampled by the player's own samplers (RwActorSampler, RwCameraSampler, RwStageModel), and the set is docs.get's, so it is the same in a browser; no protocol was added. It follows the playhead, live while the episode plays. The wheel zooms about the pointer, a drag on the floor pans, and Fit shows the whole set with every camera of the scene. Drags make one edit_episode edit each, the person's own and undone with Ctrl+Z, previewed as a ghost with what it will do in words while dragged, and refused in the core's own words when it cannot apply. A character dropped on a mark (or beside a piece of the set, element:<id>) moves there at the playhead: before any line or business of the scene has started, where they start (set_mark with the character, their opening blocking; people start on marks, so a piece is refused there); while one of their walks is under way, that walk goes there instead (set_mark with its cue); otherwise a new walk from the playhead (set_move, timed with the latest line or business started by then and offset to the playhead, so it keeps its moment when the scene is re-timed: the core starts it on that very frame). Characters stand only on marks or by the set's pieces in this IR, so a drop anywhere else, or with Alt held (no snapping), is refused before anything is sent. The knob at the tip of someone's wedge turns them toward someone, a mark, a piece of the set or the camera, whichever lies nearest that way within 30°: a body look (set_look turn: "body"), the one under way turned there, else a new one timed as a walk is; there is no edit for the facing of the opening blocking, so a look is the turn. The current shot's camera dragged round what it looks at orbits it there: a framed shot's yawOffsetDeg turns by as much as it was dragged, the way the framing solver turns it (a group's or an insert's to the camera's right; a single's toward the side the camera stands on of the line its subject plays along, partnerOf's, so the drop lands where the ghost was); a setup's shot becomes a framing of whom it shows, at the size it shows them (set_camera size, subjects, yawOffsetDeg, from where it was dropped), and a setup that shows no one is refused. A click on a character, a prop or the camera selects their cue under way at the playhead (else their next, else their last), or the shot, on the timeline and opens it in the inspector; selecting a block shows whom or what it is about on the stage.
  • Chat: "hold on Otto longer" goes through the same tool, so chat edits appear on the timeline the same way.
  • Revising a proposal: edit_episode with change edits a proposal still waiting (a direct_episode not yet approved, or an earlier edit) instead of the episode on disk, which a new episode is not on yet. The result is its revision: it carries the proposal's other files (a revised screenplay) and supersedes it, so approving it rejects the original. episode.timeline with change shows a proposal's new episode the same way.
  • Delivery and sound: set_delivery changes how a line is said (emotion, intensity, volume, pace, an actor's note) and drops its recorded take so it is voiced again; set_sound adds, changes, repeats or removes a sound cue. The tenth watch-it's showrunner could neither bring out a "serenely" the director missed nor add a sound. (implementation) set_music starts or stops one of the show's music tracks, looping (EpisodeIR 1.28) or not, with a fade and a gain, timed after or with a cue; or changes or removes one by its cue id (new ones are uNN). set_fx adds, changes, aims (toward, EpisodeIR 1.17), unaims or removes an effect cue, on a character, a piece of the set or (implementation) a prop (EpisodeIR 1.21), and plays it until a cue (until, EpisodeIR 1.27), or for a length again (durationSec); the fifteenth watch-it shaped a coffee machine so its steam would land on Otto. (implementation) set_gesture adds, changes, holds, releases or removes a gesture cue (who, which gesture of their library, at whom, and when). The twelfth watch-it's Captain could not hold out her hand. set_expression adds, changes or removes a face someone pulls (who, which emotion, how strongly, and when); the thirtieth watch-it's showrunner could take out the Chief's nod but not the amused face with it. set_mess puts something on someone's face (soot, sand, snow, how much, and when), wipes it off (cover 0), or changes or removes one. set_damage leaves a mark on a piece of the set (a crack, a scorch, a dent or a stain; how big, where on it, and when), takes it away (acrossM 0), or changes or removes one. set_posture sets the posture someone opens a scene in, or adds, changes or removes a posture cue, and how it eases (easing; style gives it back the style's own); the nineteenth watch-it's Chief stood as the blackout opened, though he "stands up behind the console" later. set_move adds, changes, retimes or removes a walk (who, to a mark, an entrance or a character, gait, speed, in through an entrance, and when); the thirteenth watch-it's Captain set off back to the door before she had reached the Chief, and there was no edit to time her second walk from her first. set_look adds, changes, retimes or removes a look (who, at whom or what, eyes, head or body, how fast), and, naming a line, sets who it is said to without voicing it again; the fourteenth watch-it's Captain said "The rules are simple, Pilot" looking at the Chief. set_lighting lights a scene with another of its set's presets (revise_set adds one); the fifteenth watch-it's morning was lit for night, and nothing could change it. Timed after or with a cue, it changes the lights mid-scene instead (a lighting cue, EpisodeIR 1.18), and with cue changes or removes one; the nineteenth watch-it's blackout and the lights coming back on each had to be a scene of their own. set_prop removes a prop cue (remove), and clears a field with unset (a throw's recipient once it hits a wall: the thirty-third watch-it's first snowball kept the Chief as its target with his wall); a throw's place may be face, a hit. place_prop and set_prop may put a prop in or on another (place: prop.<name>, EpisodeIR 1.19), which carries it: the twentieth watch-it's pancake could not be in its pan.
  • Re-blocking: set_mark gives a character a new starting mark in a scene (whoever starts there takes their old one) or a move a new destination. The seventh watch-it had Otto at the Chief's bench and no way to move her. A move's destination may be a character, to walk up beside them where no mark is free (EpisodeIR 1.8), or a piece of the set (element:<id>), to walk up to it where no mark stands by it (EpisodeIR 1.16).
  • Turning a shot: set_camera's yawOffsetDeg turns a framed shot's camera round its subject (the ninth watch-it had a close-up of the back of the Captain's head, and no way to turn it). A setup keeps its own angle; subjects with a size take a shot off the set's setup and frame them (the seventeenth watch-it's showrunner added a cut instead).
  • Removing a cue: what is timed after or with it is timed from what it was timed from, the offsets added, and a shot cut on it is cut where it started; what ends on it (a float or a repeat until it) keeps it. The seventeenth watch-it left an empty walk in a scene because a beat was timed from it.
  • On purpose: a camera across the 180° line is refused like any grammar error, unless set_camera marks the shot crossesAxis with a note saying why (the shot's own note will do), the EpisodeIR's rule since M1; crossesAxis: false takes the mark off. The sixth watch-it's showrunner wanted a reverse from outside the porthole and had no way to say so.
  • Lighting that fades: (implementation) every lighting change was a cut, and nothing could dim the lights (the October product audit's finding 13). A lighting cue now has durationSec (a fade, up to 120 s), easing (ease_in_out unless given) and level (1 the preset as it is, 0.3 dimmed, 0 out; EpisodeIR 1.48). set_lighting takes all three on a new or changed cue; a level alone dims the preset lit then ("the lights slowly dim" is {after, level: 0.3, durationSec: 4}); a fade of 0 or a level of 1 takes them away, an easing with no fade is refused, and the scene's opening lighting has neither. set_timing's durationSec on a lighting cue sets its fade. The edit and the Set lane say what it does: "the lights fade to amber glow over 2 s", "the lights dim to 30% over 4 s", "the lights go out", "the lights come back up". On the timeline a change is as long as its fade, its end drags the fade (set_timing), and the inspector gives it Lights, Fade, Easing (while it fades), Level and "Scene opens" (set_lighting with no cue; on a shot too, once the set's presets are read). "Add a lighting change" on any block adds one after its cue (on a shot, after the cue playing at the playhead): the lights lit then fade to half over 2 s, or back up when they were dim, and the new change is selected to set its light. The heuristic director writes them from the script's words: a dim, a fade out (to the set's dark preset, else level 0), the lights back up, night falling or dawn breaking (a 10 to 20 s fade to the set's preset for that time, by its id, description or hour), moonlight through the blinds (a night preset with a blinds gobo); slowly, gradually and "over six seconds" set the fade, snap, suddenly and cut to keep it a cut. A model director is told the same.
  • An editor's timeline: (implementation; product audit 2, findings 11 and 12) What a pro reaches for in the first ten minutes. Ctrl+C, Ctrl+X, Ctrl+V and Ctrl+D copy, cut, paste at the playhead and duplicate: the clipboard holds cues and shots as the episode has them, so a paste into another episode works the same; edit_episode paste gives each cue a free id, keeps the timings among the pasted ones and times the rest with what plays where they land, writes a pasted line into the screenplay, and lays a shot over its length. I and O mark In and Out; lift (;) takes out what starts between them and re-times what followed it to stay where it was, extract (') takes the time out too, closing up the cut, and both take the lines out of the screenplay. The timecode under the picture takes one typed; J and L shuttle at 1×, 2×, 4× and 8× either way, the sound along up to 2×. Every sound draws its waveform (waveforms.get: a peak a hundredth of a second, made once per file and kept by hash), the meters read the playing sound, and each clip fades by handles at its corners (set_fade inSec, outSec; EpisodeIR 1.55 on lines, sounds and foley). The episode's mix (EpisodeIR 1.55 mix, Timeline 1.32 audio.tracks) sets each track's level, mute and solo, from a sound row's M and S or the mixer's strips (set_mix); it is what Studio plays and what renders, as an editor's export honours a muted track, and the compiler says so in its notes.

Captions (core/src/compile/captions.ts)

A caption has to be readable before it is anything else, so the compiler cuts a line's caption into cards: at most two rows of 42 characters (the broadcast convention). A line that fits is one card. A longer one breaks at its sentences, packed greedily; a sentence too long for a card breaks at its clauses (after , ; : and dashes), and a clause too long at its words. Each card shows from the take's timing of the word that starts it (the words the compiler already has for lip sync and word anchors), the first from the line's start and the last until its end; without word timings, by its share of the characters. An automatic card shorter than a second moves its break with a neighbour a word at a time, while both still fit a card and the neighbour keeps its second; failing that it joins a neighbour it fits on one card with, and otherwise stays short. A flash nobody can read is worse than a moved break, but a card never grows past two rows. (implementation) The first answer always joined the neighbour, and since greedy packing leaves no room in the card before, a quick line's last fragment made a card of three or four rows.

A person can override the cut on the line itself (EpisodeIR 1.3, LineCue caption): text with explicit breaks, a newline for a new row and a blank line for a new card, and offsets that show the caption later or keep it longer than the line. Written cards are kept however short. The text should say the line's words; changing them warns caption.mismatch, and its cards are then timed by characters, since the word timings no longer line up. The Timeline (1.4) gives each caption its card number under the line's cue, so the timeline draws one Dialogue block per line and one Captions block per card; WebVTT and SRT write a cue per card with its rows. Captions are not drawn into frames.

Later in M7

  • Music cues placed and stopped from the Music track (chat starts, stops and loops them with set_music, and tunes them with set_gain and set_fade).
  • The rest of a precise editor: curves and easing edited on the timeline for more than a camera move and a posture change (a gesture's or a walk's).

Watch it

Open the cold open in Studio's Timeline, drag the cut into the Chief's reply half a second later, approve it, and play the storyboard: the cut lands later, the running time in the proposal matches, and undo puts it back. Then double-click Otto's first caption, give "Chief!" a card of its own, and turn the scanner ping down 6 dB from its menu; approve both, and the rendered WebVTT has "Chief!" as its own cue (tools/timeline-watch.sh).