← Back to Docs
  • index.html
  • Clayground
  • Clayground.Lab
  • FlowStep
  • Clayground 2026.7
  • FlowStep QML Type

    One stop of a lab Flow: what is said, what the lab does, what the learner does. More...

    Import Statement: import Clayground.Lab

    Properties

    Detailed Description

    A step is either a demonstration (demo runs, the learner watches), a task (task waits for the learner) or narration only.

    See also Flow.

    Property Documentation

    demo : var

    Actions the lab performs on entering, as [[verb, args...], ...].

    Verbs are resolved against the lab's flowActions() map. The form ["let", "name", verb, args...] binds the verb's return value to a flow-local name usable as an argument in later actions.


    dwell : var

    Sim seconds to linger, or "auto" to estimate from reading time.


    expect : var

    Optional predicate asserted after the step, for headless checks.


    key : string

    Stable step name; also the narration key suffix.

    The narration is looked up as flow.<flowId>.<key> in LabLang, which is what makes a flow translatable. say is the fallback.


    mark : var

    Parts (or sub-parts) this step's line names, as a list of names.

    The eye's half of a spoken sentence. A line that says "the battery, the switch, the LED and the resistor, one loop" asks the learner to find four things by ear; mark: ["battery", "switch", "led", "resistor"] rings all four on the model while the line lasts, and the marks go with the step.

    The names are the lab's own - resolved exactly as a performance script's *point at NAME* target is, by whatever the presenter's guide was given as a resolver - so they are language-neutral authoring tokens, not display text. Nothing here draws them: a lab binds them to a MarkLayer.

    A directed step (one with a performance script) ignores this field: its marks come from the script's own *mark ...* cues, which can raise a different set per line.


    say : string

    Narration text, used when no dictionary entry exists for key.


    task : var

    What the learner must do: {until, allow, hint, hintAfter, solve}.

    until is a predicate receiving a name lookup function and returning true once the step is satisfied; solve is an action list that performs it (used by "show me" and by the headless verification run).

    allow is what the task hands over: the parts the learner may touch while it runs, named the way until and solve name them ("allow": ["sw"]), everything else on the board being inert until the task is done. A step whose subject is whatever the preset it just applied put there names it with a function of the same name lookup instead ("allow": (n) => root.logicInputs). Leaving it out keeps the whole board live, which is what a flow written before Flow::control existed still gets.


    view : var

    Where the camera should be for this step. Null leaves it alone.

    A narrated step that talks about the far corner of the board while the camera is still on the near one teaches nothing, and moving it from a demo verb means every lab has to invent that verb. Three forms, all applied after the demo has run, so a step can frame what it just built:

    Add ms: to any of them to set the travel time. Applied only when the Flow has a camera; a flow without one ignores the property entirely, which is what keeps it non-breaking.


    watch : var

    Wait for the simulation, as {until}.

    The sibling of task for continuous labs: nothing is asked of the learner, the step simply ends when the world reaches a state ("the car enters the tunnel", "sigma passes 2 m"). Same predicate, different promise - so the narrator says "watching" rather than "your turn".