Last updated: April 2, 2026
Purl Syntax Reference
All scripting syntax in one table. Use search at the top of the page.
| Category | Name | Syntax | Details |
|---|---|---|---|
| EVENTS | |||
| Event | onEnter | onEnter: |
Cell or object — fires when player enters cell. All handlers run concurrently (repeat/wait loops don't block other objects' init). Cross-object dependencies: use onMessage |
| Event | onExit | onExit: |
Cell or object — fires when player leaves cell |
| Event | onClick | onClick: |
Object — fires when clicked |
| Event | onKeyDown | onKeyDown "Key": |
Cell — fires when key pressed. Keys: Escape, Space, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, a-z, 0-9. Gamepad: gamepad-a (Space), gamepad-b (Escape), gamepad-x (e), gamepad-y (q), gamepad-up/down/left/right (arrows). Ctrl+Escape exits to build mode |
| Event | onKeyUp | onKeyUp "Key": |
Cell — fires when key released. Same keys as onKeyDown including gamepad |
| Event | onHover | onHover: |
Object — mouse enters bounds |
| Event | onHoverEnd | onHoverEnd: |
Object — mouse leaves bounds |
| Event | onDragStart | onDragStart: |
Object — drag begins. Requires draggable |
| Event | onDrag | onDrag: |
Object — each frame while dragging |
| Event | onDragEnd | onDragEnd: |
Object — drag released |
| Event | onOverlap | onOverlap: |
Object — starts overlapping another. Requires sensor on one object. Use other to reference |
| Event | onOverlapEnd | onOverlapEnd: |
Object — stops overlapping |
| Event | onCollide | onCollide: |
Object — hits a blocker. Use other to reference blocker |
| Event | onMove | onMove: or onMove "dir": |
Object — movement starts. Directions: up, down, left, right |
| Event | onRotate | onRotate: or onRotate "dir": |
Object — rotation starts/changes. Directions: cw (clockwise), ccw (counter-clockwise) |
| Event | onStop | onStop: |
Object — movement stops (any reason: wall hit, input released, path bend) |
| Event | onArrive | onArrive: |
Object — reached moveTo/click-to-move target. Use for waypoint patrol instead of onStop |
| Event | onTick | onTick: |
Object — fires every physics frame (~60fps). deltaTime variable available (seconds). Use for continuous logic |
| Event | onJump | onJump: |
Object — jump triggered. Requires jumpable |
| Event | onLanding | onLanding: |
Object — lands on surface |
| Event | onBounds | onBounds: |
Object — fires when object crosses cell boundary. Optional direction filter: onBounds "left", "right", "top", "bottom". Fires once per crossing. Movable objects only |
| Event | onSpawn | onSpawn: |
Object — fires when spawned at runtime |
| Event | onDestroy | onDestroy: |
Object — fires before destruction |
| Event | onSubmit | onSubmit: |
Object — fires when Enter pressed in editable text. self.content has the submitted text |
| Event | onDefocus | onDefocus: |
Object — fires when editable text loses focus (click elsewhere or Escape) |
| Event | onBreak | onBreak: |
Peg — fires when constraint breaks (force exceeds breakForce) |
| Event | onMessage | onMessage "MSG": |
Cell or object — receives shout. Top-level only — cannot be nested inside repeat, if, or other blocks. Runs concurrently with other handlers. To react to a message inside a loop, set a variable in the handler and check it in the loop |
| Event | onMessageFrom | onMessageFrom "Source" "MSG": |
Cell or object — receives shout from specific sender. Same top-level restriction as onMessage |
| Event | Combined | onClick | onKeyDown "Space": |
Multiple events trigger same code |
| COMMANDS | |||
| Command | goto | goto "CellName" |
Navigate to cell. Directions: north, east, south, west. Transitions: with fade, with slide-up, etc. Reset: clean (reset objects, keep vars), fresh (reset all) |
| Command | goto transition | goto "Room" with fade 500 |
Navigate with transition animation. Duration in ms or expression: random(200,500) |
| Command | goto reset | goto "Room" clean or goto "Room" fresh |
Navigate with reset level. Combinable: goto "Room" clean with fade |
| Command | restart | restart |
Go to start cell + full reset. restart cell restarts current cell |
| Command | endGame | endGame |
Exit play mode. In studio returns to build mode, in player stops the game |
| Command | show | show X or show X with fade 300 |
Make object visible. Transitions: fade, scale, slide-up, slide-down. Text-only: typewriter, word, scramble, redact. Duration in ms or expression: random(200,500) |
| Command | hide | hide X or hide X with fade 300 |
Make object invisible. Transitions: fade, scale, slide-up, slide-down. Text-only: typewriter, word, scramble, redact. Duration in ms or expression: random(200,500) |
| Command | spawn | spawn "Template" {params} |
Create object at runtime. Params: x, y, cellX, cellY, custom |
| Command | spawn at | spawn "Template" at AnchorName |
Spawn at anchor position/rotation. If anchor is inside a component, spawned object becomes a child |
| Command | destroy | destroy X or destroy X with fade 300 |
Remove object from scene. Works on spawned and design-time objects. Design-time objects reappear on reset. Transitions: fade, scale, slide-up, slide-down. Duration in ms or expression. Targets: name, self, other, parent, siblings, children, #tag |
| Command | addTag | addTag self #robot |
Add tag to object at runtime. Targets: name, self, other, #tag, all type. No-op if tag already exists |
| Command | removeTag | removeTag self #robot |
Remove tag from object at runtime. Same targets as addTag. No-op if tag not present |
| Command | set variable | set score 10 |
Create/update variable |
| Command | set property | set X.opacity 0.5 |
Change object property |
| Command | set property (tween) | set X.opacity 0 over 500 |
Smooth transition over duration (ms). Optional easing |
| Command | set property (easing) | set X.x 0.8 over 300 ease-out |
Easing: linear, ease-in, ease-out, ease-in-out, ease-in-cubic, ease-out-cubic, ease-in-out-cubic |
| Command | set state (tween) | set X.state "RED" over 500 |
Tween from current to target state over N ms |
| Command | set state (tween+mod) | set X.state "RED" position over 300 cw |
Modifiers before over. Optional cw/ccw for rotation direction |
| Command | enable | enable X movable |
Enable capability (movable, jumpable, draggable, keyboard, click, gamepad, subject, follow, avoid). Target: name, self, other, self.Child, parent, siblings, children, #tag |
| Command | disable | disable X movable |
Disable capability. Same targets as enable |
| Command | clear grid | clear Grid |
Clear all cell data |
| Command | clear cell | clear Grid.cell[x][y] |
Clear one cell's data |
| Command | shout | shout "MSG" {key: val} |
Send message to current cell listeners. Params optional, accessed as variables in handler |
| Command | shout global | shout "MSG" global |
Send message to ALL cells' listeners (cross-cell broadcast) |
| Command | shout to | shout to X "MSG" {key: val} |
Send message to specific object or #tag. Params optional |
| Command | reset | reset session |
Reset variables. Scopes: session, game, all, objects (reset objects, keep vars), fresh (reset objects + vars), visits (reset current cell visit count) |
| Command | reset script | reset script |
Reset sequential onClick counter |
| Command | wait time | wait 500ms or wait 2s |
Pause execution. Accepts expressions: wait delay, wait random(1000,3000), wait (baseTime * 2) |
| Command | wait movement | wait movement |
Pause until all movement settles |
| Command | wait movement (target) | wait movement self |
Pause until specific object stops. Also: wait movement ObjName |
| Command | sync | sync |
Synchronize parallel scripts |
| Command | copy | copy value |
Copy to clipboard. Only works from user events (onClick, onKeyDown) |
| Command | log | log "text" value |
Debug output to console |
| Command | openUrl | openUrl url [newTab] |
Open URL in browser. newTab opens in new tab instead of current window |
| Command | post | post url {data} |
HTTP POST request |
| Command | fetch | fetch url into var |
HTTP GET into variable |
| Command | transition | transition fade 500 |
Cell entrance animation. Types: fade, slide-up, slide-down, slide-left, slide-right, zoom |
| Command | return | return |
Exit current action early |
| Command | break | break |
Exit current loop |
| Command | save | save "checkpoint" |
Save game state to named slot. Stores all variables, object states, visited cells, spawned objects, physics positions/velocities, and current cell |
| Command | load | load "checkpoint" |
Restore game state from named slot and navigate to saved cell. Sets newGame to false. Silently ignored if slot doesn't exist |
| Command | delete save | delete save "checkpoint" |
Delete a save slot |
| Command | reveal | reveal Mask1 0.5 0.5 |
Punch transparent hole in mask. Args: mask name, x, y (mask-relative coords). Optional: radius, fade. reveal Mask1 self.x self.y 0.05 0.02 |
| Command | rehide | rehide Mask1 |
Reset mask fog to fully opaque. Resets base canvas + all revealer layers. rehide Mask1 Player resets only Player's revealer layer |
| ANIMATION | |||
| Animate | group | animate X "group" loop |
Play state group animation. Modes: loop, once, pingpong |
| Animate | group fps | animate X "group" fps 12 once |
Frame mode with custom FPS |
| Animate | group duration | animate X "group" duration 500 loop |
Tween mode with duration per step (ms) |
| Animate | group easing | animate X "group" duration 300 ease-in-out |
Tween easing. Values below |
| Animate | group resume | animate X "group" loop resume |
Don't restart if running; smooth entry when starting |
| Animate | group cw/ccw | animate X "group" loop cw |
Force clockwise rotation interpolation (ccw for counter-clockwise) |
| Animate | group exclusive | animate X "group" loop exclusive |
Stop all other group animations on this object before starting |
| Animate | stop | stop animate X |
Stop all group animations on object |
| Animate | shake | shake X 300 |
Horizontal oscillation (duration in ms) |
| Animate | vibrate | vibrate X 300 or vibrate X loop |
Rapid micro-jitter. Optional intensity (default: 2) |
| Animate | pulse | pulse X 300 or pulse X loop |
Scale breathe effect. Optional scale (default: 1.15) |
| Animate | squeeze | squeeze X 300 |
Squash & stretch. Optional direction: horizontal, vertical |
| Animate | bounce | bounce X 300 |
Vertical hop with squash. Optional height (default: 20) |
| Animate | spin | spin X 300 |
360° rotation. Optional direction: cw, ccw. On components, rotates as a unit; add children for per-child effect |
| Animate | glow | glow X 1000 or glow X 500 loop |
Pulsing glow effect. Optional color: glow X 1500 loop "#ff0000" |
| Animate | stop effects | stop X |
Stop fire-and-forget effects on object |
| Animate | screenshake | screenshake 300 |
Camera/viewport shake. Optional intensity (default 3): screenshake 200 5. Intensity range: screenshake 2000 1-5 (ramps from 1 to 5). Add loop to repeat. Non-looping damps to zero |
| Animate | stop screenshake | stop screenshake |
Stop camera shake |
| AUDIO | |||
| Audio | play | play Music |
Start or resume playback |
| Audio | play loop | play Music loop |
Play with looping |
| Audio | pause | pause Music |
Pause (resume with play) |
| Audio | stop | stop Music |
Stop and reset to beginning |
| Audio | volume | set Music.volume 0.5 |
Set volume (0-1) |
| Audio | loop | set Music.loop true |
Set loop property |
| Audio | startMarker | set Music.startMarker 5 |
Start position in seconds |
| Audio | duration | set Music.duration 10 |
Playback duration from start marker in seconds |
| Audio | autoplay | Object property | Auto-play on cell enter |
| Audio | extend | Object property | Keep playing across cell transitions |
| Audio | buffered | Object property | Independent playback per instance (default: true for SFX) |
| Audio | spatial | Object property | Distance-based volume from camera subject |
| Audio | spatialRange | Object property | Distance (0-1) where volume reaches 0 (default: 1.0) |
| EMITTER | |||
| Emitter | emitterShape | Object property | Emit shape: "circle" (outward) or "rectangle" (top edge inward) |
| Emitter | emitterRate | Object property | Particles per second (default: 10) |
| Emitter | emitterBurst | Object property | Set to N to emit N particles instantly (resets to 0) |
| Emitter | particleLifetime | Object property | Particle lifetime in ms (default: 1000) |
| Emitter | particleSpeedMin | Object property | Min speed canvas-units/sec (default: 0.1) |
| Emitter | particleSpeedMax | Object property | Max speed canvas-units/sec (default: 0.3) |
| Emitter | particleSpread | Object property | Emission arc degrees — circle: cone width, rectangle: deviation (default: 30) |
| Emitter | particleShape | Object property | Particle shape: "circle", "square", or "line" |
| Emitter | particleTrailLength | Object property | Trail positions (0=off, default: 0) |
| Emitter | particleSizeStart | Object property | Starting size px (default: 6) |
| Emitter | particleSizeEnd | Object property | Ending size px (default: 2) |
| Emitter | particleOpacityStart | Object property | Starting opacity 0-1 (default: 1) |
| Emitter | particleOpacityEnd | Object property | Ending opacity 0-1 (default: 0) |
| Emitter | particleColorA | Object property | Spawn color range start (default: #ffffff) |
| Emitter | particleColorB | Object property | Spawn color range end (default: #ffffff) |
| Emitter | particleColorEnd | Object property | Optional fade-to color over lifetime |
| Emitter | particleGravityX | Object property | World gravity X (default: 0) |
| Emitter | particleGravityY | Object property | World gravity Y (default: 0) |
| Emitter | particleDrag | Object property | Velocity damping 0-1/sec (default: 0) |
| Emitter | emitterGlow | Object property | Halo glow intensity 0-1 (default: 0) |
| Emitter | emitterGlowSize | Object property | Halo size multiplier (default: 1.5) |
| Emitter | emitterGlowFlicker | Object property | Halo flicker amplitude 0-1 (default: 0) |
| CONTROL FLOW | |||
| Control | if | if condition: |
Conditional block |
| Control | else | else: |
Alternative block |
| Control | else if | else if condition: |
Chained conditional |
| Control | foreach | foreach item in list: |
Iterate over array or tagged objects |
| Control | repeat | repeat: |
Infinite loop — runs until break or cell exit. Use wait for pacing. Reads live variables each iteration |
| Control | repeat N | repeat 5: |
Loop N times |
| Control | first | first #tag where .x > 0: |
Find first matching object |
| Control | action | action name: or action name { } |
Define reusable code block |
| Control | do | do actionName or do Object.actionName |
Execute custom action |
| TARGETING | |||
| Target | By name | ObjectName |
Direct reference |
| Target | By tag | #tagname |
All objects with tag |
| Target | By type | all shapes |
All objects of type |
| Target | self | self |
Current object |
| Target | self property | self.name, self.x |
Read/write property on current object |
| Target | parent | parent |
Containing component |
| Target | parent property | parent.name, parent.x |
Read/write property on parent component |
| Target | siblings | siblings |
Objects at same level |
| Target | children | children |
Contained objects |
| Target | children property | children.opacity |
Read/write property on all children |
| Target | other | other |
Other object in overlap/collision |
| Target | other property | other.name, other.x |
Read property on the other object in overlap/collision |
| Target | Component child | Component.Child |
Child inside component |
| Target | Self child | self.Child.property |
Access child of current component. Read/write: self.Turret.rotation |
| Target | Cross-cell | @Cell.Object |
Object in different cell |
| Target | Cross-cell prop | @Cell.Object.property |
Read property from another cell |
| Target | State read | X.states.StateName.property |
Read property from a named state |
| Target | Cross-cell state | @Cell.Object.states.State.prop |
Read state property from another cell |
| PROPERTIES | |||
| Property | name | X.name |
Object name (read-only) |
| Property | id | X.id |
Object ID (read-only, unique identifier) |
| Property | x | X.x |
Horizontal position (0-1) |
| Property | y | X.y |
Vertical position (0-1) |
| Property | width | X.width |
Width (0-1) |
| Property | height | X.height |
Height (0-1) |
| Property | visible | X.visible |
Boolean visibility |
| Property | clickable | X.clickable |
Boolean — accepts clicks |
| Property | opacity | X.opacity |
Transparency (0-1) |
| Property | blendMode | X.blendMode |
Compositing blend mode: normal, multiply, screen, overlay, darken, lighten, color-dodge, color-burn |
| Property | rotation | X.rotation |
Angle in degrees (0-360) |
| Property | flipX | X.flipX |
Horizontal flip |
| Property | flipY | X.flipY |
Vertical flip |
| Property | zIndex | X.zIndex |
Layer order (higher = on top) |
| Property | content | X.content |
Text content |
| Property | textColor | X.textColor |
Text color |
| Property | fontSize | X.fontSize |
Font size (rem) |
| Property | fontFamily | X.fontFamily |
Font family |
| Property | fontWeight | X.fontWeight |
Font weight (normal, bold, etc.) |
| Property | fontStyle | X.fontStyle |
Font style (normal, italic) |
| Property | textDecoration | X.textDecoration |
Text decoration (none, underline, etc.) |
| Property | textAlign | X.textAlign |
Text alignment (left, center, right) |
| Property | textPadding | X.textPadding |
Text padding |
| Property | lineHeight | X.lineHeight |
Line spacing multiplier (textbox only, default 1.3) |
| Property | verticalAlign | X.verticalAlign |
Vertical text alignment: top, center, bottom (textbox only) |
| Property | editable | X.editable |
Allow typing at runtime (text only). Click to focus, Enter to submit, Escape to revert |
| Property | fillColor | X.fillColor |
Fill color (read/write shorthand) |
| Property | color.color | X.color.color |
Fill color (layer path) |
| Property | color.opacity | X.color.opacity |
Color layer opacity (0-1) |
| Property | fill.color | X.fill.color |
Fill color (alias for color.color) |
| Property | strokeColor | X.strokeColor |
Border color |
| Property | strokeWidth | X.strokeWidth |
Border width |
| Property | strokeStyle | X.strokeStyle |
Border style (solid, dashed, dotted) |
| Property | cornerRadius | X.cornerRadius |
Corner rounding |
| Property | shadowX | X.shadowX |
Shadow horizontal offset |
| Property | shadowY | X.shadowY |
Shadow vertical offset |
| Property | shadowBlur | X.shadowBlur |
Shadow blur radius |
| Property | shadowColor | X.shadowColor |
Shadow color |
| Property | glowBlur | X.glowBlur |
Glow spread radius |
| Property | glowColor | X.glowColor |
Glow color |
| Property | glowIntensity | X.glowIntensity |
Glow intensity (1-10, higher = more solid) |
| Property | tags | set X.tags ["a", "b"] |
Object tags (array of strings) |
| Property | spriteFrame | X.spriteFrame |
Current sprite sheet frame (0-based). Requires sprite image fill |
| Property | state | X.state |
Current state name (any object) |
| Property | set state | set X.state "RED" |
Apply state (composable — patches delta onto current) |
| Property | set state next | set X.state next |
Cycle to next available state. Wraps around. No-op if object has 0 or 1 states |
| Property | state modifier: none | set X.state "Y" none |
Skip spatial properties (position, size, rotation, flip) |
| Property | state modifier: position | set X.state "Y" position |
Apply only position + non-spatial |
| Property | state modifier: rotate | set X.state "Y" rotate |
Apply only rotation/flip + non-spatial |
| Property | state modifier: scale | set X.state "Y" scale |
Apply only size + non-spatial |
| Property | state combined | set X.state "Y" position rotate |
Modifiers combine: position + rotation filter |
| Property | mass | X.mass |
Object mass (affects forces) |
| Property | gravityScale | X.gravityScale |
Gravity multiplier (0=weightless, 1=normal, 2=heavy) |
| Property | windScale | X.windScale |
Wind multiplier (0=immune, 1=normal, 2=extra) |
| Property | dragScale | X.dragScale |
Drag multiplier (0=no drag, 1=normal, 2=heavy) |
| Property | rotatable | X.rotatable |
Enable angular physics (tipping, torque) |
| Property | level | X.level |
Elevation level (integer, default 0). Objects at different levels don't collide, aren't detected by sensors, and are excluded from nearby(). Set to ALL (-999) to collide at every level |
| Property | ghost | X.ghost |
Invisible to blocking collision. Sensors are auto-ghost |
| Property | perspectiveX | X.perspectiveX |
Perspective scroll factor X (0=stationary, 1=full scroll) |
| Property | perspectiveY | X.perspectiveY |
Perspective scroll factor Y (0=stationary, 1=full scroll) |
| Property | revealer | X.revealer |
Boolean — auto-reveal overlapping masks as object moves |
| Property | revealerRadius | X.revealerRadius |
Reveal radius in mask-relative units |
| Property | revealerFade | X.revealerFade |
Reveal edge fade (blur width, mask-relative units) |
| Property | revealerNoise | X.revealerNoise |
Reveal edge noise (0=smooth, 1=max) |
| Property | revealerShape | X.revealerShape |
Reveal shape: circle or rect |
| Property | revealTags | set X.revealTags ["mask1"] |
Only reveal masks with matching tags (empty = all masks) |
| Property | revealerRehide | X.revealerRehide |
Boolean — fog returns when revealer moves away |
| Property | revealerRehideSpeed | X.revealerRehideSpeed |
Delay before fog starts regrowing (seconds) |
| Property | revealerRehideGrowth | X.revealerRehideGrowth |
Regrowth time — how long each stamp takes to close (seconds, 0=instant) |
| Property | revealerRehideRate | X.revealerRehideRate |
Rehide speed multiplier (1=normal, 2=twice as fast) |
| Property | revealerRehideStopThreshold | X.revealerRehideStopThreshold |
Pause rehide when stopped briefly (seconds, 0=disabled) |
| Property | trail | X.trail |
Enable motion trail (boolean) |
| Property | trailLength | X.trailLength |
Trail distance in world units (default 0.3) |
| Property | trailOpacity | X.trailOpacity |
Trail starting opacity (default 0.3) |
| Property | trailColor | X.trailColor |
Trail color (default: object fill) |
| Property | trailScale | X.trailScale |
Trail taper — tail/head width ratio (default 0.3, 0=pointed, 1=uniform) |
| Property | trailWidth | X.trailWidth |
Trail width multiplier of min(width, height) (default: 1) |
| Property | lineX1 | X.lineX1 |
Line start X coordinate |
| Property | lineY1 | X.lineY1 |
Line start Y coordinate |
| Property | lineX2 | X.lineX2 |
Line end X coordinate |
| Property | lineY2 | X.lineY2 |
Line end Y coordinate |
| Property | lineStartMarker | X.lineStartMarker |
Line start marker: none, arrow, circle, square, diamond |
| Property | lineEndMarker | X.lineEndMarker |
Line end marker: none, arrow, circle, square, diamond |
| Property | lineCap | X.lineCap |
Line cap style: butt, round, square |
| Property | pegType | X.pegType |
Peg constraint type: pin (hinge) or weld (rigid) |
| Property | pegDamping | X.pegDamping |
Swing friction (0 = swings forever, 1 = stops quickly) |
| Property | pegBreakForce | X.pegBreakForce |
Force threshold to break the peg connection |
| Property | springStiffness | X.springStiffness |
Spring stiffness (0 = rigid rod, higher = more elastic). Spring objects only |
| Property | springDamping | X.springDamping |
Spring energy dissipation. Spring objects only |
| Property | springBreakForce | X.springBreakForce |
Force threshold to break the spring |
| Property | gradient.angle | X.gradient.angle |
Gradient rotation (0-360) |
| Property | gradient.gradientType | X.gradient.gradientType |
Gradient type: linear or radial |
| Property | gradient.opacity | X.gradient.opacity |
Gradient layer opacity (0-1) |
| Property | pattern.pattern | X.pattern.pattern |
Pattern type name |
| Property | pattern.scale | X.pattern.scale |
Pattern scale |
| Property | pattern.color | X.pattern.color |
Pattern color |
| Property | pattern.opacity | X.pattern.opacity |
Pattern layer opacity (0-1) |
| Property | noise.noiseType | X.noise.noiseType |
Noise type: fractalNoise or turbulence |
| Property | noise.scale | X.noise.scale |
Noise scale |
| Property | noise.intensity | X.noise.intensity |
Noise intensity (0-1) |
| Property | noise.monochrome | X.noise.monochrome |
Grayscale noise (boolean) |
| Property | noise.opacity | X.noise.opacity |
Noise layer opacity (0-1) |
| Property | image.mode | X.image.mode |
Image mode: fill, fit, or tile |
| Property | image.scale | X.image.scale |
Image scale |
| Property | image.opacity | X.image.opacity |
Image layer opacity (0-1) |
| Property | innerShadow.color | X.innerShadow.color |
Inner shadow color |
| Property | innerShadow.blur | X.innerShadow.blur |
Inner shadow blur radius (px) |
| Property | innerShadow.offsetX | X.innerShadow.offsetX |
Inner shadow X offset (px) |
| Property | innerShadow.offsetY | X.innerShadow.offsetY |
Inner shadow Y offset (px) |
| Property | innerShadow.opacity | X.innerShadow.opacity |
Inner shadow layer opacity (0-1) |
| TIME SCALE | |||
| Time Scale | Object | set self.timeScale 0 |
Per-object time scale override (0=frozen, 0.5=half, 1=normal, 2=double). Overrides Cell.timeScale for this object |
| Time Scale | Cell | set Cell.timeScale 0 |
Time scale for all objects in the cell. Per-object timeScale overrides this. Supports over: set Cell.timeScale 0 over 500 |
| OBJECT VARIABLES | |||
| Object var | set | set self.energy 100 |
Per-object variable (any name not a built-in property) |
| Object var | read | self.energy |
Read object variable in expressions |
| Object var | tag set | set #robots.energy 50 |
Set on each tagged object independently |
| Object var | children | set children.speed 3 |
Set on each child independently |
| Object var | foreach | foreach r in #robots: set r.score r.score + 1 |
Per-object in loops |
| MOVEMENT | |||
| Movement | cellX | X.cellX |
Grid column (0-based). Writable: set X.cellX 2 |
| Movement | cellY | X.cellY |
Grid row (0-based). Writable: set X.cellY 3 |
| Movement | moving | X.moving |
Boolean — is moving. Read-only |
| Movement | direction | X.direction |
up, down, left, right, none. Read-only |
| Movement | velocityX | X.velocityX |
Horizontal velocity. Writable: set X.velocityX 0.5 sets absolute velocity |
| Movement | velocityY | X.velocityY |
Vertical velocity. Writable: set X.velocityY -0.3 sets absolute velocity |
| Movement | moveAngle | X.moveAngle |
Movement angle in degrees (0=right, 90=down, -1=stopped). Read-only |
| Movement | moveSpeed | X.moveSpeed |
Movement speed magnitude. Read-only |
| Movement | angularVelocity | X.angularVelocity |
Rotation speed (requires rotatable). Read-only |
| Movement | followDistance | X.followDistance |
Current follow/avoid distance. Read/write. Only available when follow/avoid is enabled |
| MOVABLE | |||
| Movable | Enable | enable X movable |
Enable with defaults |
| Movable | speed | enable X movable speed 0.5 |
Max velocity (default: 0.3) |
| Movable | acceleration | enable X movable acceleration 0.5 |
Seconds to reach max speed (0=instant, default: 0) |
| Movable | deceleration | enable X movable deceleration 1 |
Seconds to stop from max speed (0=instant, default: 0.3) |
| Movable | style | enable X movable style slide |
Animation: teleport, slide, jump, fade (default: teleport) |
| Movable | axis | enable X movable axis x |
Constrain to one axis: x (horizontal only), y (vertical only), or forward (steering mode) |
| Movable | steer | enable X movable axis forward steer 1.5 |
Steering turn rate multiplier (default 1). Only with axis forward |
| Movable | path | enable X movable speed 0.3 path Track |
Constrain movement along a named path (line, curve, or polygon). Object moves forward/back along the path instead of freely. Combine with speed, steer, etc. |
| Movable | path reverse | enable X movable path Track reverse |
Faces opposite direction along the path |
| Movable | path span | enable X movable path Track span 0.8 |
Two-point path binding: front/rear contact points separated by object width × span factor (default 1.0). Requires steer or faceTravel. Object straddles curves naturally |
| Movable | faceTravel | enable X movable path Track faceTravel |
Face direction of travel on path. Flips 180° when reversing. Implies steer |
| Movable | turnaround | enable X movable path Track faceTravel turnaround |
Smooth rotation when direction changes (uses steerRate). Modifier for faceTravel |
| Movable | facing | enable X movable facing |
Auto-rotate to face movement direction (smooth lerp). The right side of the object (0°) is treated as the front. Mutually exclusive with rotatable and axis forward |
| Movable | stable | set X.stable true |
Geometric collision (default off). When on: no momentum transfer between movers. Use for vehicles in top-down games where movers should stop cleanly on contact. Also: enable X movable stable |
| Movable | dodge | enable X movable dodge |
Steer around other moving objects (axis=forward only). On/off toggle |
| Movable | Combined | enable X movable speed 0.5 axis x deceleration 0.1 |
Multiple params |
| Movable | Disable | disable X movable |
Turn off |
| INPUT | |||
| Input | keyboard | enable X keyboard |
WASD + arrow keys control |
| Input | click | enable X click |
Click-to-move control |
| Input | gamepad | enable X gamepad |
Gamepad left stick + D-pad |
| Input | script | enable X script |
Script input — responds to press/release commands only, not physical keyboard. Use for AI-controlled objects, virtual buttons, automation |
| Input | multi-input | enable X keyboard then enable X gamepad |
Multiple inputs combine — keyboard + gamepad are additive, click is fallback |
| Input | Disable | disable X keyboard |
Remove specific input type |
| Input | none | (default) | Physics only, no player control |
| JUMPABLE | |||
| Jumpable | Enable | enable X jumpable |
Enable with defaults |
| Jumpable | height | enable X jumpable height 0.8 |
Jump impulse (default: 0.5) |
| Jumpable | multijump | enable X jumpable multijump 2 |
Max jumps before landing (default: 1) |
| Jumpable | key | enable X jumpable key "w" |
Custom jump key (default: Space) |
| Jumpable | Combined | enable X jumpable height 0.6 multijump 2 |
Multiple params |
| Jumpable | Disable | disable X jumpable |
Turn off |
| Jumpable | jump | jump X |
Trigger jump impulse from script. Bypasses key input and multi-jump counter |
| Jumpable | jump height | jump X height 0.8 |
Jump with height override. Accepts expressions: jump self height random(0.3, 0.8) |
| IMPULSE | |||
| Impulse | impulse | impulse X vx vy |
Add velocity to object. Additive — accumulates with existing velocity |
| Impulse | impulse expr | impulse self random(-0.2, 0.2) -0.5 |
Accepts expressions for both vx and vy |
| Impulse | set velocity | set X.velocityX 0.5 |
Set absolute velocity (not additive). Also: velocityY, vx, vy |
| TRANSPORT | |||
| Transport | basic | transport X to 0.5 0.5 over 1000 |
Smoothly move to (x, y) over duration (ms). Real position updates each frame |
| Transport | easing | transport X to 0.5 0.5 over 500 ease-in-out |
With easing: ease-in, ease-out, ease-in-out, ease-in-cubic, ease-out-cubic, ease-in-out-cubic |
| Transport | dynamic | transport X to Player.x Player.y over 300 |
Target can be any expression (evaluated at call time) |
| Transport | multi | transport #tag to 0.5 0.5 over 500 |
Transport all tagged objects. Also: self, siblings, children |
| Transport | notes | No collision, no movable required. Physics bypassed during transit. Fires onMove/onStop events. New transport replaces old. set X.x cancels |
|
| MOVETO | |||
| MoveTo | basic | moveTo X 0.5 0.5 |
Move to position using movable speed. Obeys physics — collides with blockers, affected by gravity |
| MoveTo | self | moveTo self 0.5 0.5 |
Move current object to position |
| MoveTo | dynamic | moveTo self Player.x Player.y |
Target can be any expression |
| MoveTo | multi | moveTo #robots Player.x Player.y |
Move all tagged objects. Also: self, other, siblings, children |
| MoveTo | notes | Requires movable. Uses object's speed/acceleration. Uses A* pathfinding around static obstacles. Fires onArrive on arrival (use instead of onStop for waypoint logic). Keyboard/gamepad overrides direction. New moveTo replaces old target |
|
| SYNTHETIC KEYS | |||
| Press | basic | press "q" |
Send a script key-down to the current object. Fires onKeyDown handlers. Objects need Script input enabled to respond |
| Press | target | press "Space" on Tank |
Inject key-down on a specific object. Fires onKeyDown on that object and its children |
| Press | movement | press "ArrowLeft" |
Also updates the input system — movable+keyboard objects will start moving, just like a physical keypress |
| Release | basic | release "q" |
Send a script key-up to the current object. Fires onKeyUp handlers |
| Release | target | release "Space" on Tank |
Inject key-up on a specific object |
| Release | movement | release "ArrowLeft" |
Clears the key from the input system — movable+keyboard objects stop receiving that direction |
| Script Keys | cell context | press "Space" |
When called from a cell script, injects globally — all objects with Script input respond |
| Script Keys | hold pattern | press without matching release keeps the key held. Standard pattern: press "q" → (wait or tick logic) → release "q" |
|
| Script Keys | use case | AI control: sense target → calculate bearing → press "q" to rotate → press "Space" to fire. Also powers virtual buttons and automated movement |
|
| FOLLOW / AVOID | |||
| Follow | follow | enable Dog follow "Player" |
Object moves toward target. Requires movable. Target can be a variable: enable self follow myTarget |
| Follow | distance | enable Dog follow "Player" distance 0.2 |
Maintain distance from target (default: 0 = reach target). Negative = overlap. Distance is edge-to-edge by default |
| Follow | followDistance | set Dog.followDistance 0.1 |
Read/write follow distance at runtime without re-specifying target. Only works when follow/avoid is active |
| Follow | center | enable Dog follow "Player" distance 0.2 center |
Measure distance center-to-center instead of edge-to-edge |
| Follow | rigid | enable self follow leader distance 0.05 rigid |
Deterministic trail follow. Follower traces target's exact position history at fixed arc-length offset. No breadcrumb intelligence — pure position replay. Ideal for snake-like chains |
| Follow | tag | enable #robots follow "Player" |
All tagged objects follow target |
| Follow | avoid | enable Dog avoid "Player" |
Object moves away from target |
| Follow | avoid distance | enable Dog avoid "Player" distance 0.3 |
Flee only when closer than distance |
| Follow | deadZone | enable Dog follow "Player" deadZone 0.02 |
Stop within this distance of target (default: 0.015). Prevents fidgeting |
| Follow | arrival | enable Dog follow "Player" arrival 0.15 |
Begin decelerating within this distance (default: 0.08). Larger = smoother |
| Follow | steering | enable Tank follow "Player" |
Steered objects (axis forward) automatically turn toward target and drive forward |
| Follow | pathfinding | enable Dog follow "Player" pathfinding |
A* pathfinding around static obstacles when stuck. Follower routes around blockers to reach breadcrumb waypoints |
| Follow | disable | disable Dog follow |
Stop following or avoiding |
| Follow | priority | Manual input (keyboard, gamepad) overrides follow direction | |
| PHYSICS ZONES | |||
| Zone | enable | enable WaterRegion zone gravity 0.3 drag 0.8 |
Object becomes a physics zone — overrides cell physics for contained objects |
| Zone | gravity | enable X zone gravity 0 |
Override gravity (0 = weightless) |
| Zone | wind | enable X zone wind 5 windAngle 0 |
Override wind magnitude and direction (degrees, 0=right, 90=down) |
| Zone | drag | enable X zone drag 0.8 |
Override drag coefficient (0=vacuum, 1=thick) |
| Zone | flow | enable X zone flowX 0.3 |
Constant drift (mass-independent, like conveyor/current). Also: flowY |
| Zone | combined | enable X zone gravity 0 drag 0 |
Multiple overrides. Omitted params use cell defaults |
| Zone | affects | enable X zone gravity 0.3 affects #swimmer |
Only affect objects with matching tag. Multiple tags use OR logic: affects #light #paper. Omit for all objects (default) |
| Zone | disable | disable X zone |
Deactivate zone — physics reverts to cell defaults |
| Zone | containment | Object is "in" zone when its center point is inside the zone's collision shape | |
| Zone | priority | Smallest zone wins when multiple zones overlap | |
| SPAWN PARAMS | |||
| Spawn | position | spawn "T" {x: 0.5, y: 0.3} |
Spawn at specific position |
| Spawn | velocity | spawn "T" {vx: 2, vy: -1} |
Spawn with initial velocity |
| Spawn | combined | spawn "T" {x: self.x, y: self.y, vx: 2, vy: -1} |
Position + velocity. Other params pass to onSpawn |
| Spawn | at anchor | spawn "T" at MuzzlePoint |
Spawn at anchor's position and rotation |
| Spawn | at + params | spawn "T" at MuzzlePoint {vx: 1} |
Anchor position + custom params |
| DRAGGABLE | |||
| Draggable | Enable | enable X draggable |
Enable basic drag |
| Draggable | once | enable X draggable once |
Can only drag one time |
| Draggable | collision | enable X draggable collision |
Respect blockers while dragging |
| Draggable | discrete | enable X draggable discrete |
Grid objects move cell-by-cell |
| Draggable | discrete occupy | enable X draggable discrete occupy |
Reject drop if cell occupied |
| Draggable | Combined | enable X draggable discrete occupy collision |
Multiple options |
| Draggable | Disable | disable X draggable |
Turn off |
| COLLISION | |||
| Collision | enable blocking | enable X blocking |
Enable collision blocking. Optional affects #tag to only block tagged movers |
| Collision | disable blocking | disable X blocking |
Disable collision blocking |
| Collision | blocking expr | set X.blocking "self.color != other.color" |
Conditional blocking expression |
| Collision | enable sensor | enable X sensor |
Enable overlap detection. Optional affects #tag to only detect tagged objects |
| Collision | disable sensor | disable X sensor |
Disable overlap detection |
| Collision | enable phase | enable X phase affects #tag |
Phase through blockers. Without affects, phases through all. With affects #tag, only phases through tagged blockers |
| Collision | disable phase | disable X phase |
Disable phasing (resume normal collisions) |
| Collision | ghost | set X.ghost true |
Invisible to blocking collision. Sensors are auto-ghost |
| Collision | oneWay | set X.oneWay true |
One-way platform (pass through from below) |
| Collision | pullable | set X.pullable true |
Can be pulled by other objects |
| Collision | friction | set X.friction 0.5 |
Surface friction (0-1) |
| Collision | restitution | set X.restitution 0.5 |
Bounciness (-1 to 1). Negative absorbs bounce (sticky surface) |
| GRID | |||
| Grid | snapToGrid | set X.snapToGrid "GridName" |
Attach object to grid |
| Grid | cellX | set X.cellX 2 |
Set grid column |
| Grid | cellY | set X.cellY 3 |
Set grid row |
| Grid | cell data write | set Grid.cell[x][y].prop value |
Store metadata |
| Grid | cell data read | Grid.cell[x][y].prop |
Read metadata |
| CAMERA | |||
| Camera | subject | enable X subject |
Camera follows this object |
| Camera | disable subject | disable X subject |
Stop camera following |
| Camera | canvasDraggable | set Cell.canvasDraggable false |
Disable manual panning |
| Camera | zoom | set Camera.zoom 2 |
Zoom level (1 = default, 2 = 2x closer). Read/write: Camera.zoom returns current value |
| Camera | x | set Camera.x 1.5 |
Viewport center X in world coordinates. Read/write. Clamped to cell bounds |
| Camera | y | set Camera.y 0.5 |
Viewport center Y in world coordinates. Read/write. Clamped to cell bounds |
| Camera | aspectRatio | set Camera.aspectRatio 1.78 |
Viewport aspect ratio (width/height). Read/write. Set to Screen.aspectRatio to fill screen |
| Camera | viewportWidth | Camera.viewportWidth |
Visible width in world units (read-only) |
| Camera | viewportHeight | Camera.viewportHeight |
Visible height in world units (read-only) |
| Camera | subjectTransition | set Camera.subjectTransition 500 |
Duration (ms) for smooth pan when switching subjects. 0 = snap (default) |
| SCREEN | |||
| Screen | aspectRatio | Screen.aspectRatio |
Actual device/window aspect ratio (read-only) |
| Screen | width | Screen.width |
Window width in pixels (read-only) |
| Screen | height | Screen.height |
Window height in pixels (read-only) |
| CELL PROPERTIES | |||
| Cell | width | Cell.width |
Cell width in screens (read-only) |
| Cell | height | Cell.height |
Cell height in screens (read-only) |
| Cell | gravity | set Cell.gravity 1.5 |
Vertical acceleration (-10 to 10) |
| Cell | wind | set Cell.wind 0.3 |
Wind magnitude (-10 to 10) |
| Cell | windAngle | set Cell.windAngle 90 |
Wind direction (0=right, 90=down) |
| Cell | drag | set Cell.drag 0.1 |
Air drag |
| Cell | timeScale | set Cell.timeScale 0 |
Time scale for all objects (0=paused, 0.5=half, 1=normal, 2=double). Supports over for smooth transition: set Cell.timeScale 0 over 500 |
| Cell | backgroundColor | set Cell.backgroundColor "#ff0000" |
Cell background color |
| Cell | backgroundPattern | set Cell.backgroundPattern "grid" |
Cell background pattern |
| Cell | patternColor | set Cell.patternColor "rgba(0,0,0,0.2)" |
Pattern overlay color |
| Cell | patternScale | set Cell.patternScale 1.5 |
Pattern scale (0.5-2) |
| FUNCTIONS | |||
| Math | random | random(1, 6) |
random() returns 0-1 float. random(min, max) returns integer when both args are integers, float when either has decimals. random(1, 6, float) forces float mode |
| Math | floor | floor(x) |
Round down |
| Math | ceil | ceil(x) |
Round up |
| Math | round | round(x) |
Round to nearest |
| Math | abs | abs(x) |
Absolute value |
| Math | min | min(a, b) |
Smaller value |
| Math | max | max(a, b) |
Larger value |
| Math | hash | hash(values...) |
Hash from any number of values. hash(x, y), hash(#tag.prop). Deterministic — same inputs always give same result |
| Math | sin | sin(degrees) |
Sine of angle in degrees. sin(90) → 1 |
| Math | cos | cos(degrees) |
Cosine of angle in degrees. cos(0) → 1 |
| Math | atan2 | atan2(y, x) |
Angle in degrees from coordinates. atan2(1, 0) → 90 |
| Math | cardinal | cardinal(angle) |
Angle to direction: right, down, left, up |
| Arrays | length | length(arr) |
Array length |
| Arrays | range | range(5) or range(0, 5) |
range(n) returns [0..n-1]. range(min, max) returns [min..max] inclusive |
| Arrays | shuffle | shuffle(arr) |
Randomize array order |
| Arrays | pick | pick(arr) |
Random element from array |
| Conditions | visited | visited("Cell") |
Boolean — has cell been visited |
| Conditions | visits | visits("Cell") |
Number of times cell was visited |
| Conditions | hasObject | hasObject("Name") |
Boolean — does object exist in current cell |
| Conditions | hasSave | hasSave("checkpoint") |
Boolean — does save slot exist |
| Conditions | get | get("scope.key") |
Read variable value (returns undefined if unset) |
| Grid | isEmpty | isEmpty("Grid", x, y) |
Check if grid cell has no object |
| Grid | emptyCells | emptyCells("Grid") |
Array of {x, y} for empty cells |
| Grid | cellsWhere | cellsWhere("Grid", "prop", "==", val) |
Find cells by metadata |
| Grid | floodfill | floodfill("Grid", x, y, "prop", val, connectivity) |
Find connected cells. Connectivity: 4 (cardinal) or 8 (default, + diagonal) |
| Grid | minimax | minimax("Grid", "prop", "AI", "Human", depth, empty, winLen) |
AI best move for N-in-a-row games. Returns {x, y} or 0 |
| SPATIAL | |||
| Spatial | distance | distance(self, Target) |
Euclidean distance between two objects (0–1 coords). Works with self, other, or object names |
| Spatial | nearby | nearby(self, 0.2) or nearby(self, 0.2, #tag) |
Objects within radius, sorted by distance. Returns [{name, x, y, distance}]. Optional tag filter. Level-filtered: only returns objects at the same level as the reference (ALL level sees everything) |
| Spatial | nearest | nearest(self, #coin) |
Closest object to reference. Filter by #tag, name, or "sibling". Also: nearest(x, y, #tag) from coordinates. Add rank for Nth nearest: nearest(self, #robot, 2). Returns {name, x, y, distance} or 0. Level-filtered (same as nearby). Store in a variable to read fields: set t nearest(...) then t.x, t.y, t.name, t.distance. To store per-object, copy to properties: set self.tx t.x |
| Spatial | intersects | intersects(Paddle, Target) |
SAT collision test. Also: intersects(self, #tag) — true if any tagged object overlaps. Level-filtered: objects at different levels never intersect (ALL level intersects everything) |
| Spatial | randomFree | randomFree(self, 0.3) or randomFree(x, y, 0.3) |
Random unblocked position within radius. Uses pathfinding bitmap. Returns {x, y} or 0. Two forms: object ref (current position as center) or coordinates (fixed point for patrol). Level-filtered |
| Spatial | canSee | canSee("Grid", x1, y1, x2, y2, "wall") |
Line of sight via Bresenham. Blocked by cells where the given property is truthy. Default prop: "wall" |
| Spatial | pathfind | pathfind("Grid", x1, y1, x2, y2, "wall") |
A* pathfinding. Returns [{x, y}] waypoints (excl. start, incl. goal). Default blocker: "wall" |
| Spatial | generateMaze | generateMaze("Grid", "wall") |
Recursive backtracker maze. Sets cell data: true = wall, false = passage. Best with odd-dimension grids |
| BUILT-IN VARIABLES | |||
| Variable | random | random |
Fresh random number 0-1 each access |
| Variable | currentCell | currentCell |
Name of the current cell |
| Variable | clicks | clicks |
How many times current object was clicked |
| Variable | clickX | clickX |
Pointer X in world units. Available in onClick, onDrag*, onHover* |
| Variable | clickY | clickY |
Pointer Y in world units. Available in onClick, onDrag*, onHover* |
| Variable | deltaTime | deltaTime |
Frame time in seconds. Available in onTick. Multiply speeds by this for frame-rate independence |
| Variable | newGame | newGame |
True on normal cell entry, false when restored from a save (load command or auto-save resume). Use if newGame: to guard variable initialization |
| OPERATORS | |||
| Operator | Arithmetic | + - * / % |
Math operations (% is modulo) |
| Operator | Comparison | == != > < >= <= |
Compare values |
| Operator | Logical | and or not |
Boolean logic |
| Operator | Tag check | X is #tag |
Check if object has tag |
| Operator | Tag check (negated) | X is not #tag |
Check if object does NOT have tag |
| Operator | Array access | arr[i] or arr[i].prop |
Get element or property |
| AGGREGATES | |||
| Aggregate | all | all #tag.prop == value |
True if every tagged object matches |
| Aggregate | any | any #tag.prop == value |
True if at least one matches |
| Aggregate | count | count #tag.prop == value |
Number of tagged objects that match |
| Aggregate | count (simple) | count #tag |
Number of objects with tag (no condition) |
| BLOCK STYLES | |||
| Syntax | Colon | onClick: + indented block |
Indentation-based |
| Syntax | Braces | onClick { ... } |
Brace-delimited |
| Syntax | Single-line | onClick: show Panel |
One-liner |