The Trail
Concept
I wanted to build something that felt genuinely alive, not just shapes moving around a screen, but a system with real logic behind it. I kept coming back to one question: how do ants form those perfect lines without anyone telling them where to go?
The answer is surprisingly simple. One scout finds a path and leaves a chemical trail called a pheromone. Workers smell it and follow. The more ants walk the same path, the stronger the smell, the more ants follow. A highway emerges from nothing, no leader, no plan, just chemistry.
That became the concept. You are the scout. Move your mouse, and the colony follows the exact path you traced. Stop moving, and the scout breaks away to investigate the environment on its own, sniffing nearby rocks while the workers wait in place.
References and inspiration:
- The Nature of Code — Autonomous Agents, Daniel Shiffman — the steering force formula everything is built on
- Ant Foraging and Pheromone Trails — PMC Research — real biology behind how trails form and evaporate
- Trail Pheromones — Wikipedia — how pheromones work chemically and why they fade
- Tandem Running in Ants — Wikipedia — the specific behavior where one ant physically leads another
Code I’m Proud Of
The moment that made everything click was the pebble investigation system. When the mouse stops, the scout doesn’t just freeze, it actively searches for the nearest rock within 120 pixels and slowly approaches it, like an ant sniffing an obstacle. When it gets close enough it clears that target and finds the next one.
// ── LEADER
if (mouseStill) {
// slow crawl speed while exploring
leader.maxSpeed = 0.5;
// clear pebble target once scout is close enough
if (targetPebble) {
let d = dist(leader.pos.x, leader.pos.y, targetPebble.x, targetPebble.y);
if (d < SEEK_STOP) targetPebble = null;
}
// find a new pebble if not already investigating one
if (!targetPebble) targetPebble = findNearestPebble();
// arrive at pebble slowly, or wander if none nearby
if (targetPebble) leader.arrive(createVector(targetPebble.x, targetPebble.y));
else leader.wander();
What I love about this is that it uses the same arrive() behavior the whole project is built on, just at a slower speed. One behavior, three different contexts: following the mouse, following history points, investigating a rock. That reuse felt elegant.
Embedded Sketch
Milestones and Process
Phase 1 — Getting the chain to work
Started with two plain circles. One follows the mouse using arrive. Every frame, its position gets saved into a history array. The second circle targets history[40], where the first was 40 frames ago. That delay creates the following effect. The main challenge was stopping them from overlapping when the mouse stopped, fixed by only recording history when the leader actually moved.
Phase 2 — Scaling to a colony
Scaled from one follower to seven using a simple loop. Each ant targets a different point further back in history. Added real ant bodies, the sandy background, and separation logic between every pair of ants so they never overlap.
Phase 3 — The Final Sketch
Added the fading pheromone trail, pebble investigation when the mouse stops, workers freezing while the scout explores, and a custom glowing cursor. The final version can be found embedded above.
Reflection and Future Ideas
The biggest surprise was how little code produces this behavior. A five-line loop creates the chain. One Perlin noise value creates the wander. Simple rules, complex result, exactly what the ant research described.
Future ideas:
- Add a real food source that the scout can find and bring workers to complete the full foraging loop
- Two competing colonies with different trail colors racing to the same food
- Make the trail actually fade so workers that fall too far behind lose the scent and wander off alone