▶ Live demo: run this tutorial — built from src/07_links.ts. Distilled from samples/agent_links.ts.
Links connect agents into a graph — AgentScript's third primitive after turtles and patches. Taos Engine stores a fixed number of link slots per agent, uploaded once as a topology, and the built-in
link_springsbehavior force-directs them: linked agents pull toward a rest length while everything repels, so a tangled community graph untangles itself.
Declaring links and the behavior#
{
population: 1500,
movement: 'velocity',
neighbors: { /* … */ }, // link_springs uses the hash for repulsion
links: { linksPerAgent: 8 }, // 8 slots per node
behaviors: [{
type: 'link_springs',
restLength: 5, stiffness: 6, // Hooke spring toward each linked node
repulsion: 60, repelRadius: 12, damping: 0.85,
maxSpeed: 45, worldHalf: HALF, edgeMargin: 8, edgeForce: 90,
}],
}Uploading the topology#
The graph itself (who links to whom) is host data you upload with
app.setLinks(Int32Array) from onReady — population × linksPerAgent i32 slots,
each a linked agent index or -1 for empty:
onReady: (app) => {
app.setLinks(buildGraph(POP)); // community graph
},buildGraph builds six
densely-linked communities plus a few cross-community bridges. A rebuild gives a
fresh buffer, so re-upload after it: app.rebuild(() => app.setLinks(...)).
Drawing the edges#
AgentLinkFeature draws one ground-plane ribbon per undirected edge. It's an HDR
overlay, so add it through extraFeatures (which splices it in after the agents but
before tonemap); its source reads the live particle + link buffers off
app.particles.pass:
extraFeatures: (app) => [
new AgentLinkFeature({
source: () => ({
particleBuffer: app.particles.pass?.particleBuffer ?? null,
linkBuffer: app.particles.pass?.linkBuffer ?? null,
linksPerAgent: app.particles.pass?.linksPerAgent ?? 0,
count: app.particles.pass?.maxParticles ?? 0,
}),
color: [0.35, 0.55, 1.0], intensity: 0.5, width: 0.25,
}),
],Watch the scattered nodes pull into six clusters joined by bridges — a classic force-directed layout, computed entirely on the GPU.
Constraint: linksPerAgent is fixed, the topology is host-uploaded, and there's
no on-GPU add/break of links or per-link iteration in the step yet (those need a
mutable adjacency structure that doesn't fit the fixed-width model). The
link_springs behavior + edge rendering cover the common force-directed case.
Next#
- Tutorial 8 — Measurement & Plots: reading model state back to the CPU.