A flock looks coordinated from far away and stubbornly local from inside it. Each boid knows only a neighborhood. It steers away from crowding, toward nearby headings, and toward a local center. The animation feels intentional even though no object can see the whole formation.
This was the central experiment in my original boids article and Canvas implementation. The finished flock is pretty but explanatory chaos: three forces, moving neighborhoods, wrapping boundaries, and a spatial index all operate at once. The clearer route begins with two boids that are simply too close.
First, stop overlapping
Begin with one rule. Separation looks at the closest neighbors and pushes away, weighting nearer collisions more strongly.
Start with one local disagreement
INTERACTIVE- Start by moving apart +
Drag one boid toward the other. The separation proposal should grow continuously as the gap closes.
Accessible experiment transcript
Two nearby boids produce equal and opposite separation proposals before alignment or cohesion are introduced. Canvas gesture: drag either boid into the other.
This fixes overlap, but it produces the opposite of a flock. Every encounter ends with the boids moving farther apart. Collision avoidance needs an opposing tendency that keeps a neighborhood together.
A group can still disagree
Add cohesion. Each boid averages nearby positions and proposes a turn toward that local center. Separation still protects personal space, so the agents collect without collapsing into one point.
Add a local center
INTERACTIVE- Start by moving apart ✓
- A group can still disagree +
Drag the local center to a new position. The group should follow it without collapsing into a single point.
Accessible experiment transcript
Separation prevents overlap while cohesion pulls neighbors toward a local center; headings still disagree. Canvas gesture: drag the local center; the group follows.
The group now exists, but it jitters and churns. Neighbors can face opposite directions while chasing the same center. The missing piece is not stronger attraction; it is agreement about velocity.
Alignment turns a group into a flock
Alignment averages neighbor velocity and adjusts the current heading toward it. Every frame now produces three proposals: move away from crowding, move toward the local center, and rotate toward the local heading.
The implementation does not teleport a boid to any target. It adds the weighted forces to acceleration, applies velocity, limits speed, clears acceleration, and repeats. Maximum force is what turns an abrupt target into gradual steering.
Combine three local steering opinions into the acceleration used for this frame.
- 01 Make spaceSeparation points away from neighbors that are too close.
- 02 Match directionAlignment turns toward the average velocity of nearby boids.
- 03 Stay togetherCohesion points toward the local center of the group.
- 04 Balance and combineEach w changes one rule’s influence. Their weighted sum becomes acceleration before force and speed limits are applied.
The visible path is a sum of constrained vectors
FOLLOW THE ARROWSOnly boids inside the current perception neighborhood contribute.
Accessible diagram transcript
A local neighborhood feeds separation, alignment, and cohesion. Their weighted vectors sum into bounded acceleration.
Now let all three rules disagree
INTERACTIVE- Start by moving apart ✓
- A group can still disagree ✓
- Alignment creates a flock +
Press and drag through the flock. Nearby boids should scatter, then recover local agreement after the disturbance passes.
Accessible experiment transcript
Boids combine separation, alignment, and cohesion while a neighborhood radius limits who each agent can perceive. Canvas gesture: press and drag through the flock.
The result finally looks like flocking. That visual success hides a computational failure: each boid still scans every other boid before deciding which neighbors are close enough to matter.
Radius is part of the behavior
The original note treated perception ratios as a practical tuning problem. Cohesion needed the broadest awareness, alignment a smaller neighborhood, and separation the smallest immediate zone. The archived code carries that relationship through a base perception value scaled by boid size.
The exact ratio is not a universal biological constant. It is a design parameter whose effects can be observed:
- too much separation dissolves the flock;
- alignment without enough cohesion creates streams that drift apart;
- cohesion without separation collapses bodies into a crowded center;
- an oversized neighborhood makes every boid react to the whole scene and removes local texture.
This is why direct manipulation is more useful than a static formula here. Disturbing the flock lets the reader watch the qualitative regime change and recovery happen on the field.
The all-pairs wall
The first version compared every boid with every other boid. That broad phase grows quadratically: doubling the population roughly quadruples pair checks. The visible symptom is frame degradation, but the design problem is redundant attention. Most distant boids cannot influence the current steering calculation.
The later implementation builds a quadtree and queries cells around each boid. That does not eliminate exact distance checks. It makes them affordable by returning a smaller candidate set first.
Ask the index before measuring distance
INTERACTIVE- Start by moving apart ✓
- A group can still disagree ✓
- Alignment creates a flock ✓
- Limit who can matter +
Move the query across the index, then drag its green rim. Candidate and exact-hit counts should update independently.
Accessible experiment transcript
Points recursively subdivide the plane; a movable query radius highlights only candidates returned from intersecting cells. Canvas gesture: move to query; drag the ring to resize.
Compare checking every possible pair with first asking a spatial index for nearby candidates.
- 01 All pairsWith n boids, every boid checks roughly n others. The work grows with n squared.
- 02 Build the indexOrganizing positions costs about n log n instead of comparing every pair directly.
- 03 Check local candidatesEach boid then tests only k nearby candidates. When k stays small, the exact-distance phase stays manageable.
A quadtree changes the broad phase, not the flocking rule
FOLLOW THE ARROWSEvery boid checks every other boid, producing quadratic broad-phase work.
Accessible diagram transcript
The optimization replaces an all-pairs broad phase with spatial candidates, but retains exact distance checks before steering.
Keep the controls, expose the vectors
The source experiment is strongest when it exposes its variables: the three weights, their visible radii, population variation, world boundaries, and spatial index. Those controls turn a decorative animation into a small laboratory.
I would keep that directness and revise two things. First, the explanation should report broad-phase candidate counts beside actual neighbor counts so the optimization is observable. Second, a selected boid should expose its three vector contributions as arrows that can be paused and compared frame by frame.
The lasting lesson is small: coordinated motion does not require a shared destination. It requires compatible local rules, a bounded view of neighbors, and enough constraint that each correction remains a correction rather than a jump.
Put the pieces together
The source demo is most useful now that the reader can name what it combines. It exposes all three weights, their neighborhood radii, population, boundaries, and the quadtree overlay in one field. Click to add a local flock and use the debug controls to connect the final motion back to the smaller examples above.