Documentation
How MathPets works
A MathPets model is a plain-text file with named sections for the world, its parameters, the agents and the rules that run each tick. Start with the quickstart, read the language reference, or take the course.
Quickstart
Build Fire and Ants section by section: patches, pets, setup, steps and styles.
Start the quickstartLanguage reference
Sections, types, queries, actions and the update model, chapter by chapter.
Open the referenceCourse
Narrated units with exercises on running models.
Start the courseScope
What MathPets is for
MathPets is for models where local rules produce system-level behaviour: cellular automata, ecological and epidemic models, diffusion, foraging, flocking and networks. The source is meant to read the way a modeller would explain the system: what the world contains, what each agent stores, and which local transitions run each tick.
The compiler turns the source into JavaScript that runs in the browser, but the model file stays the thing people read and review: declarations first, setup once, then one or more step phases that repeat every tick.
small complete rule loop
world: x: -20..20 y: -20..20 topology: torus patches: state: empty | active = empty setup: patches: state := empty where (random-float(100) < 28): state := active step staged: patches: where active: state := empty where (empty and any neighbors8 where active): state := activeAuthoring
Web IDE, CLI, and VS Code
The studio is the main place to write models. It edits the source with inline diagnostics, runs the model in the browser, keeps drafts in local storage, and shows parameters, presets, styles and monitors next to the board.
The VS Code extension in packages/ide of the open-source core supports .pet files with syntax highlighting, completion, diagnostics and a side-panel preview. From the command line, the core compiles a model file to a standalone JavaScript module.
controls and monitors
params: density: number = slider(35, 0..100) show-grid: boolean = toggle(true) monitors: living-cells: number = count patches where alive patches: state: dead | alive = dead setup: patches: state := dead where (random-float(100) < density): state := alive step staged: patches: state := stateAuthoring
Controls and monitors come from the model
params: declarations are the inputs the Studio renders as widgets. A slider(value, min..max) becomes a number slider; a toggle(value) becomes a checkbox; a select(value) over an enum type becomes a dropdown. The model code reads the param as an ordinary declared value — no event wiring, no setter.
monitors: declarations are the readouts. Each monitor is an expression with a name and a type; the studio recomputes it every tick and shows it in the inspector. The style sidecar chooses whether a monitor renders as a value, a color scale, or a line graph.
The controls on the right are the studio's own widgets. The readout and sparkline under them are simulated for this page; open any model to see the same widgets wired to a running world.
source
params:
density: number = slider(62, 0..100)
show-grid: boolean = toggle(true)
seed-mode: single | random-seed = select(single)
monitors:
living-cells: number = count patches where alivecontrols
monitors
3D worlds
Explore the depth of a model
Turn tile values into terrain, spread a graph through space, or give pets a third coordinate. Declare the view under world:, then drag to orbit and scroll or pinch to zoom. Borders show the world’s extent from every angle.
Sandpile stacks grains as unit voxels. Conway 3D evolves a cubic lattice with 26 neighbors per cell. Flocking 3D sends directional birds through a volume, while Claude Black Hole arranges its connections in a 3D graph.
Choose cubes, spheres, arrows, or the pet’s usual shape in the model. Colours and sizes still come from the style sheet. Read the 3D reference →
Model Shape
Logic and display are separate
The model logic describes what exists and how it changes. It lives in sections such as world:, params:, patches:, pets:, setup:, and step:. State transitions stay semantic: a tree burns, a cell lives, an ant carries food.
The display describes how those states should look. Studio keeps display material in sidecar files such as styles.petstyle and presets.petpreset. That split lets the Studio restyle color, size, shape, visibility, and transitions without changing the simulation rules.
logic beside presentation
patches: state: empty | tree | burning | burned = empty step staged: patches: where burning: state := burned where (tree and any neighbors4 where burning): state := burningpatches: states: burning: color: "#f97316" burned: color: "#29180f" transition: 3Agents
Patches, pets, and lifecycle
Patches are the grid. Every patch has coordinates px and py, plus the fields declared in patches:. Patch models use neighborhood reporters such as neighbors4 and neighbors8 when local adjacency is the rule surface.
Pets are movable agents grouped into named breeds. A breed can own fields, move across patches, read its current patch with patch, and issue commands such as forward(1) or turn(45). Setup runs once, step phases run every tick, and staged steps let updates read the old phase state before committing together.
moving agent lifecycle
pets: ants: state: searching | carrying = searching released: boolean = false setup: create ants population ants: set-position(0, 0) heading := random(360) step: ants: where searching: where (patch.state = food): state := carrying turn(180) forward(1)Files
One model, four files
Every complete model is a four-file bundle. source.pet contains executable rules. definition.petmeta names and explains the model, styles.petstyle controls its presentation, and presets.petpreset stores named parameter configurations. All three companion files are standard YAML.
Keep fields next to the rules that use them, visual choices in the style file, and repeatable starting values in presets rather than in the rules. The compiler and the VS Code extension check references across all four files.
model bundle
my-model/ source.pet definition.petmeta styles.petstyle presets.petpresetLearning path
A suggested route through the examples
The model catalog is not ordered, but the examples build on each other. This progression introduces one new language surface per step; each language chapter also ends with the models that exercise it.
If you prefer a structured course with narrated lessons, saved progress, worked models, and end-of-unit checkpoints, start Agent-Based Modeling with MathPets.
Step 1
Life
Patch-only rules and the staged step: every cell reads the same snapshot before any cell commits.
Open model →Step 2
Fire
Adds the full model loop — params as controls, monitors as readouts, and a stop condition around a patch rule.
Open model →Step 3
Flocking
First moving agents: a breed with headings, radius queries, and steering — no patch state at all.
Open model →Step 4
Ants
Pets and patches together: gradient sensing, chemical trails, and observer-level diffusion.
Open model →Step 5
Wolf Sheep Predation
Population dynamics from lifecycle commands: hatch, die, kill, and per-pet energy budgets.
Open model →Step 6
Virus on a Network
Links as first-class agents: build a contact network in setup, then spread state across it tick by tick.
Open model →