raea

The main entry: compositions, sequences, time, interpolation, springs, footage, sound and words.

View as Markdown

raea is the path nearly every composition starts from. A file registers its compositions with registerRoot; each <Composition> has a size, a frame rate, a length and a component. Inside it, useCurrentFrame() is the frame being drawn, <Sequence> shifts time for what it holds, and interpolate and spring turn frames into values. The entry also re-exports the footage, sound, word and state helpers, which have pages of their own.

TSX
import { AbsoluteFill, Composition, Sequence, interpolate, registerRoot, useCurrentFrame } from "raea";

function Title({ text }: { text: string }) {
  const frame = useCurrentFrame();
  const opacity = interpolate(frame, [0, 12], [0, 1], { extrapolateLeft: "clamp", extrapolateRight: "clamp" });
  return <AbsoluteFill style={{ justifyContent: "center", alignItems: "center", fontSize: 120, color: "#fff", opacity }}>{text}</AbsoluteFill>;
}

registerRoot(() => (
  <Composition id="main" width={1080} height={1920} fps={30} durationInFrames={90} component={() => (
    <AbsoluteFill style={{ background: "#000" }}>
      <Sequence from={0} durationInFrames={45}><Title text="Hello" /></Sequence>
      <Sequence from={45} durationInFrames={45}><Title text="world" /></Sequence>
    </AbsoluteFill>
  )} />
));

See Your first video for the whole loop, and Compositions for how frames, sequences and time work.

TS
import { AbsoluteFill, ACTION_KEY, actionsIn, Animate } from "raea"

raea exports 18 components, 8 hooks, 52 functions, 8 values, 91 types. Source: sdk/raea/src/index.tsx.

Components

AbsoluteFill

A box over the whole of its parent, laid out as a flex column; style is merged over that.

PropTypeWhat it does
styleCSSPropertiesmerged over the fill's own style (absolute, inset 0, a flex column)
classNamestringTailwind or CSS classes
childrenReactNodewhat fills it

Used in: ui/images/image_node, ui/images/ui_texture_slice_flip_and_tile, ui/images/image_node_resizing, ui/images/ui_texture_atlas_slice, ui/images/ui_texture_slice, ui/images/ui_texture_atlas, ui/layout/grid, ui/layout/ghost_nodes, and 95 more.

Animate

, memoised by its props' content (React skips a render whose props fingerprint matches the last). The fingerprint is on it as Animate.fingerprint for a runtime's own bailout. Its declaration is the engine's Animation (@bevy raea_core_animate::spec::Animation), typed from the registry (animate.gen.ts), sent as data-raea-anim and read back as that type by sdk/react animate.rs.

Also takes the props of AnimateOwnProps.

Audio

Sound in step with the frame; no picture. A muted or ended Audio is silent.

PropTypeWhat it does
src (required)string | GeneratedAsseta file URL, or a generated asset from lyria() or sao()

Also takes the props of MediaProps.

Clock

What time a composition is at: the frame, frame rate, size and length its hooks read, and its words, perception and input. The renderer, the live view and tests put one around every composition; a composition never needs its own.

PropTypeWhat it does
frame (required)numberthe composition frame to draw
fps (required)numberframes a second
width (required)numberin px
height (required)numberin px
durationInFrames (required)numberthe composition's length in frames
idstringthe composition's id ("main" by default)
defaultPropsRecord<string, unknown>the props the composition is rendered with
wordsreadonly TimelineWord[]the transcript, in composition frames, that captions and word cuts read
perceptionPerceptionwhat perception saw at this frame (faces, the safe area)
inputInputTimelinea game's recorded input by frame
childrenReactNodethe composition

Composition

Declares a composition inside the root. It draws nothing itself; a renderer finds it through registerRoot.

PropTypeWhat it does
id (required)stringthe composition's id: letters, digits and dashes (raea render --composition picks it)
component (required)ComponentType<P>the React component it renders
width (required)numberin px
height (required)numberin px
fps (required)numberframes a second
durationInFrames (required)numberits length in frames
defaultPropsPthe props it's rendered with (JSON-like values only)
editEdita hand edit laid over the composition (docs/craft-system.md, L): written back by the app's timeline

Used in: ui/images/image_node, ui/images/ui_texture_slice_flip_and_tile, ui/images/image_node_resizing, ui/images/ui_texture_atlas_slice, ui/images/ui_texture_slice, ui/images/ui_texture_atlas, ui/layout/grid, ui/layout/ghost_nodes, and 148 more.

Freeze

Shows its children as they are at frame, whatever the parent's frame.

PropTypeWhat it does
frame (required)numberthe frame its children see, whatever the parent's frame
childrenReactNodewhat's held

Img

An image; the renderer holds the frame until it has loaded and fails the render (naming src) if it can't.

Also takes the props of ImgHTMLAttributes (alt, crossOrigin, decoding, fetchPriority, height, loading, referrerPolicy, sizes, src, srcSet, useMap, width); HTMLAttributes (defaultChecked, defaultValue, suppressContentEditableWarning, suppressHydrationWarning, accessKey, autoCapitalize, autoFocus, className, contentEditable, contextMenu, dir, draggable, enterKeyHint, hidden, id, lang, nonce, slot, spellCheck, style, tabIndex, title, translate, radioGroup, role, about, content, datatype, inlist, prefix, property, rel, resource, rev, typeof, vocab, autoCorrect, autoSave, color, itemProp, itemScope, itemType, itemID, itemRef, results, security, unselectable, popover, popoverTargetAction, popoverTarget, inert, inputMode, is, exportparts, part); AriaAttributes (aria-activedescendant, aria-atomic, aria-autocomplete, aria-braillelabel, aria-brailleroledescription, aria-busy, aria-checked, aria-colcount, aria-colindex, aria-colindextext, aria-colspan, aria-controls, aria-current, aria-describedby, aria-description, aria-details, aria-disabled, aria-dropeffect, aria-errormessage, aria-expanded, aria-flowto, aria-grabbed, aria-haspopup, aria-hidden, aria-invalid, aria-keyshortcuts, aria-label, aria-labelledby, aria-level, aria-live, aria-modal, aria-multiline, aria-multiselectable, aria-orientation, aria-owns, aria-placeholder, aria-posinset, aria-pressed, aria-readonly, aria-relevant, aria-required, aria-roledescription, aria-rowcount, aria-rowindex, aria-rowindextext, aria-rowspan, aria-selected, aria-setsize, aria-sort, aria-valuemax, aria-valuemin, aria-valuenow, aria-valuetext); DOMAttributes (children, dangerouslySetInnerHTML, onCopy, onCopyCapture, onCut, onCutCapture, onPaste, onPasteCapture, onCompositionEnd, onCompositionEndCapture, onCompositionStart, onCompositionStartCapture, onCompositionUpdate, onCompositionUpdateCapture, onFocus, onFocusCapture, onBlur, onBlurCapture, onChange, onChangeCapture, onBeforeInput, onBeforeInputCapture, onInput, onInputCapture, onReset, onResetCapture, onSubmit, onSubmitCapture, onInvalid, onInvalidCapture, onLoad, onLoadCapture, onError, onErrorCapture, onKeyDown, onKeyDownCapture, onKeyPress, onKeyPressCapture, onKeyUp, onKeyUpCapture, onAbort, onAbortCapture, onCanPlay, onCanPlayCapture, onCanPlayThrough, onCanPlayThroughCapture, onDurationChange, onDurationChangeCapture, onEmptied, onEmptiedCapture, onEncrypted, onEncryptedCapture, onEnded, onEndedCapture, onLoadedData, onLoadedDataCapture, onLoadedMetadata, onLoadedMetadataCapture, onLoadStart, onLoadStartCapture, onPause, onPauseCapture, onPlay, onPlayCapture, onPlaying, onPlayingCapture, onProgress, onProgressCapture, onRateChange, onRateChangeCapture, onSeeked, onSeekedCapture, onSeeking, onSeekingCapture, onStalled, onStalledCapture, onSuspend, onSuspendCapture, onTimeUpdate, onTimeUpdateCapture, onVolumeChange, onVolumeChangeCapture, onWaiting, onWaitingCapture, onAuxClick, onAuxClickCapture, onClick, onClickCapture, onContextMenu, onContextMenuCapture, onDoubleClick, onDoubleClickCapture, onDrag, onDragCapture, onDragEnd, onDragEndCapture, onDragEnter, onDragEnterCapture, onDragExit, onDragExitCapture, onDragLeave, onDragLeaveCapture, onDragOver, onDragOverCapture, onDragStart, onDragStartCapture, onDrop, onDropCapture, onMouseDown, onMouseDownCapture, onMouseEnter, onMouseLeave, onMouseMove, onMouseMoveCapture, onMouseOut, onMouseOutCapture, onMouseOver, onMouseOverCapture, onMouseUp, onMouseUpCapture, onSelect, onSelectCapture, onTouchCancel, onTouchCancelCapture, onTouchEnd, onTouchEndCapture, onTouchMove, onTouchMoveCapture, onTouchStart, onTouchStartCapture, onPointerDown, onPointerDownCapture, onPointerMove, onPointerMoveCapture, onPointerUp, onPointerUpCapture, onPointerCancel, onPointerCancelCapture, onPointerEnter, onPointerLeave, onPointerOver, onPointerOverCapture, onPointerOut, onPointerOutCapture, onGotPointerCapture, onGotPointerCaptureCapture, onLostPointerCapture, onLostPointerCaptureCapture, onScroll, onScrollCapture, onScrollEnd, onScrollEndCapture, onWheel, onWheelCapture, onAnimationStart, onAnimationStartCapture, onAnimationEnd, onAnimationEndCapture, onAnimationIteration, onAnimationIterationCapture, onToggle, onBeforeToggle, onTransitionCancel, onTransitionCancelCapture, onTransitionEnd, onTransitionEndCapture, onTransitionRun, onTransitionRunCapture, onTransitionStart, onTransitionStartCapture).

