Guide · 03 of 15
Scene & State
A Prism file is exactly one scene <type> { ... } block. Everything else — space config, state, objects, controls, timeline — lives inside it.
scene#
type is plane (2D cartesian) or numberline (1D axis); space3, circuit and magnet have their own sections. For plane, both x: and y: are required. For numberline, only x: is needed. The space config lines can appear anywhere in the block, in any order, alongside state/object/control declarations.
By default the x and y domains are stretched independently to fill the box, so a circle only looks round if the domains happen to match the box. Add aspect: equal when shape matters — unit circles, Argand diagrams, geometry, force diagrams — and one shared scale is used for both axes, letterboxed inside the same space.
On a plane the domains can use the scene's params, which is how you zoom: x: [1 - z, 1 + z] with a slider on z closes in on x = 1, and a goal like when: z < 0.05 asks the student to zoom until the curve looks straight. The grid and tick labels follow the zoom.
scene <type> { x: [min,max] [y: [min,max]] [grid] [axes] [aspect: equal] [alt: "what the picture shows"] ... }
| prop | type | description |
|---|---|---|
| x* | [expr, expr] | x-axis domain; may use params on a plane, to zoom |
| y | [expr, expr] | y-axis domain (plane only) |
| grid | flag | draw a background grid (plane only) |
| axes | flag | draw axes. they are on by default — write axes: false to hide them |
| aspect | equal | one scale for both axes, so circles stay round (plane only) |
| alt | string | what a screen reader hears: what the picture shows and what the student can change. dsl verify --standard asks for one on every main-path scene |
Example
axis titles#
Names an axis at its arrow, as I (A): a latin symbol in italics, coloured by quantity:. Give name:, unit: or both. A tick under the title gives way. Plane and numberline (x: only).
x: [min, max] { name: "" , unit: "" , quantity: <role or colour> }
Example
linked views#
A slide can hold any number of scenes, all sharing one state: a param, bool or choice declared in one can be read, dragged, bound and animated from all, and goals, showme: and after: see it all. Declare each name once. Two scenes back to back sit side by side (stacked on a phone), their controls in one strip; a scene after text is its own block, shown where it is written. A circuit must come first, and only the first scene (or the one beside it) may have steps. Each scene needs its own alt:.
slide "..." { scene <type> { ... } scene <type> { ... } }
Example
param#
Declares a numeric state variable. Controls (sliders, steppers) and draggable objects write to it; object expressions read from it. The { ... } block is optional, so omit it if there is nothing to configure. keep makes the value part of the lesson's memory: a later slide with a keep param of the same name starts where the student left it (a reload too), and prose can show it with ${recall("name")}.
clock: makes the param move by itself, by the rate every second; the rate can read other params, so a slider sets the speed and 0 stops it, and wrap: w keeps the value in [0, w) to drive a phase. Only time moves a clock, so it takes no range, step or keep, no control, drag, timeline step or showme: may write it, and no goal or wait: may read it. It holds still off screen and under reduced motion.
param <name> = <number> { [range: [min,max]], [step: <number>], [keep] } or { clock: <rate>, [wrap: <number>] }
| prop | type | description |
|---|---|---|
| range | [number, number] | min/max bounds for controls |
| step | number | discrete step size |
| keep | flag | carry the value to later slides that keep a param of the same name |
| clock | expr | rate per second; the param moves on its own |
| wrap | number | with clock, keep the value in [0, wrap) |
Example
bool#
Declares a boolean state variable. Toggles write to it; show: on objects reads from it.
bool <name> = <true|false>
Example
choice#
Declares a string-valued state variable restricted to a fixed set of options. A picker control writes to it; object expressions read it and compare with ==.
choice <name> = " { options: ["a", "b", ...] }
| prop | type | description |
|---|---|---|
| options* | string[] | the allowed values, required |
Example