title: "Gizmo Language Specification" description: "An overview of the Gizmo drawing language" date: 2025-05-16 author: Michael Banham tags: ["software-development", "language design", "compilers" ] icon: "language.svg"

Overview

The Gizmo language is a declarative, javascript-like visual programming language designed for creating interactive diagrams and applications. It combines shape manipulation, reactive programming, and physics simulation capabilities.

You can write code in the code window on the left and save your creations. You can also drag and drop from the shape panels on the right to help you get started.

It's implemented at Gizmo Draw

Core Concepts

Shape Creation and Properties

// Basic shape creation
let myShape = shapeType { // circle, rect, polygon, ellipse, line, text, etc.
// Position
x: number,
y: number,

// Dimensions (shape-specific)
width?: number, // For rectangles
height?: number, // For rectangles
radius?: number, // For circles
r?: number, // For circles and polygons
sides?: number, // For polygons
rx?: number, // For ellipses
ry?: number, // For ellipses
x1?: number, // For lines
y1?: number, // For lines
x2?: number, // For lines
y2?: number, // For lines

// Visual properties
fill: string, // Color
stroke?: string, // Border color
strokeWidth?: number,
opacity?: number, // 0-1
transform?: string, // Custom SVG transform

// Physics properties (optional)
physics?: {
isStatic: boolean, // Fixed in place
mass: number, // 0.01 to 100
restitution: number, // Bounciness (0-1)
friction: number, // Friction coefficient (0-1)
linearDamping: number,// Air resistance (0-1)
velocity?: { // Initial velocity
x: number,
y: number
}
}
}()

Interactive Components

// Button
let myButton = button {
x: number,
y: number,
width?: number,
height?: number,
label: string
}()

// Slider
let mySlider = slider {
x: number,
y: number,
min: number,
max: number,
value: number,
step?: number,
label?: string
}()

// Text input
let myInput = text {
x: number,
y: number,
value: string,
fontSize?: number,
fontFamily?: string,
label?: string
}()

// Game Components
let myCannon = cannon {
x: number,
y: number,
width: number,
height: number,
fill: string,
physics: {
isStatic: boolean
},
transform: {
elementId: "cannon-barrel", // Target specific SVG element
rotate: number // Rotation angle in degrees
}
}()

Connections and Joints

// Basic connection
shape1--shape2

// Connection using specific anchors
shape1'anchor--shape2'anchor // anchors: n, s, e, w, c, start, end

// Hinge joint (implemented)
let myHinge = hinge {
x: number,
y: number,
r: number, // Radius
shapes: [shape1, shape2], // Shapes to connect
limits?: {
min: number, // Minimum angle in degrees
max: number // Maximum angle in degrees
},
stiffness?: number, // 0-1, joint stiffness
damping?: number // 0-1, rotation damping
}()

Physics World Properties and Functions

// Global physics settings
world.gravity = { x: number, y: number } // Set via setGravity()

// Physics functions
setGravity(x: number, y: number) // Set world gravity

// Coming soon:
// - world.timeScale
// - enablePhysics()
// - shape.applyForce()
// - shape.applyImpulse()

5. Events and Reactivity

// Component events
button.click {
// Event handler code
}

slider.change {
// Event handler code
// 'value' contains the new slider value
}

text.change {
// Event handler code
}

shape.collision {
Coming soon - not implemented yet
}

shape.sleep {
Coming soon - not implemented yet
}

shape.wake {
Coming soon - not implemented yet
}

Flow Control

If Statements

if (condition) {
// code block
} else if (condition) {
// code block
} else {
// code block
}

Conditions must evaluate to a boolean value. Supported operators:

  • Comparison: ==, !=, <, >, <=, >=
  • Logical: &&, ||, !
  • Grouping with parentheses: ()

Loops

For Loop

for (initialization; condition; increment) {
// code block
}

Example:

for (let i = 0; i < 10; i++) {
circle(i * 10, 100, 5)()
}

Example:

for (let i = 0; i < 100; i++) {
if (i % 2 == 0) continue // Skip even numbers
if (i > 50) break // Stop after 50
draw circle(i * 5, 100, 2)
}

Best Practices

  1. Physics Properties
    • Use isStatic: true for immovable objects
    • Keep mass values between 0.01 and 100
    • Set restitution (bounciness) between 0 and 1
    • Use linearDamping to prevent excessive movement
    • Initialize velocity for dynamic objects when needed
  2. Game Components
    • Use the transform property to target specific SVG elements
    • Combine physics properties with visual transforms
    • Use appropriate connection points for joints
    • Consider performance when creating many physics objects
  3. Connections and Joints
    • Use hinge joints to create articulated structures
    • Set reasonable limits for hinge joints
    • Apply appropriate stiffness and damping values
    • Consider using connection points (n, s, e, w) for visual connections
    • Note: Rigid connections and other joint types coming soon
  4. Performance
    • Minimize the number of physics-enabled objects
    • Use static objects where possible
    • Clean up unused connections and joints
    • Use appropriate damping values to prevent instability