InputRegion

Its children hear the pointer in their own box (x, y, w, h in points; the page's pixels are scale points each), as a panel does when it's a page of its own: a press inside the box is the box's until it's let go. Outside the box, and while another box holds a press, they see no pointer; keys reach every box.

PropTypeWhat it does
x (required)numberthe box's left edge, composition px
y (required)numberits top edge, composition px
w (required)numberits width, px
h (required)numberits height, px
scalenumberpage px over the box's own points (1): the pointer is divided by it
childrenReactNodethe game or panel that sees the pointer as its own

Loop

Repeats its children every durationInFrames frames, times times (forever by default).

PropTypeWhat it does
durationInFrames (required)numberthe length of one loop, in frames
timesnumberhow many times it plays (forever by default)
namestringits label in the timeline and the render manifest
layoutSequenceLayout"absolute-fill" (default) or "none", as a Sequence's
styleCSSPropertiesthe wrapping box's style
classNamestringthe wrapping box's classes
childrenReactNodewhat loops

Mix

The master: every sound in the composition brought to lufs integrated loudness (-14) under a true-peak limiter at ceiling dBTP (-1.5), as the platforms play back. Put one in the composition, around the soundtrack or anywhere.

PropTypeWhat it does
lufsnumberintegrated loudness the mix is brought to (EBU R128, LUFS)
ceilingnumberthe limiter's true-peak ceiling (dBTP)
childrenReactNodewhat it masters, when it's written around the soundtrack (): rendered as they are

Nudge

Moves its child by (x, y): an element gets the move in front of its own transform; a component, whose box it can't reach, moves inside a full-frame layer.

PropTypeWhat it does
xnumberhow far to move it, in the composition's pixels
ynumberhow far to move it down, in the composition's pixels
childrenReactNodethe part it places: an element, or a component, which moves inside a full-frame layer

Overlay

Its children only in a render asked for the overlay name.

PropTypeWhat it does
name (required)stringthe overlay's name, as the render asks for it
childrenReactNodewhat the overlay draws

Region

A box at the band its name stands for, clear of the face perception found at this frame.

PropTypeWhat it does
nameRegionNamethe band: "auto" (default) takes the larger of top and bottom; top and bottom stay clear of the face; center is the middle third; full is the safe area
marginnumberthe gap kept from the face and the sides, as a share of the width (0.06)
styleCSSPropertiesmerged under the box's own placement
classNamestringTailwind or CSS classes
childrenReactNodewhat goes in the band; useRegion() reads its box

Sequence

Shifts time by from and shows its children only for durationInFrames frames.

PropTypeWhat it does
fromnumberthe parent frame its frame 0 falls on (0)
durationInFramesnumberhow many frames it shows its children (forever by default)
namestringits label in the timeline and the render manifest (data-sequence)
layoutSequenceLayout"absolute-fill" (default) wraps the children in a full-size box; "none" adds no box
widthnumberthe width its children see, px (the parent's by default)
heightnumberthe height its children see, px (the parent's by default)
styleCSSPropertiesthe wrapping box's style
classNamestringthe wrapping box's classes
childrenReactNodewhat plays in it, at its own local time

Series

Plays its Series.Sequence children back to back, each shifted by its own offset.

PropTypeWhat it does
childrenReactNodethe Series.Sequence slots, played back to back

SongPlot

The map drawn for a human to check: section bands named, the energy curve with builds, stops, dips and drops on it, hits, the feature lanes, and the pacing (cuts per bar). raea song FILE --plot OUT.png renders it.

PropTypeWhat it does
map (required)SongMapthe song's map, from `raea song`
widthnumberin px
heightnumberin px
titlestringthe heading (the song's name, tempo, metre and length by default)

Stagger

Each child in its own , entrances each frames apart (or by grid distance). The same content as last render gives the same element back.

Also takes the props of StaggerProps (each, grid, exitEach); AnimateOwnProps.

Video

A video clip in step with the frame; data-source-time is the source time (seconds) to show.

PropTypeWhat it does
framing"face"ours: frame the take on the largest face
punchInnumberours: multiplies the framing's scale (1.15 is the usual)

Also takes the props of MediaProps.

Hooks

useCurrentFrame

The frame being rendered, counted from the start of the nearest enclosing Sequence.

TS
function useCurrentFrame(): number

Used in: ui/scroll_and_overflow/overflow_transform, ui/render_ui_to_texture, ui/ui_material, ui/styling/gradients, ui/text/text_debug, ui/text/text, ui/text/font_atlas_debug, 3d/fog_volumes, and 43 more.

useGameEvents

The frames, in order, at which isEvent(before, after) holds: after is the state step makes at frame f from before, the state at f - 1. It runs the same (kept) fold as useGameState through the composition's last frame, counted from the nearest enclosing Sequence, so sound can be cued to what happens in the game. While a person plays (live input) it runs only through this frame: what comes next hasn't been played yet. The list is read-only (frozen): the same one is handed out while nothing new happened, so copy it before changing it.

TS
function useGameEvents<S>(initial: S, step: Step<S>, isEvent: (before: S, after: S) => boolean): number[]

useGameState

The game's state at this frame: initial at frame 0, then step(state, input, g) applied for each earlier frame g in order. Frames count from the nearest enclosing Sequence, so a game starts when its Sequence does.

TS
function useGameState<S>(initial: S, step: Step<S>): S

Used in: shader/shader_prepass, shader/sprite_material.

useInput

This frame's input ({keys: []} when there was none). Its gamepads are Bevy's (bevy_gilrs's Gamepad entities, read by engine/render's gamepad_keys):

Bevy: bevy_input::gamepad::Gamepad.

TS
function useInput(): FrameInput

Used in: shader/shader_prepass, shader/sprite_material.

useRegion

The Region this is rendered inside: its name and box in composition px.

TS
function useRegion(): RegionBox

useSong

Where the song is at the current frame (frame 0 of the enclosing Sequence is offset seconds into the song), with the map bound to the composition's fps as song.

TS
function useSong(map: SongMap, options?: UseSongOptions): SongMoment & { song: Song; }

useVideoConfig

The settings of the composition being rendered (a Sequence's width and height win inside it).

TS
function useVideoConfig(): VideoConfig

useWords

Every word heard on the timeline, in the frames of the nearest enclosing Sequence.

TS
function useWords(): TimelineWord[]

Functions

actionsIn

The actions handed in this frame, in order.

TS
function actionsIn(input: FrameInput): { name: string; args: any; }[]

applyActions

state with this frame's handed-in actions run on it, in order (an unknown name is skipped).

TS
function applyActions<S>(actions: PanelActions<S>, state: S, input: FrameInput): S

curveFn

A curve name as a function (the engine's easing::Easing::parse, the same names).

TS
function curveFn(name: string, fps?: number): (t: number) => number

delay

The same move later by frames.

TS
function delay(m: MoveLike, frames: number): Move

fade

opacity 0 to 1 over frames (6).

TS
function fade(o?: { frames?: number; ease?: Curve; }): Move

feedIn

What the app tells the panels, by name ("transcript", "object"); undefined until it has.

TS
function feedIn<T = any>(input: FrameInput, what: string): T | undefined

fill

a bar filling: width 0 to to (100%) over frames (24), out-cubic.

TS
function fill(o?: { to?: number; frames?: number; unit?: "px" | "%"; ease?: Curve; }): Move

findPhrase

Finds the composition frame where phrase is said in a transcript.

TS
function findPhrase(words: readonly HeardWord[], phrase: string, options?: WordOptions): number

fish

Retired on 2026-11-05: Fish narration is no longer part of raea. Narrate with <Speech text start> from raea/speech (Pocket TTS, on this computer), or make a line with a raea gen step on fish:<model> and your own FISH_API_KEY. Kept as a name only, so an older edit says what to use instead of failing to bundle.

TS
function fish(text: string, _options?: Record<string, unknown>): never

getCompositions

The compositions the registered root declares, in order.

TS
function getCompositions(): RegisteredComposition[]

gridDelay

A grid item's distance from an origin, in steps (raea-animate's StaggerPattern::Grid, the same rule).

TS
function gridDelay(cols: number, rows: number, from: GridFrom, index: number): number

inState

Whether name is active in the snapshot (the leaf or any state around it), as XState's state.matches.

TS
function inState<N extends string>(snap: Snapshot<N>, name: N): boolean

interpolate

x mapped from the input range onto the output range, piece by piece: input rises, and the two have the same length. options.easing shapes each piece; extrapolateLeft and extrapolateRight say what happens outside the range (extend, the default, carries on; clamp holds the end value; identity returns x; wrap repeats).

TS
function interpolate(x: number, input: readonly number[], output: readonly number[], options?: InterpolateOptions): number

isGeneratedAsset

Whether a value is a generated asset (what sao, tokensynthNote and lyria return), not a file path.

TS
function isGeneratedAsset(v: unknown): v is GeneratedAsset

keyEdges

The input edges between two frames' keys, as events for a machine's on: "keydown:K" for each key pressed this frame, "keyup:K" for each released (keep last frame's keys in the game state to have prev).

TS
function keyEdges(prev: readonly string[] | undefined, now: readonly string[] | undefined): string[]

lyria

Music an older edit generated (30 seconds by default). Retired: a take already made plays, a new one is refused.

TS
function lyria(prompt: string, options?: { seconds?: number; }): GeneratedAsset

machine

A machine for contexts of type C, stepped with an env of type E (a game's frame input and world, a workflow's facts). Curried so the state names are inferred from the definition while C and E are given: machine<Player, Env>()({ id, initial, states }). A transition to a state that doesn't exist, or a guard reading a field C lacks, fails to compile; what types can't hold (an initial that isn't a substate, unreachable states, dead ends) throws here, when the module loads.

TS
function machine<C, E = unknown>(): <const N extends string, const K extends string = "sm">(config: MachineConfig<C, E, N, K>) => Machine<C, E, N, K>

measureSpring

How many frames a spring with these settings takes to settle (before any stretching).

TS
function measureSpring(opts: { fps: number; config?: SpringConfig; durationRestThreshold?: number; }): number

move

A move from its tracks, by property: move({ opacity: track({ 0: 0, 6: 1 }), y: track({ 0: 30, 6: 0 }) }). Its length is its last key. The named moves (rise, pop and the rest) are built with it.

TS
function move(tracks: Record<string, TrackSpec<string | number> | TrackSpec<string | number>[] | Keys<string | number>>): Move

overlays

The overlays this render was asked for ([] in a clean render and in live play).

TS
function overlays(): string[]

parallel

Every step at once.

TS
function parallel(...steps: Step[]): Group

pop

scale from (0.6), peak (1.08) at frames/2, 1 at frames (8); in over 3 frames.

TS
function pop(o?: { from?: number; peak?: number; frames?: number; ease?: Curve; }): Move

proofBoxes

Checks measured part boxes; returns one fault per problem, empty when all is well.

TS
function proofBoxes({ width, height, face, parts }: ProofInput): string[]

propsFingerprint

A props object's fingerprint: what and compare to know a render would give the same element, and what a runtime's bailout can key on (Animate.fingerprint).

TS
function propsFingerprint(props: object): number

pushIn

a slow push-in on footage: scale 1 to 1 + amount (0.04) across frames (90), linear.

TS
function pushIn(o?: { amount?: number; frames?: number; }): Move

regionBand

Works out the vertical band each name stands for, given perception and the composition size.

TS
function regionBand(name: RegionName, width: number, height: number, perception: Perception, margin?: number): Band

registerRoot

Names the root component the renderer starts from, and records its compositions. Call it once.

TS
function registerRoot(given: ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentType): void

Used in: ui/images/image_node, ui/images/ui_texture_slice_flip_and_tile, ui/images/image_node_resizing, ui/images/ui_texture_atlas_slice, ui/images/ui_texture_slice, ui/images/ui_texture_atlas, ui/layout/grid, ui/layout/ghost_nodes, and 148 more.

replayDecider

A decider that replays recorded decisions: log[machine][n] is the edge chosen at that machine's step n (missing: wait). How a model's or a person's choices, taken outside the step, re-enter it exactly.

TS
function replayDecider(log: Record<string, Record<number, number | { edge: number; evidence?: unknown; }>>, name?: string): Decider

reverse

A move played backwards: it leaves the way it came (each curve reversed, so an out-curve becomes the matching in-curve). An exit is its entrance reversed.

TS
function reverse(m: MoveLike): Move

rise

y offset distance to 0 over frames (30 px over 6), fading in over fade (5).

TS
function rise(o?: { distance?: number; frames?: number; fade?: number; ease?: Curve; }): Move

sampleAnimation

What an Animation sets at composition frame frame: page style keys, a counter's text, or 3D props (raea-animate's Sampled, here for plain bun).

TS
function sampleAnimation(a: Animation, frame: number): { style: Record<string, string | number>; text?: string; values: Record<string, string | number>; }

sao

A sound effect to generate (2 seconds by default).

TS
function sao(prompt: string, options?: { seconds?: number; }): GeneratedAsset

sequence

Each step when the one before it ends (gap frames apart: sequenceGap).

TS
function sequence(...steps: Step[]): Group

sequenceGap

Each step when the one before it ends, gap frames later (a negative gap overlaps them).

TS
function sequenceGap(gap: number, ...steps: Step[]): Group

slam

a hit: scale from (1.3), dip (0.96) at frames/2, 1 at frames (8); in over 2 frames.

TS
function slam(o?: { from?: number; dip?: number; frames?: number; ease?: Curve; }): Move

slide

arrives from a side: distance px (30) over frames (7), fading in over 5. from is where it comes from.

TS
function slide(o?: { from?: Dir; distance?: number; frames?: number; ease?: Curve; }): Move

song

A song map bound to a frame rate (and where frame 0 sits in the song): frames from song times, and the reverse.

TS
function song(map: SongMap, options: SongOptions): Song

songAt

Where the song is at t seconds: a pure function of the map.

TS
function songAt(map: SongMap, t: number): SongMoment

spring

A damped spring's value at frame: from from (0) to to (1), started delay frames late, by its config (mass 1, damping 10, stiffness 100). It overshoots and settles unless overshootClamping is set; durationInFrames stretches it to end at that frame. measureSpring says how long one takes to settle.

TS
function spring(opts: SpringOptions): number

stagger

The parts each frames apart, each with m. With grid, delays spread by grid distance from an origin.

TS
function stagger(parts: string[], each: number, m: MoveLike, grid?: { cols: number; rows?: number; from?: GridFrom; } | undefined): Group

stateOf

The active leaf of a snapshot (undefined before the first step).

TS
function stateOf<N extends string>(snap: Snapshot<N>): N | undefined

staticFile

The URL of a file in the space's media folder, each path segment URL-encoded.

TS
function staticFile(path: string): string

Used in: ui/images/image_node, ui/images/ui_texture_slice_flip_and_tile, ui/images/image_node_resizing, ui/images/ui_texture_atlas_slice, ui/images/ui_texture_slice, ui/images/ui_texture_atlas, ui/layout/grid, ui/layout/ghost_nodes, and 100 more.

stepAll

One frame for each entity of a list, each carrying its own machine (one per enemy), in order.

TS
function stepAll<C, E, N extends string, K extends string>(m: Machine<C, E, N, K>, entities: readonly C[], env: E, opts?: readonly string[] | StepOptions): C[]

strike

a strike-through line drawn: width 0 to 100% over frames (8).

TS
function strike(o?: { frames?: number; ease?: Curve; }): Move

tick

a number counting from from (0) to to over frames (24), written as the element's text: digits decimals, separator between its thousands ("," or true writes 12,345; none by default), prefix and suffix around it ("quot;, " pts"). Hidden until it starts, then in over fade frames (2; 0 shows it at from the whole time).

TS
function tick(o: { to: number; from?: number; frames?: number; digits?: number; ease?: Curve; prefix?: string; suffix?: string; separator?: string | boolean; fade?: number; }): Move

tickClocks

Tells every mounted Clock's frame readers that the frame is about to move on, in the same batch as the update that moves it, so they render in that one commit. A host that steps frames back to back calls it with its frame update: else each Clock tells them as its frame commits, a second commit each frame, and React stops a chain of more than 50 (raea's bake steps a range of frames as one chain: many_cubes stalled at frame 26).

TS
function tickClocks(): void

timeline

Steps placed in time (a sequence of them). Each part's start is decided here, once.

TS
function timeline(...steps: Step[]): Plan

toMove

A name, a move or several moves together, as one move.

TS
function toMove(m: MoveLike): Move

track

A track: track({ 0: 30, 6: 0 }) is a 30 px rise over 6 frames, out-cubic by default.

TS
function track<V = string | number>(keys: Keys<V>, ease?: Curve | Curve[], opts?: Omit<TrackSpec<string | number>, "ease" | "keys">): TrackSpec<V>

transitionOf

The transition a step took, read from two snapshots of one machine (null when none fired): how a trace that only sees states (a playtest over a game's pure fold) recovers the TransitionRecord a sink would have had, minus evidence.

TS
function transitionOf(m: AnyMachine, before: Snapshot<string> | undefined, after: Snapshot<string>): TransitionRecord | null

wipe

a reveal wiping across from from (left) over frames (8), in-out-cubic, by clipping.

TS
function wipe(o?: { from?: Dir; frames?: number; ease?: Curve; }): Move

word

The composition frame where phrase is said. Call it while rendering (it reads the Clock).

TS
function word(phrase: string, options?: WordOptions): number

Values

ACTION_KEY

The prefix the app puts on an action handed in as input: a key action:NAME ARGS_JSON, held for one frame.

curve

Curve helpers: curve.bezier(0.05, 0.7, 0.1, 1), curve.spring({ damping: 15, stiffness: 120 }).

Easing

The easing curves, each a function of progress 0..1: linear, quad, cubic, poly(n), sin, circle, exp, back, elastic, bounce and bezier(x1, y1, x2, y2), eased in as they are; Easing.out(f) and Easing.inOut(f) turn one round. Pass one as interpolate's easing.

FEED_KEY

The prefix of the keys the app hands every panel for what it knows: feed:transcript (the conversation's last lines, [{ who: "you" | "agent" | "tool" | "note", text, live }]), feed:object (the object on the stage: { name, kind }) and feed:stage (what the object publishes with data-feed-publish, as a panel's publishes reach the object) and feed:player (the stage's player: { frame, frames, rate, playing }; frames is 0 for a game, which runs on). Handed in only on the frame it changes (and when the panel opens), so keep it in state: useGameState([], (s, input) => feedIn(input, "transcript") ?? s). A panel standing in for the terminal sends by publishing { send: { n, text } } (a higher n is a new message); a panel drives the player by publishing { control: { n, do: "play" | "pause" | "seek", frame } } the same way.

firstDecider

The default decider: the first candidate.

MEDIA_ROOT

Where the space's media folder is served from.

moves

The named moves by name, as enter="rise" finds them.

SPACE_KEY

The prefix of the key the app holds on the stage for each panel that publishes (data-feed-publish on an element): space:PANEL JSON, held while the value stands, so the object on the stage reads what the panels picked.

Types

AbsoluteFillProps

The props of AbsoluteFill, tabled there.

Action

An action: a pure function returning the new context (never a changed old one).

TS
type Action = (ctx: C, env: E) => C

Actions

TS
type Actions = Action<C, E> | readonly Action<C, E>[]

Analysis

FieldTypeWhat it is
id (required)stringthe machine's id
states (required){ name: N; parent: N | null; depth: number; kind: "leaf" | "compound" | "final"; initia…every state with its parent, depth, kind and whether it's an initial state
edges (required)Edge<N>[]every transition
reachable (required)N[]states some sequence of transitions reaches from the initial state (guards assumed satisfiable)
unreachable (required)N[]states no sequence of transitions reaches
deadEnds (required)N[]non-final leaves with no transition out (their own or an enclosing state's): once entered, never left

AnimateOwnProps

FieldTypeWhat it is
enterMoveLikethe entrance: a move's name, a move, or several together
exitMoveLikethe exit, played at exitAt (an entrance reversed: exit="rise" sinks back out)
animateRecord<string, TrackSpec | TrackSpec[] | Keys> | Movefree tracks by property, in local frames: { backgroundColor: track({ 0: "#fff", 20: "#000" }) }
atnumberlocal frame the entrance starts (0)
exitAtnumberlocal frame the exit starts
timelinePlana timeline's plan and this element's part in it: the part's move, at its start (plus at)
partstringthe part in `timeline` whose move this element plays
mount"during" | "always""always" (default): in the tree, and its layout, the whole time (invisible before an entrance that fades in); "during": only from the entrance's start until the exit ends (it takes its space when it arrives)
asstringthe element: "div" by default
styleCSSPropertiesinline style
classNamestringTailwind or CSS classes
childrenReactNodewhat moves

AnimateProps

TS
type AnimateProps = AnimateOwnProps & { [attr: string]: unknown }

Animation

One element's declared animation.

Rust: raea_core_animate::spec::Animation.

FieldTypeWhat it is
origin (required)numberthe composition frame the element's local frame 0 falls on (where its Sequence starts)
freeze (required)number | nulla local frame to hold at whatever the composition's frame (inside a Freeze)
fps (required)numberthe frames per second its frames count; springs measure their settle time with it (0: the clock's)
tracks (required)(AnimTrack)[]the element's keyframed properties, one track each
show_from (required)number | nullthe local frame it's shown from, when it shows only for a window (mount="during"); before it, display none
show_until (required)number | nullthe local frame it's hidden from again

AnimKey

One key: a value at a local frame, and the curve from it to the next key.

Rust: raea_core_animate::spec::AnimKey.

FieldTypeWhat it is
at (required)numberthe local frame it's at
value (required)numbera number property's value there
color (required)stringa colour property's value (CSS text); empty for numbers
ease (required)stringthe curve to the next key (easing::Easing::parse); empty is linear

AnimTrack

Keyframes on one property.

Rust: raea_core_animate::spec::AnimTrack.

FieldTypeWhat it is
prop (required)stringthe property it keys: opacity, x, y, z, scale, rotate, width, height, blur, clip, a colour, text, or another number
keys (required)(AnimKey)[]its keyframes in frame order
unit (required)stringa length's unit: "px" (when empty) or "%"
repeat (required)stringpast the last key: "" or "hold", "loop", "pingpong" (for ever), or "loop:N" / "pingpong:N"
digits (required)numberdecimals a text number is written with
prefix (required)stringwritten before and after a text number (a counter's "quot; and " pts")
suffix (required)stringwritten after a text number
separator (required)stringbetween a text number's thousands ("," writes 12,345); empty: none

AnyMachine

TS
type AnyMachine = Machine<any, any, string, string>

AssetKind

TS
type AssetKind = "lyria" | "sao" | "tokensynth"

AudioProps

The props of Audio, tabled there.

ChoicePoint

A choice point as a decider sees it: which machine, where, and the candidates whose guards hold.

FieldTypeWhat it is
machine (required)stringthe machine's id
state (required)stringthe state whose choose list this is, and the active leaf
leaf (required)stringthe active leaf state
n (required)numberthe machine's step
candidates (required){ edge: number; to: string; description?: string }[]the candidates whose guards hold, in their order (each an edge of machine.edges)
ctx (required)Cthe context the machine drives
env (required)Ewhatever the step was given as env

ClockProps

The props of Clock, tabled there.

CompositionProps

The props of Composition, tabled there.

Curve

TS
type Curve = CurveName | (string & {})

CurveName

Curve names. Any of these, or bezier(x1,y1,x2,y2), steps(n), spring(mass,damping,stiffness), reverse(<curve>).

TS
type CurveName = | "linear" | "ease" | `${"in" | "out" | "in-out"}-${"quad" | "cubic" | "quart" | "quint" | "sine" | "expo" | "circ" | "back" | "elastic" | "bounce"}`

CutOptions

FieldTypeWhat it is
by"section" | "bar""section" (default) takes each section's rate, steady across it; "bar" each bar's own
scalenumbermultiplies every rate (2: twice as many cuts), kept on the ladder 0.25..4
dropsbooleancut on every drop (default true)
stopsbooleancut on a stop's hits (default true)
buildsbooleandouble the rate through a build's second half (default true)
minGapnumbercuts closer than this many frames are merged, the earlier kept (default a quarter second)
fromnumberfirst frame (inclusive), default 0
tonumberlast frame (exclusive), default the song's end

Decider

Picks a transition at a choice point. Called inside the step, so it must answer synchronously: a model or a person is asked outside the step and their answer replayed (replayDecider). Deterministic deciders keep a fold pure.

FieldTypeWhat it is
name (required)stringits name in the trace's by column
decide (required)(point: ChoicePoint<unknown, unknown>) => Decisionpicks a candidate at a choice point, synchronously

Decision

What a decider answers: the edge it picks (one of the candidates' edge), or null to wait this step; evidence is whatever supports the choice (a bot's score, a model's probabilities), recorded beside the transition.

FieldTypeWhat it is
edge (required)number | nullthe edge picked, one of the candidates' edge; null waits this step
evidenceunknownwhat supports the choice (a bot's score, a model's probabilities), recorded with the transition

EasingFn

TS
type EasingFn = (p: number) => number

Edge

FieldTypeWhat it is
index (required)numberits place in machine.edges
from (required)Nthe state it leaves
to (required)Nthe state it enters
kind (required)"always" | "after" | "on" | "done" | "choose"what fires it: a guard polled each step (always), a delay (after), an event (on), the substate finishing (done) or a decider (choose)
eventstringthe event an on edge waits for
after (required)numbersteps in from before it may fire
guarded (required)booleanwhether it has a guard (when)
descriptionstringwhat the transition means, from its config

Edit

A hand edit: segments are the composition's own frame ranges, [from, to), played one after another, so a trim, a split, a cut word or a moved span is a change to this list; the length becomes their sum.

FieldTypeWhat it is
segmentsreadonly (readonly [number, number])[]the composition's own frame ranges, [from, to), played one after another

ExtrapolateMode

TS
type ExtrapolateMode = "extend" | "clamp" | "identity" | "wrap"

FrameInput

One frame's input for a game.

FieldTypeWhat it is
keys (required)string[]the keys held (KeyboardEvent.key names: "ArrowLeft", "a", " ")
pointer{ x: number; y: number; down: boolean }the primary pointer in composition px, and whether it's pressed
buttonsstring[]the mouse buttons held besides the primary one: "Right", "Middle", "Back", "Forward" (Bevy's MouseButton names)
wheel{ x: number; y: number }the wheel turned this frame, in CSS px, down and right positive (the DOM's deltaX and deltaY)
gamepads{ buttons: string[]; axes: Record<string, number> }[]each connected gamepad: the buttons held and the sticks' and triggers' axes, by Bevy's GamepadButton and GamepadAxis names ("South", "DPadUp", "RightTrigger2"; "LeftStickX" -1..1, "LeftZ")
touches{ id: number; x: number; y: number }[]the fingers down, in composition px

FrameRange

FieldTypeWhat it is
fromnumberfirst frame (inclusive), default 0
tonumberlast frame (exclusive), default the song's end

FreezeProps

The props of Freeze, tabled there.

GeneratedAsset

FieldTypeWhat it is
kind (required)AssetKindwhich generator makes it: lyria (music), sao (sound effects) or tokensynth (an instrument's note)
prompt (required)stringwhat to make, in words
seconds (required)numberhow long it is
id (required)stringa stable hash of kind, prompt and seconds
src (required)string"asset:/"
optionsRecord<string, unknown>the generator's own settings (a TokenSynth note's midi, velocity, seed and device)

GridFrom

TS
type GridFrom = "top-left" | "top-right" | "bottom-left" | "bottom-right" | "center" | "top" | "bottom" | "left" | "right"

Group

FieldTypeWhat it is
kind (required)"sequence" | "parallel"sequence: one after another; parallel: together
steps (required)Step[]its steps, in order
gap (required)numberframes between steps of a sequence (negative overlaps)

Guard

A trigger: polled each step while its state is active (the context, and whatever the step passes as env).

TS
type Guard = (ctx: C, env: E) => boolean

ImgProps

The props of Img, tabled there.

InputTimeline

Recorded input by composition frame; frames without an entry had no input.

TS
type InputTimeline = Record<number, Partial<FrameInput> | undefined>

InterpolateOptions

FieldTypeWhat it is
easingEasingFn | EasingFn[]the curve between keyframes: one for all, or one a segment
extrapolateLeftExtrapolateModebelow the first keyframe: extend the line (default), clamp to it, identity (the input itself) or wrap
extrapolateRightExtrapolateModepast the last keyframe: extend (default), clamp, identity or wrap

Keys

Keyframes by local frame: numbers, or colour text for colour properties (a material's animate takes other values for its own fields, LinearRgba for an emissive).

TS
type Keys = Record<number, V>

LoopProps

The props of Loop, tabled there.

Machine

FieldTypeWhat it is
id (required)stringthe machine's name in traces and reports
key (required)Kthe context's field holding its snapshot ("sm")
states (required)readonly N[]every state, in definition order (outer before inner)
edges (required)readonly Edge<N>[]every transition, in the order they're checked within a state
start (required)() => Snapshot<N>a snapshot before the first step: the first step enters the initial states (running their entry actions)
step (required)(ctx: C, env: E, opts?: readonly string[] | StepOptions | undefined) => COne step: poll the active states' transitions (innermost first, then outward; within a state on for this step's events, then always, after, onDone, then the choose candidates for the decider), take the first that fires (at most one a step), then run the active states' tick actions. Returns the new context with its snapshot; the old one is unchanged. The third argument is this step's events, or StepOptions.
state (required)(ctx: C) => Nthe active leaf (the initial leaf before the first step)
path (required)(ctx: C) => N[]the active states, outermost first
is (required)(ctx: C, name: N) => booleanwhether name is active (the leaf or a state around it)
steps (required)(ctx: C, name?: N | undefined) => numbersteps since name (the leaf by default) was entered; -1 when it isn't active
entered (required)(before: C, after: C, name?: N | undefined) => booleanwhether the step from before to after entered name (any state when omitted)
watch (required)(ctx: C) => Watchedthis machine's state in ctx, for a trace
analyze (required)() => Analysis<N>the static analysis machine checks read

MachineConfig

FieldTypeWhat it is
id (required)stringthe machine's name in traces and reports
initial (required)NoInfer<N>the state it starts in
states (required){ [S in N]?: StateConfig<C, E, N> }its states by name, each a StateConfig (substates nest inside)
keyKthe context's field holding the snapshot ("sm")
strictbooleanrefuse unreachable states and non-final dead ends when the machine is built (true)

MediaProps

FieldTypeWhat it is
src (required)stringthe file: staticFile("clip.mp4"), or a generated asset
startFromnumberthe media's own frame it starts playing from (0); the same as trimBefore
endAtnumberthe media's frame it stops before (exclusive): it holds the last frame, or loops; the same as trimAfter
trimBeforenumberframes of the media cut off its start (the newer name for startFrom)
trimAfternumberthe media's frame it's cut at (the newer name for endAt)
volumeVolumeProplinear gain, 1 being unity (0.5 is about -6 dB, 1.78 about +5 dB), or a function of the media's own frame
gainDbVolumePropours: the gain in decibels (or a function of the media's own frame returning it); wins over volume
fadeInnumberours: seconds to ramp the sound in from silence at its start (applied by the renderer at the audio's rate)
fadeOutnumberours: seconds to ramp the sound out to silence at its end
playbackRatenumberhow fast it plays (1): 2 is double speed
mutedbooleanplay no sound
loopbooleanstart again from startFrom when it reaches endAt
busstringthe bus it plays into: a named channel of the edit's Tone graph (music, sfx, voice, ambience, ui), so it takes that bus's volume, effects and ducking (raea/tone buses)
namestringthe entity's name, for picking, the inspector and world.*
classNamestringTailwind or CSS classes
styleCSSPropertiesinline style

MixProps

The props of Mix, tabled there.

Move

Tracks by property, in frames from the move's own start.

FieldTypeWhat it is
tracks (required)Record<string, TrackSpec | TrackSpec[]>keyframes by property, in frames from the move's start
frames (required)numberhow long it runs (its last key)

MoveLike

TS
type MoveLike = MoveName | Move | MoveLike[]

MoveName

TS
type MoveName = "rise" | "pop" | "slam" | "slide" | "wipe" | "fill" | "strike" | "pushIn" | "fade"

NudgeProps

The props of Nudge, tabled there.

PanelAction

One action: what it does (for the agent), its arguments by name with a few words each, and what it does to the panel's state.

FieldTypeWhat it is
about (required)stringwhat the action does, for the agent
argsRecord<string, string>its arguments by name, a few words each
run (required)(state: S, args: A) => Sthe panel's state after it

PanelActions

TS
type PanelActions = Record<string, PanelAction<S>>

Perception

What perception saw at this frame: the largest face, and the platform's safe area (composition px).

FieldTypeWhat it is
faceRectthe largest face's box, when there's one
safe{ top?: number; bottom?: number }px the platform's UI covers at the top and bottom

Plan

A timeline's plan: each part's start frame and move, and the whole length.

FieldTypeWhat it is
parts (required)Record<string, { at: number; move: Move }>each part's start frame and move, by its name
frames (required)numberthe whole timeline's length in frames

Playtest

What a playtester needs from a game, exported beside the view as export const playtest: Playtest<S> = {...} (sdk/react/docs/playtest.md). Optional: a game without one is played from pixels and events alone. Everything here is pure, so a bot steps the game headlessly, restores any state it has seen (states are values) and searches from it; whatever it plays is an input timeline raea render --input turns back into the same frames.

FieldTypeWhat it is
initial (required)Sthe state at frame 0, as useGameState is given it
step (required)Step<S>the fold useGameState is given: the same function, so a bot plays the game the render shows
actions (required)string[][]the key chords worth trying ([] is "nothing held"); a bot's moves are these, each held some frames
observe(state: S, frame: number) => Owhat a player could know at this frame, as plain JSON (positions, lives, what's near): a model reads it
progress(state: S, frame: number) => numberhow far toward the goal, 0..1: search follows it, and "stuck" means it stopped rising
outcome(state: S, frame: number) => "won" | "lost" | null"won" when the goal is reached, "lost" on game over, null while play goes on
eventsRecord<string, (before: S, after: S) => boolean>named moments as useGameEvents takes them (a death, a coin): counted, placed and rendered for the judge
machines(state: S) => Record<string, Watched>every state machine in the state, by entity name ({ player: player.watch(s.player), flow: flow.watch(s) }): the trace records each one's state and transitions, and the machine checks (coverage, softlocks, unreachable states, reached) read them (sdk/react/docs/state-machines.md)

ProofInput

FieldTypeWhat it is
width (required)numberthe composition's width, px
height (required)numberthe composition's height, px
faceRectthe face's box, when perception found one
parts (required)ProofPart[]the measured boxes of the parts to check

ProofPart

FieldTypeWhat it is
name (required)stringthe part's name, in the faults
band[number, number]the band the part must fit in, [top, bottom] in px
x (required)numberthe left edge, px
y (required)numberthe top edge, px
w (required)numberwidth, px
h (required)numberheight, px

RaeaCSSProperties

FieldTypeWhat it is
baselineSourceGlobals | "auto" | "first" | "last" | undefinedwhich baseline of a box aligns it in its line: its first line's or its last's (css-inline-3)
flexLineCountGlobals | number | undefineda flex container's line count when it balances its items across lines (css-flexbox-2): a positive integer
maskPositionXProperty.BackgroundPositionX<TLength> | undefineda mask image's horizontal position, as background-position-x takes it (css-masking-1)
maskPositionYProperty.BackgroundPositionY<TLength> | undefineda mask image's vertical position, as background-position-y takes it (css-masking-1)
textDecorationInsetGlobals | TLength | "auto" | (string & {}) | undefinedhow far an underline or line-through reaches past (or short of) the text at each end: auto, or one or two lengths (css-text-decor-4)

Rect

A box in composition px.

FieldTypeWhat it is
x (required)numberthe left edge, px
y (required)numberthe top edge, px
w (required)numberwidth, px
h (required)numberheight, px

RegionBox

The band a Region occupies, in composition px.

FieldTypeWhat it is
name (required)RegionNamethe band it took: top, bottom, center or full ("auto" resolves to top or bottom)
x (required)numberthe left edge, px
y (required)numberthe top edge, px
w (required)numberwidth, px
h (required)numberheight, px

RegionName

TS
type RegionName = "auto" | "top" | "bottom" | "center" | "full"

RegionProps

The props of Region, tabled there.

RegisteredComposition

FieldTypeWhat it is
id (required)stringthe composition's id: letters, digits and dashes (raea render --composition picks it)
component (required)ComponentType<any>the React component it renders
width (required)numberin px
height (required)numberin px
fps (required)numberframes a second
durationInFrames (required)numberits length in frames
defaultProps (required)Record<string, unknown>the props it's rendered with (JSON-like values only)

SequenceLayout

TS
type SequenceLayout = "absolute-fill" | "none"

SequenceProps

The props of Sequence, tabled there.

SeriesSequenceProps

FieldTypeWhat it is
offsetnumberframes from the previous slot's end to this one's start (0); negative overlaps
heightnumberthe height its children see, px (the parent's by default)
styleCSSPropertiesthe wrapping box's style
childrenReactNodewhat plays in it, at its own local time
classNamestringthe wrapping box's classes
namestringits label in the timeline and the render manifest (data-sequence)
widthnumberthe width its children see, px (the parent's by default)
durationInFramesnumberhow many frames it shows its children (forever by default)

Snapshot

The machine's runtime state, kept in the context it drives. path is the active states outermost first ([] before the first step); at[i] is the step on which path[i] was entered; n counts the machine's steps from 0; e is the edge the last transition took (an index into machine.edges); by names the decider that chose it (absent: a guard); hist is each history state's last substate.

FieldTypeWhat it is
path (required)N[]the active states, outermost first ([] before the first step)
at (required)number[]the step each state in path was entered on
n (required)numberthe machine's steps so far, from 0
e (required)numberthe edge the last transition took, an index into machine.edges
bystringthe decider that chose the last transition (absent: a guard did)
hist{ [S in N]?: N }each history state's last substate

Song

FieldTypeWhat it is
map (required)SongMapthe song's map, from `raea song`
fps (required)numberthe composition's frame rate, that frames are counted in
offset (required)numberseconds into the song frame 0 falls on (0)
frame (required)(seconds: number) => numberthe frame a song time falls on
seconds (required)(frame: number) => numberthe song's seconds at a frame
at (required)(frame: number) => SongMomentwhere the song is at a frame
onBeat (required)(every?: number | undefined, range?: FrameRange | undefined) => number[]frames of every every-th beat (1: each beat), counted from the song's first
onDownbeat (required)(every?: number | undefined, range?: FrameRange | undefined) => number[]frames of every every-th downbeat
eventsOf (required)(kind: SongEventKind, range?: FrameRange | undefined) => { frame: number; event: SongEv…frames of every event of a kind (a build's or stop's start), with the event
cutsAt (required)(options?: CutOptions | undefined) => number[]frames to cut on, paced to the energy: each section's (or bar's) rate, on its beats, plus drops, a stop's hits, and a build's second half at double rate

SongBar

FieldTypeWhat it is
time (required)numberseconds from the song's start where the bar begins (its downbeat)
beat (required)numberthe index of its first beat
beats (required)numberhow many beats it holds
energy (required)numberits mean energy, 0..1
cuts (required)numbersuggested cuts in this bar: 0.25, 0.5, 1, 2 or 4

SongEvent

FieldTypeWhat it is
kind (required)SongEventKindwhat the event is: build, drop, stop, hit, dip or break
time (required)numberseconds from the song's start: a beat (drop, a downbeat) or the grid's nearest beat or half beat (hit)
endnumberspans (build, stop, dip, break) end here
beat (required)numberthe index of the beat it starts on, in SongMap.beats
bar (required)numberthe index of the bar it starts in
beatsnumbera span: how many beats it lasts
strength (required)number0..1
intonumber | nulla build or stop: the drop it leads into, seconds
hitsSongHit[]a stop: its sparse hits
risenumbera drop: the energy of the bar after minus the bar before (negative when the band cuts after one big hit)
holdsbooleana drop: the bar after stays up (false: one hit, then the band cuts out)
afterStopbooleana drop: it comes straight out of a stop
afterBuildbooleana drop: it lands at the end of a build (within two bars of it)
gapBeforebooleana drop: a breath of near-silence just before it
atnumbera hit: the onset's own time; how far over the groove it stands
overnumbera hit: how far over the groove it stands

SongEventKind

TS
type SongEventKind = "build" | "drop" | "stop" | "hit" | "dip" | "break"

SongFeatures

FieldTypeWhat it is
loudness (required)number[]loudness (RMS) a beat, 0..1 over the song
onsets (required)number[]onset strength (spectral flux) a beat, 0..1: how much is struck
brightness (required)number[]brightness (spectral centroid) a beat, 0..1
low (required)number[]the low end (kick and bass, under 150 Hz) a beat, 0..1
high (required)number[]the high band (over 3 kHz) a beat, 0..1
energy (required)number[]the combined energy a beat, 0..1: loudness, low end, onsets and highs together

SongHit

A hit inside a stop: time on the beat grid (a beat or half beat), at where the onset is.

FieldTypeWhat it is
time (required)numberseconds from the song's start, snapped to the beat grid (a beat or half beat)
at (required)numberseconds from the song's start where the onset itself is
strength (required)numberhow hard the hit is, 0..1

SongLevel

TS
type SongLevel = "intro" | "low" | "mid" | "high" | "outro"

SongMap

FieldTypeWhat it is
version (required)numberthe map format's version (1)
duration (required)numberthe song's length in seconds
tempo (required)number | nullbeats per minute, or null when no beat was found
beatsPerBar (required)numberbeats in a bar (4 for 4/4)
beats (required)number[]every beat's time in seconds, ascending
downbeats (required)number[]every bar's first beat, in seconds
features (required)SongFeaturesone value a beat, 0..1 over the song
bars (required)SongBar[]the bars in order, each with its energy and suggested cut rate
sections (required)SongSection[]the song's sections in order (intro, verse, chorus and so on)
events (required)SongEvent[]builds, drops, stops, hits, dips and breaks, in time order
sectionsFrom"markers" | "novelty"where the sections came from: the song file's markers, or novelty in the music itself
boundaries{ time: number; beat: number; bar: number; strength: number }[]the candidate section boundaries novelty found, each with its strength 0..1
sourcestring | nullthe song file's name

SongMoment

Where a moment of the song is. Seconds are the song's; infinities when there's no such event.

FieldTypeWhat it is
time (required)numberthe moment, seconds from the song's start
beat (required)numberthe beat at or before time (-1 before the first)
bar (required)numberthe bar at or before time (-1 before the first beat)
beatInBar (required)number0-based position in the bar
phase (required)number0..1 through the beat, and through the bar
barPhase (required)number0..1 through the bar
energy (required)numberthe features at time, interpolated between beats
loudness (required)numberloudness at time, 0..1
onsets (required)numberonset strength at time, 0..1
brightness (required)numberbrightness at time, 0..1
low (required)numberthe low end at time, 0..1
section (required)SongSection | nullthe section time is in (null before the first)
sectionIndex (required)numberthat section's index in SongMap.sections (-1 for none)
sectionProgress (required)number0..1 through the section
cutsPerBar (required)numberthe bar's suggested cut rate (cuts per bar)
drop (required)SongEvent | nullthe last drop at or before time, the next after it
nextDrop (required)SongEvent | nullthe next drop after time
sinceDrop (required)numberseconds since the last drop (Infinity when there's none)
untilDrop (required)numberseconds until the next drop (Infinity when there's none)
build (required)SongEvent | nullthe build time is in, and 0..1 through it
inBuild (required)booleanwhether time is inside a build
buildProgress (required)number0..1 through that build
stop (required)SongEvent | nullthe stop time is in
inStop (required)booleanwhether time is inside a stop
dip (required)SongEvent | nullthe dip or break time is in
next (required)SongEvent | nullthe next event of any kind after time

SongOptions

FieldTypeWhat it is
fps (required)numberthe composition's frame rate
offsetnumberseconds into the song at frame 0 (where an

SongPlotProps

The props of SongPlot, tabled there.

SongSection

FieldTypeWhat it is
name (required)stringthe section's marker name when the song file has markers, else its level
level (required)SongLevelhow high the section sits in the song: intro, low, mid, high or outro
time (required)numberseconds from the song's start where the section begins
end (required)numberseconds from the song's start where it ends
beat (required)numberthe index of its first beat
bar (required)numberthe index of its first bar
energy (required)numberits mean energy, 0..1
cuts (required)numbersuggested cuts per bar: 0.25, 0.5, 1, 2 or 4

SpringConfig

FieldTypeWhat it is
massnumberhow heavy the spring's weight is (1): heavier is slower and swings further
dampingnumberhow fast the swing dies (10): lower bounces more
stiffnessnumberhow hard the spring pulls (100): stiffer is quicker
overshootClampingbooleanstop at to the first time it gets there, with no overshoot (false)

SpringOptions

FieldTypeWhat it is
frame (required)numberthe frame to sample, usually useCurrentFrame()
fps (required)numberframes a second, from useVideoConfig()
fromnumberthe value it starts at (0)
tonumberthe value it settles at (1)
configSpringConfigthe spring: mass, damping, stiffness, overshootClamping
durationInFramesnumberstretch or squeeze the spring to settle in this many frames
durationRestThresholdnumberhow close to to, as a share of the travel, counts as settled when timing it (0.005)
delaynumberframes before it starts (0)
reversebooleanplay it backwards: from to back to from

StaggerProps

FieldTypeWhat it is
each (required)numberframes between one child's entrance and the next
grid{ cols: number; rows?: number; from?: GridFrom }spread by grid distance instead of order
exitEachnumberthe exit staggered too, exitEach frames apart (0: all together)
styleCSSPropertiesinline style
animateRecord<string, TrackSpec | TrackSpec[] | Keys> | Movefree tracks by property, in local frames: { backgroundColor: track({ 0: "#fff", 20: "#000" }) }
asstringthe element: "div" by default
exitMoveLikethe exit, played at exitAt (an entrance reversed: exit="rise" sinks back out)
childrenReactNodewhat moves
enterMoveLikethe entrance: a move's name, a move, or several together
atnumberlocal frame the entrance starts (0)
exitAtnumberlocal frame the exit starts
mount"during" | "always""always" (default): in the tree, and its layout, the whole time (invisible before an entrance that fades in); "during": only from the entrance's start until the exit ends (it takes its space when it arrives)
classNamestringTailwind or CSS classes

StateConfig

FieldTypeWhat it is
entryActions<C, E>run when the state is entered (outer states before inner ones)
exitActions<C, E>run when the state is left (inner states before outer ones)
tickActions<C, E>run every step the state is active, after this step's transition (outer before inner, the entry step too)
alwaysTransitions<C, E, N>triggers polled every step, in order: the first whose guard holds fires (XState's eventless always)
after{ readonly [steps: number]: Transitions<C, E, N> }delays in steps: after: { 30: "fall" } fires once the state has been active 30 steps (and its guard holds)
on{ readonly [event: string]: Transitions<C, E, N> }named events the step is given this time (input edges: games.ts keyEdges gives "keydown:ArrowUp")
chooseTransitions<C, E, N>a choice point: of these candidates, those whose guards hold go to the step's Decider, which picks one or waits (no decider: firstDecider takes the first). Polled after always and after.
initialNoInfer<N>a compound state's first substate
states{ [K in N]?: StateConfig<C, E, N> }substates: names are unique across the whole machine, so to: "run" names one state wherever it is
history"shallow" | "deep"re-entering this compound state resumes the substate it left ("shallow"), or that substate's own (deep)
onDoneTransitions<C, E, N>a compound state's transition taken when its active substate is final
type"final"a final state: no transitions out (a dead enemy, the game won, the work shipped)
descriptionstringwhat the state means, for reports and a decider

StateName

The state names of a machine.

TS
type StateName = M extends Machine<any, any, infer N, any> ? N : never

Step

A timeline step: [part, move], a group from sequence/parallel/stagger, or a pause in frames.

TS
type Step = [part: string, move: MoveLike] | { part: string; move: MoveLike; offset?: number } | Group | number

StepOptions

What a step may be given besides the context and env.

FieldTypeWhat it is
eventsreadonly string[]named events this step (an on edge waits for one)
decideDeciderpicks at choice points (default firstDecider)
trace(r: TransitionRecord) => voidreceives every transition this step takes, as a row

TimelineWord

FieldTypeWhat it is
text (required)stringthe word as spoken
from (required)numberfirst frame of the word
to (required)numberframe after the word ends (exclusive)

TrackSpec

One property's keyframes: values by frame, the curve between each pair (one for all, or one per segment).

FieldTypeWhat it is
keys (required)[number, V][][frame, value] pairs in frame order, frames from the move's start
ease (required)Curve | Curve[]the curve between keys: one for all, or one a segment
unit"px" | "%"a length's unit: px (the default) or %
repeat"hold" | "loop" | "pingpong" | ${"loop" | "pingpong"}:${number}``past the last key: hold (the default), loop or pingpong, for ever or N times ("loop:3")
digitsnumberdecimals a text counter writes
prefixstringa text counter's text before and after the number, and between its thousands ("," writes 12,345)
suffixstringwritten after a text counter's number (" pts")
separatorstringbetween a text counter's thousands ("," writes 12,345)

TransitionConfig

A transition: where to go (to, or XState's target), when (when, or XState's guard; none: always), after how many steps in the state at least (after), and what to do on the way (actions).

TS
type TransitionConfig = Target<N> & When<C, E> & { /** steps in the state before this transition may fire (0) */ after?: number; actions?: Actions<C, E>; /** what the transition means: a decider reads it (a model's option description), reports show it */ description?: string; }

TransitionRecord

One transition as a row: what a trace keeps and rdb loads (step, machine, from, to, edge, decider, evidence). from is null for the first step's entry into the initial states.

FieldTypeWhat it is
machine (required)stringthe machine's id
step (required)numberthe machine's step it happened on
from (required)string | nullthe leaf it left (null for the first entry)
to (required)stringthe leaf it entered
edge (required)numberthe edge it took, an index into machine.edges
kind (required)Edge["kind"] | "start"what kind of edge: always, after, on, choose, done (an onDone), or start for the first entry
by (required)string"guard" for a trigger, "start" for the first entry, else the decider's name
evidenceunknownthe decider's evidence for the choice

Transitions

A target's name alone, one transition, or several checked in order.

TS
type Transitions = | NoInfer<N> | TransitionConfig<C, E, N> | readonly (NoInfer<N> | TransitionConfig<C, E, N>)[]

UseSongOptions

FieldTypeWhat it is
offsetnumberseconds into the song at frame 0 of the enclosing Sequence

VideoConfig

FieldTypeWhat it is
id (required)stringthe composition's id ("main" by default)
width (required)numberin px
height (required)numberin px
fps (required)numberframes a second
durationInFrames (required)numberits length in frames
defaultProps (required)Record<string, unknown>the props the composition is rendered with

VideoProps

The props of Video, tabled there.

VolumeProp

TS
type VolumeProp = number | ((mediaFrame: number) => number)

Watched

A machine's state in some context, for a trace (Playtest.machines).

FieldTypeWhat it is
machine (required)AnyMachinethe machine
snapshot (required)Snapshotits runtime state in that context

WordOptions

FieldTypeWhat it is
occurrencenumberwhich time the phrase is said, from 1
edge"start" | "end""start": the phrase's first frame; "end": the frame after its last word ends