The scene document
The shape of a saved scene: frame, modules, instances, actions, tracks, clips, cameras, shots and audio, and how the pieces refer to each other.
A scene is one JSON document. The studio, the command line and every agent read and write the same shape, and puni contract prints its types verbatim.
#The top level
A saved scene is { schemaVersion: 2, name, description, environment, composition }; the fields below live in composition.
| Field | Holds |
|---|---|
frame | width, height, fps, duration |
modules | The kinds of thing in the scene, with their properties |
instances | The objects: each one an instance of a module with a transform |
actions | Motion: keys on properties, or a procedure |
tracks | One lane per animated object |
clips | An action placed on a track at a time |
cameras, shots | Saved framings and when each one is on screen |
audio | Sound clips with start, offset, duration and gain |
seed | The number procedural motion starts from |
Distances are millimetres, time is seconds, angles are degrees in transforms.
#Modules and instances
A module says what a thing is: its adapter (shape, curve, profile, source, text, mark, cloner, shader, interface, fitting, group) and the properties it exposes with their types, defaults and ranges. An instance places one on the stage with a transform, a parent, and values for those properties.
{
"id": "body",
"moduleId": "soft-body",
"name": "Body",
"parentId": null,
"visible": true,
"locked": false,
"transform": { "position": [0, 40, 0], "rotation": [0, 0, 0], "scale": [1, 1, 1] },
"properties": { "color": "#819ad5", "skin": "clay", "finish": 0.5, "weight": 0.5 }
}A transform may carry a pivot, in the object's own millimetres. Rotation and scale turn about that point instead of the origin. A lid 40 mm deep hinged on its back edge is "pivot": [0, 0, -20] and opens with one rotation key.
An instance may carry an opacity from 0 to 1 (absent is 1). It multiplies through the object's children, and it animates on the path opacity. A faded object draws as a solid one fading: its front surface over whatever is behind it, never its own inner faces. Shapes melted into one blend fade with their group, not one by one.
A group module can declare parameter bindings, so one control on the parent drives properties in its children.
#Outlines
A profile module extrudes a flat outline by its depth. Its outline property is JSON text in one of two forms. The point form lists a contour and up to eight openings in millimetres, and rounding softens its corners. The path form is SVG path data drawn exactly, so a logo or wordmark goes in whole:
{ "version": 1, "path": "M7.99 9.557h10.45 … Z", "fillRule": "evenodd", "flipY": true, "center": true }Curves (C S Q T A, absolute or relative) are sampled when the scene draws. Every subpath is a contour; the fill rule decides which are islands and which are holes, and one outline can hold many islands. Contours may not cross or touch: overlapping pieces are not unioned. scale is millimetres per path unit, flipY turns SVG's downward y upright and center puts the drawing's centre at the origin. The contract's ProfileOutlineData type and AUTHORING_LIMITS give every bound.
Either form can carry a bevel in millimetres. The bevel is cut inward from the outline, so the silhouette and the thickness stay exactly as authored. bevelSegments sets its bands: one is a flat chamfer, more make a quarter round (six by default). A bevel deeper than half the thickness, or than the narrowest stroke can lose, is drawn clamped.
#Motion
An action holds channels: a property path and its keys, each with a time, a value and an ease. A key may carry a curve that shapes the segment to the next key in place of its ease. {"kind": "bezier", "points": [x1, y1, x2, y2]} reads as CSS cubic-bezier. {"kind": "spring", "damping": 0.4, "frequency": 2} is a damped spring that overshoots and lands exactly on the next key. Its damping is a ratio, and its frequency is in hertz on the clip's clock. A track belongs to one object. A clip puts an action on a track with a start, a duration, a blend, a weight, a repeat and a fill. A clip with a trigger waits for a tap instead of the timeline.
Procedural actions carry their recipe instead of keys: settle, turntable, impulse, float, shake, or a recorded rigid-body motion.
#Cameras and audio
A camera has a position, a target, a field of view, roll, focus and aperture. A shot puts a camera on the timeline with a transition and an ease. An audio clip references retained bytes by URI and SHA-256.
#Reading the contract
puni contract --jsonOver MCP, read_contract with topic: "types" returns the same text; topic: "shape" returns a ready-made module you can add. Read Commands for how the document changes.
Was this useful?