Taos Engine · Agent Tutorials

Agent Tutorials · Step 3

Patches & Stigmergy

▶ Live demo: run this tutorial — built from src/03_patches.ts. Distilled from samples/agent_slime.ts.

Patches are AgentScript's grid — a field of numbers that diffuses and evaporates each tick. Agents read it (sense) and write it (deposit), coordinating only through the trail they leave behind. That's stigmergy, and the canonical example is the slime mold (Physarum): agents steer up the pheromone gradient they themselves lay, and self-organize into a network.

Declaring a patch grid#

Add a patches block — a square grid mapped onto your world rectangle, holding one or more scalar fields:

TypeScript
patches: {
  resolution: 512,                                  // a 512×512 grid
  worldMin: [-HALF, -HALF], worldSize: [WORLD, WORLD],
  fields: [{ name: 'pheromone', diffuse: 0.12, evaporate: 0.94 }],
},

Per field: diffuse (in [0,1]) is the fraction each cell blends toward its 4-neighbor average per step — AgentScript's patches.diffuse. evaporate (in [0,1]) is the multiplicative decay (1 = none, 0.94 ≈ fades over ~16 steps).

Sensing and depositing#

Inside the step, agents read and write the field by index:

TypeScript
step: [
  agent.turn(agent.steer(0, { dist: 9, angle: 0.5, turn: 0.5 })),  // sniff & steer
  agent.turn(agent.randomTurn(0.1)),                               // wander → branching
  agent.moveForward(18),
  agent.deposit(0, 5),                                             // lay pheromone here
],

Deposits are fixed-point under the hood (depositScale, default 1024); for a static field that agents only edit (no spreading), use diffuse: 0, evaporate: 1.

Visualizing the field#

A field is invisible on its own. Add a patchViews entry to the runAgentModel call and the harness draws it as an additive colormapped ground quad — it wires the live buffer source and world rectangle for you:

TypeScript
runAgentModel({
  params: {},
  model: slimeMold,
  camera: { /* … */ },
  patchViews: [{ field: 0, intensity: 0.05 }],
});

PatchViewOptions also takes tint, flat (a solid color for discrete state fields rather than the ramp), opaque (draw under the agents), and a two-field compare mode. To tweak a view live from a control, app.patchView(0) returns it.

importDataSet / exportDataSet#

To preload a field from a CPU raster (a heightmap, a cost map — AgentScript's importDataSet), call app.seedPatch(field, Float32Array) from onReady (row-major [z*res + x]). To read one back for measurement (exportDataSet), await app.readPatch(field) — see tutorial 8.

Next#