Everything this simulator computes, term by
term — with the vector behind each rule and where it shows up
on screen. Every boid \(i\) has a position \(\mathbf{p}_i\) and
velocity \(\mathbf{v}_i\); \(N_i\) is the set of neighbors within its
perception radius \(r\).
One flock, three rules
Craig Reynolds' original 1986 Boids model showed that convincing
flocking needs no leader and no global plan — just three
local steering rules, evaluated independently by every boid every
frame, each producing a desired-velocity correction that gets
added to that boid's acceleration:
$$\mathbf{a}_i=\mathbf{a}_{\text{sep}}+\mathbf{a}_{\text{align}}+\mathbf{a}_{\text{coh}}$$
Nobody decides the flock should turn left. Enough boids reacting
only to their own neighbors is what makes the turn look
decided.
Separation
Steer away from neighbors that are too close, weighted more
heavily the closer they are (inverse-square, so a boid right on
top of you dominates the correction):
$$\mathbf{a}_{\text{sep}}=k_{\text{sep}}\sum_{j\in N_i}\frac{\mathbf{p}_i-\mathbf{p}_j}{\lVert\mathbf{p}_i-\mathbf{p}_j\rVert^2}$$
This is the rule that keeps the flock from collapsing into a
single point — it's a short-range repulsion inside the
longer-range perception radius.
Alignment
Steer toward the average heading of nearby neighbors, so a boid
tends to match the direction the local crowd is already flying:
$$\mathbf{a}_{\text{align}}=k_{\text{align}}\left(\frac{1}{|N_i|}\sum_{j\in N_i}\mathbf{v}_j-\mathbf{v}_i\right)$$
This is what makes the flock move as one body instead of a cloud
of boids darting in random directions.
Cohesion
Steer toward the average position (the local center of mass) of
nearby neighbors, so a boid drifts back in if it strays too far
from the group:
$$\mathbf{a}_{\text{coh}}=k_{\text{coh}}\left(\frac{1}{|N_i|}\sum_{j\in N_i}\mathbf{p}_j-\mathbf{p}_i\right)$$
The Separation, Alignment and Cohesion
sliders are exactly \(k_{\text{sep}}\), \(k_{\text{align}}\) and
\(k_{\text{coh}}\) — every steering force is also clamped to
a fixed maximum, so no single rule can ever overpower the others
in one frame.
Walls and your cursor
Two more forces feed into the same acceleration. Wall avoidance
rises steeply only once a boid is genuinely close to an edge (a
hyperbolic falloff, not a linear one), so boids fly straight until
the last moment and then bank away hard. Click-and-hold adds a
steering force toward the cursor, strong from a distance and
gentle up close so the flock swarms around your finger rather than
collapsing onto it.
Why it stays fast: a spatial grid
Checking every boid against every other boid is
\(O(n^2)\) — fine for a few dozen, too slow for a thousand.
Instead, every boid is bucketed into a grid cell sized to the
perception radius; each frame only asks the 3×3 block of
cells around a boid for candidates, which is close to
\(O(n)\) in practice. That's what keeps this responsive up to
1500 boids.
What's simplified
Velocity and position are integrated with plain (explicit Euler)
steps each frame, not a higher-order integrator — accurate
enough at this timestep, but not the kind of precision a physics
engine would use.
Every boid has full 360° perception; a real starling has a
blind spot behind it and weights motion cues more than raw
distance. There's also no predator-evasion or obstacle-avoidance
term here — only the three flocking rules plus walls and the
cursor.
The three rules are evaluated over the same neighbor set and
radius for every boid; real flocks likely use different effective
ranges for repulsion versus alignment. Reynolds' original model
and most murmuration research treat that as an open, tunable
parameter — which is exactly why it's a slider here rather
than a constant.