In response to the request here: https://mathematica.stackexchange.com/q/312395​
Extends Simon Woods' Boids model with 3D spatial dynamics, velocity-color mapping (Rainbow gradients), inertia-driven coordination (velocity averaging for flock coherence), and universal friend/foe hierarchies enabling emergent leader-follower behavior.
See other parts to this post here:
​Boids 2: spherical projection with dynamic viewpoint tracking​
​Boids 3: periodic domain eliminates edge effects via rectangular lattice projections

Simon Woods’ original code

This is nice and efficient and illustrates how changing a value within a Dynamic creates a loop implicitly.
I’ve renamed the variables to make it easier for readers to see what is going on.
In[]:=
numberBoids=1000;​​randomBoid:=RandomInteger[{1,numberBoids}];​​boidForceTerm:=(#/(.01+Sqrt[#.#]))&/@(boidLocations[[#]]-boidLocations)&;​​switchFriendsEnemies:=With[{rb=randomBoid},friend[[rb]]=randomBoid;enemy[[rb]]=randomBoid];​​boidLocations=RandomReal[{-1,1},{numberBoids,2}];​​{friend,enemy}=RandomInteger[{1,numberBoids},{2,numberBoids}];
In[]:=
Graphics[​​{PointSize[0.007],​​Dynamic[If[randomBoid<100,switchFriendsEnemies];​​Point[​​boidLocations=0.995boidLocations+0.02boidForceTerm[friend]-0.01boidForceTerm[enemy]]]},​​PlotRange->2​​]
Out[]=

Original code in three dimensions

It just a simple change of the dimensions of the initial locations:
boidLocations → RandomReal[{-1, 1}, {numberBoids, 3}]
and
Graphics → Graphics3D
In[]:=
numberBoids=1000;​​randomBoid:=RandomInteger[{1,numberBoids}];​​boidForceTerm:=(#/(.01+Sqrt[#.#]))&/@(boidLocations[[#]]-boidLocations)&;​​switchFriendsEnemies:=With[{rb=randomBoid},friend[[rb]]=randomBoid;enemy[[rb]]=randomBoid];​​boidLocations=RandomReal[{-1,1},{numberBoids,3}];​​{friend,enemy}=RandomInteger[{1,numberBoids},{2,numberBoids}];
In[]:=
Graphics3D[​​{PointSize[0.007],​​Dynamic[If[randomBoid<100,switchFriendsEnemies];​​Point[​​boidLocations=0.995boidLocations+0.02boidForceTerm[friend]-0.01boidForceTerm[enemy]]]},​​PlotRange->2​​]
Out[]=

Some additions color the boids and make videos

A function to draw the boids with colors corresponding to their velocity
In[]:=
boxGraphic=
;
Options[drawBoid]={"Velocity Range"->{0.001,0.01},ImageSize->500,PlotRange->2};drawBoid[position_,velocity_,OptionsPattern[]]:=​​With{colors=ColorData["Rainbow"][Clip[Rescale[#,OptionValue["Velocity Range"]]]]&/@(Norm/@velocity)},​​Graphics3D​​{​​boxGraphic,​​MapThread[​​{#1,Sphere[#2,.015]}&,{colors,position}]},​​
​​
Initialize in a single step and introduce a velocity (to be used later)
In[]:=
Options[initialize]={"Initial Locations"->"Square"};​​initialize[n_,OptionsPattern[]]:=​​Module[{},​​numberBoids=n;​​boidLocations=​​Which[​​OptionValue["Initial Locations"]==="Ball",​​RandomPoint[Ball[],n],​​OptionValue["Initial Locations"]==="Sphere",​​RandomPoint[Sphere[],n],​​True,​​RandomReal[{-1,1},{n,3}]​​];​​randomBoid:=RandomInteger[{1,n}];​​{friend,enemy}=RandomInteger[{1,n},{2,n}];​​boidVelocity=ConstantArray[{0,0,0},n]​​]
In[]:=
$HistoryLength=1;(*videosarelarge,doingsomememorymanagement*)
Adding colors associated with velocity and making a video from the frames
In[]:=
initialize[1000];​​Dynamic[​​If[randomBoid<100,switchFriendsEnemies];​​drawBoid[boidLocations=0.995boidLocations+0.02boidForceTerm[friend]-0.01boidForceTerm[enemy],boidVelocity,PlotRange->1]​​]
Out[]=
Notice that the use of the function drawBoid slows down the code compared to Woods’. This is probably from passing variables to the function.
To make animations, I decided to use a loop with Reap/Sow.
Using export is faster than FrameListVideo
You can get the mp4 video here:

Variations on boids

Making an inertia-like term for the boids motion and using colors to indicate velocity

inertia is simulated by averaging the current and previous velocities :
vMean = 0.5 (vLast + boidVelocity)
The weighting of the averaging gives different effects
To my eye, the flocks seem to flow in a more coordinated fashion. When the flock stretches out, it seems to be longer and move in a more coordinated fashion.
You can get the mp4 video here:

Adding everyone’s friend

One boid is identified as everyone’s friend.
Also, repositioning to put mean position at center of graphic
more frames... about 5 minutes to make the video
The flock motion has more correlation.
You can get the mp4 video here:

Some variations on this would be to select several “universal friends”

This is a trivial extension of the code. Create n lists of universal friends and then for the motion associated with them:
Total[boidForceTerm /@ everyonesFriend]
You can get the mp4 video here:

CITE THIS NOTEBOOK

Boids 1: 3D dynamics, velocity-color mapping, and inertia-driven coordination​
by W. Craig Carter​
Wolfram Community, STAFF PICKS, June 24, 2025
​https://community.wolfram.com/groups/-/m/t/3485008