Formula Globals
Built-in variables available in every formula, event handler, and method.
Try it
title: "Mouse and time globals"
description: "A shape that follows the mouse and rotates with time"
nodes:
- type: STAR, name: "Cursor", w: 40, h: 40, fill: "#E74C3C", points: 4
formulas:
- node: "Cursor", prop: "x", value: "mouse.x"
- node: "Cursor", prop: "y", value: "mouse.y"
- node: "Cursor", prop: "rotation", value: "time * 90"
tools_visible: [select, play]
ui_visible: [properties, formulas]Mouse
| Property | Type | Description |
|---|---|---|
mouse.x | number | Pointer X in world coordinates |
mouse.y | number | Pointer Y in world coordinates |
mouse.down | boolean | Any mouse button currently pressed |
mouse.button | number | Which button (0=left, 1=middle, 2=right) |
Mouse state is updated every frame during play mode and run mode. In formulas, mouse.x and mouse.y are reactive — formulas depending on them re-evaluate when the pointer moves.
this.x = mouse.x // follow cursor horizontallythis.y = mouse.y // follow cursor verticallythis.opacity = mouse.down ? 0.5 : 1 // dim when pressed
Keys
| Property | Type | Description |
|---|---|---|
keys.ArrowLeft | boolean | Left arrow pressed |
keys.ArrowRight | boolean | Right arrow pressed |
keys.ArrowUp | boolean | Up arrow pressed |
keys.ArrowDown | boolean | Down arrow pressed |
keys.Space | boolean | Space bar pressed |
keys.{KeyName} | boolean | Any key by its event.key name |
Key names match JavaScript's KeyboardEvent.key values: a, b, Shift, Control, Enter, etc.
// Move with arrow keysthis.x = this.x + (keys.ArrowRight ? 3 : 0) - (keys.ArrowLeft ? 3 : 0)this.y = this.y + (keys.ArrowDown ? 3 : 0) - (keys.ArrowUp ? 3 : 0)
// Sprint with Shiftspeed = keys.Shift ? 6 : 3this.x = this.x + (keys.ArrowRight ? speed : 0) - (keys.ArrowLeft ? speed : 0)
Time
| Property | Type | Description |
|---|---|---|
time | number | Elapsed time in seconds since play started |
dt | number | Delta time — seconds since last frame (~0.016 at 60fps) |
frame | number | Current frame number (0, 1, 2, ...) |
// Smooth rotation (degrees per second)this.rotation = time * 45 // 45 degrees per second `// Oscillation` `this.x = 200 + Math.sin(time * 2) * 100` // Frame-rate independent movementthis.x = this.x + speed * dt
``// Frame counterthis.opacity = frame % 60 < 30 ? 1 : 0.5 // blink every 0.5 seconds
Why dt matters
Without dt, movement speed depends on frame rate. A device running at 30fps moves half as fast as one at 60fps. Multiply by dt to make movement consistent:
// Bad — speed depends on frameratethis.x = this.x + 5
``// Good — 300 pixels per second regardless of frameratethis.x = this.x + 300 * dt
Tag
| Property | Type | Description |
|---|---|---|
Tag.{name} | VNode[] | Array of all nodes with that tag |
Tag.{name}.length | number | Count of tagged nodes |
Tag.{name}[i] | VNode | Access by index |
Tag.{name}[i].x | number | Property of indexed node |
Tags are reactive. When a tagged node is destroyed or a tag is added/removed, all formulas reading that tag re-evaluate.
// Win conditionWinText.visible = Tag.brick.length === 0 `// Score display` `ScoreBox.width = Tag.coin.length * 20` // First enemy positionArrow.rotation = Math.atan2(Tag.enemy[0].y - this.y, Tag.enemy[0].x - this.x) * 180 / Math.PI
Autocomplete: type Tag. — see all registered tag names.
Console
| Method | Description |
|---|---|
console.log(...) | Log to browser console |
console.info(...) | Info-level log |
console.warn(...) | Warning log |
console.error(...) | Error log |
Useful for debugging formulas and event handlers. Open browser DevTools (F12) to see output.
// Debug a collisionconsole.log("Hit:", event.target.name, "at", event.point.x, event.point.y)
Math
All Math methods are available:
| Method | Description |
|---|---|
Math.sin(x), Math.cos(x), Math.tan(x) | Trigonometry (radians) |
Math.atan2(y, x) | Angle from coordinates (radians) |
Math.abs(x) | Absolute value |
Math.floor(x), Math.ceil(x), Math.round(x) | Rounding |
Math.min(a, b), Math.max(a, b) | Min/max |
Math.sqrt(x), Math.pow(base, exp) | Power/root |
Math.random() | Random 0-1 |
Math.PI | 3.14159... |
// Distance between two nodesdistance = Math.sqrt((A.x - B.x) ** 2 + (A.y - B.y) ** 2) `// Angle from node to mouse` `angle = Math.atan2(mouse.y - this.y, mouse.x - this.x)` // Clamp valuevalue = Math.max(0, Math.min(100, rawValue))
Other globals
| Global | Description |
|---|---|
JSON.parse(str) | Parse JSON string |
JSON.stringify(obj) | Convert to JSON string |
parseInt(str) | Parse string to integer |
parseFloat(str) | Parse string to float |
isNaN(x) | Check if value is NaN |
isFinite(x) | Check if value is finite |
Number(x) | Convert to number |
String(x) | Convert to string |
setTimeout(fn, ms) | Delayed execution |
setInterval(fn, ms) | Repeated execution |
clearTimeout(id) | Cancel timeout |
clearInterval(id) | Cancel interval |
Special references
| Reference | Type | Description | |
|---|---|---|---|
this | VNode | The node owning the formula/event | |
parent | VNode \ | null | Parent node in the scene tree |
event | object | Event data (only in event handlers) |
→ Formulas API → Events API → Nodes