Documentation

Intro

MathPets is a browser-native simulation studio for writing, running, styling, and inspecting agent-based models built from MathPets source.

Scope

What MathPets is for

MathPets is aimed at models where simple local rules produce visible system-level behavior: cellular automata, ecological simulations, diffusion systems, foraging, flocking, and related exploratory models. The authored source should stay close to the way a modeler explains the system: what the world contains, what each agent remembers, and which local transitions move the model forward.

MathPets is the user-facing model language. The compiler turns that source into browser runtime code, but the model file remains the readable contract: declarations first, setup once, then one or more step phases that repeat each 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 := active

Authoring

Web IDE, CLI, and VS Code

The web IDE is the main Studio surface. It edits MathPets source, shows source feedback, runs models in the browser, keeps drafts in local storage, and exposes controls for parameters, presets, style rules, monitors, and the live world view.

The command line stays workspace-oriented: start the Studio, run checks, build the app, and keep the example model files honest. The VS Code plugin in packages/ide supports .pet files with syntax highlighting, completions, a side-panel preview, and an output panel.

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 := state

Authoring

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 just an expression with a name and a type; the Studio recomputes it on 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.

Try the controls on the right. Each widget is the same React component the Studio inspector uses, driven by real state. The number readout and the sparkline below it react to the same param changes the studio would react to.

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 alive

controls

monitors

living-cells726
living-cells history

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 := burning
patches:  states:    burning:      color: "#f97316"    burned:      color: "#29180f"      transition: 3

Agents

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.

MathPets 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.

The important habit is locality: keep source fields next to the logic that consumes them, keep visual transitions in styles, and use presets for repeatable starting values instead of baking one run into the rules. The compiler and VS Code extension validate references across the whole bundle.

model bundle

my-model/  source.pet  definition.petmeta  styles.petstyle  presets.petpreset

Learning 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.