Narratomidocs
Writing

Stage

The beat that changes the 3D stage instead of the text: its thirteen action types and the parallel flag.

A stage beat (a stage direction) carries exactly one action and no text. It moves a character, turns them, plays a clip on them, changes an expression, moves the camera, places a prop, changes the light or the weather, starts or stops audio, fires a screen effect, or puts full-screen media over the stage.

This page is the field list. For what the stage actually is, how a scene is staged, and what each direction looks like, read Stage directions, Props and Staging a scene.

Fields

FieldTypeRequiredWhat it does
idstringyesStable beat id.
kind"stageDirection"yesThe discriminator.
actionobjectyesOne of the thirteen shapes below.
parallelbooleannoAbsent or false holds the script. See below.

The thirteen actions

typeFieldsNotes
movetarget (cast id), to (mark or "offstage"), gait, optional facegait is walk, jog, run or cut. face is applied on arrival and takes the same values as face.toward.
facetarget (cast id), toward (cast id, "camera" or "away")Turns the character in place.
animationtarget (cast id), clip (name), optional loopThe picker lists clips parsed out of your animation assets, plus assets by id. Free text is allowed for a clip embedded in the character's own model. loop: true makes the clip the resting idle.
camerapreset, optional target (cast id)wide, two-shot, close-up, over-shoulder. target frames that member instead of the speaker.
expressiontarget (cast id), expressionA select of the target model's own expression names when we have them, with a custom entry for free text; otherwise the six VRM presets: happy, angry, sad, relaxed, surprised, neutral.
propop (place / remove), asset or binding, at (mark or { heldBy })The asset must be a prop asset. See Props.
inspectasset or bindingOpens the orbit viewer on that prop. A hold the reader releases.
lightpresetday, dusk, night, candle, neon, storm.
weatherkindnone, rain, snow, petals, embers, fog.
musicop (play / stop), asset or binding, gain, fadeMs, loopLoops by default.
sfxsame as musicDoes not loop by default.
effecteffectshake, flash, or letterbox. Letterbox is a toggle: the second one turns it off.
cutawayop (show / end), asset or bindingOne op for both images and video. The player reads the asset's type.

gain runs 0 to 1 and the field says so when you type something outside that range. fadeMs is the fade in on play and the fade out on stop. All three audio extras are optional; left empty, the director's defaults apply.

One of each new one, as the row reads:

stage  move       Kai   to center  walk  then face Mira
stage  face       Mira  toward Kai
stage  animation  Kai   Sitting_Idle_Loop  loop
stage  camera     close-up  on Mira
stage  prop       place  lantern  held by Kai
stage  inspect    lantern
stage  light      night
stage  weather    rain

Naming an asset through a variable

The audio, cutaway, prop and inspect actions accept either a literal asset or a binding: the name of a declared text variable holding an asset id. Pick "asset from" in the row instead of "asset". A set theme = "m-storm" upstream then chooses the track, and the same stage beat plays whatever the story picked.

Naming both a literal asset and a binding on one action is INVALID_ASSET_BINDING: two answers to one question. So is binding to a variable that is neither asset-typed nor text. If the binding resolves to nothing usable (unset, not a string, or an asset id that is not in the library) the action still fires, just without audio or media. It fails quietly on purpose, the same way a pruned asset does.

Parallel, and the hold

parallel decides whether the script waits.

  • parallel: false (the default, checkbox clear) is a hold. The player emits the action and rests on this beat until the action's own chain resolves. A reader tapping the screen does not release a hold.
  • parallel: true runs the action alongside the beats that follow. Music under dialogue is the standard case.

The hold is why a non-parallel cutaway genuinely gates the next line until the clip ends, with no duration hard-coded anywhere, and why a non-parallel move gates it until the character arrives. The old recipe of a parallel cutaway followed by a wait beat is obsolete. Actions that only set state (face, prop, light, weather, camera, expression) resolve at once either way.

A held beat cannot be tapped past. If a story appears to freeze on a stage beat during preview, the action it is holding on never resolved: an asset that will not load, or a clip that is not there.

Inside a choice option

Stage beats are legal inside a choice option's inline body, and they edit exactly as they do at the top level, parallel included. That is how you fire one sting on one branch without spending a scene on it.

Compile-time errors you may see

ErrorCause
UNKNOWN_CASTA target, a face or toward naming a member, a prop's heldBy, or a camera target names no cast member.
MISSING_ASSETasset is not in the project library.
INVALID_CLIP_REFclip is a library asset id, but not an animation asset.
INVALID_PROP_ASSETA prop or inspect asset that is in the library but is not a prop.
INVALID_CUTAWAY_REFA cutaway show pointing at something that is neither an image nor a video, or at nothing at all.
INVALID_ASSET_BINDINGBoth asset and binding on one action, or a binding to a variable that is not asset-typed or text.

Camera presets, effects, gaits, light presets and weather kinds are enum-checked by the schema, so a bad one is INVALID_BEAT rather than a rule of its own.

On this page