▶ Live demo: run this tutorial — built from src/05_state_breeds.ts. Distilled from samples/agent_breeds.ts.
AgentScript turtles carry arbitrary properties and come in breeds (named sub-types with their own behavior). Taos Engine agents are fixed-layout GPU records, so per-agent state rides in a spare channel —
color.a— and a breed is just a named value of it that the step branches on.
Per-agent state in color.a#
An agent is a 64-byte record: position, velocity, color (rgba), size, rotation,
life. Most models park a small state value in color.a (the alpha channel).
Under additive arrow rendering the alpha doesn't affect brightness (the
fragment outputs color.rgb * emit), so it's a free per-agent scalar — set the
visible color in color.rgb separately.
Read it with agent.breed() (= color.a), write it with action.set('alpha', v).
Two-state models (e.g. an ant that's searching vs. carrying) use a threshold like
expr.gt(expr.attribute('alpha'), 0.7).
Breeds: N named types#
Store a breed id (0, 1, 2, …) in color.a and branch per breed:
| Verb | Meaning |
|---|---|
agent.breed() | this agent's breed id |
agent.isBreed(k) | |color.a − k| < 0.5 |
agent.setBreed(k) | write the breed id (use in spawn.actions) |
Assign breeds on spawn and give each a color:
const breedId = expr.floor(expr.random({ mode: 'perSpawn', min: 0, max: 2.999, seed: 7 }));
spawn: {
actions: [
action.set('alpha', breedId), // breed id → color.a
action.if_(agent.isBreed(0), [action.set('rgb', expr.vec3(0.25, 1.0, 0.4))]),
action.if_(agent.isBreed(1), [action.set('rgb', expr.vec3(1.0, 0.55, 0.12))]),
action.if_(agent.isBreed(2), [action.set('rgb', expr.vec3(0.3, 0.75, 1.0))]),
action.set('rotation', expr.random({ mode: 'perSpawn', min: 0, max: TWO_PI, seed: 3 })),
],
},Then give each breed its own behavior in the step:
step: [
action.if_(agent.isBreed(0), [ /* green: orbit the left home */ ]),
action.if_(agent.isBreed(1), [ /* orange: swarm the center */ ]),
action.if_(agent.isBreed(2), [ /* cyan: orbit the right home */ ]),
],The demo gives the three breeds different homes and motions so they read as three separate, distinctly-colored groups — the whole point of breeds.
Tip — keep breeds visually separate. Because rendering is additive, overlapping breeds blend toward white. If you want to see the breeds, give them distinct places or roles (as here), or they'll wash together.
Next#
- Tutorial 6 — Births & Deaths: growing and shrinking the population at runtime.