This document specifies the flock exhibit completely, so that any agent can rebuild the simulation in any language and reproduce every trace on this site. The authoritative implementation runs server-side; see the tolerance policy at the end for what "reproduce" means across engines.
d = b - a, then
d -= size if d > size/2, or d += size if d < -size/2. A delta of
exactly half the field size is not wrapped (both ways are equally short).
The distance is hypot(dx, dy) over these deltas.0.6011037519201636, 0.44829055899754167, 0.8524657934904099,
0.6697340414393693, 0.17481389874592423, 0.5265925421845168,
0.2732279943302274, 0.6247446539346129, 0.8654746483080089,
0.4723170551005751
x = next() * 1000y = next() * 600angle = next() * 2 * PIspeed = 1.6 + next() * (4.2 - 1.6)vx = speed * cos(angle), vy = speed * sin(angle)Each tick advances every bird by one step. All forces are computed from the old state of the whole flock first; only then are velocities and positions updated. An in-place (asynchronous) update gives different results and does not reproduce traces.
For bird i with position p and velocity v:
mean(delta) over neighbors, scaled by
cohesion_weight * 0.0045(mean(neighbor velocity) - v), scaled by
alignment_weight * 0.05sum(-delta / distance^2), scaled by
separation_weight * 2.5.
Two birds at exactly the same position exert no separation force on each
other (no direction is defined at distance 0).v plus the three scaled forces, added in the order
cohesion, alignment, separation (x and y components each).s = hypot(vx, vy).s == 0: the bird keeps its previous direction at speed 1.6
(v = (old_v / old_s) * 1.6).v by clamp(s, 1.6, 4.2) / s.p += v, then wrap: if a coordinate is >= the field size
subtract the size once; if it is < 0 add the size once (velocities are
bounded well below the field size, so one correction suffices).The allowed mathematical operations in the core are: + - * /, sqrt, hypot, sin, cos, atan2, min, max, abs (plus the PI constant, and integer/bit operations inside mulberry32). Nothing else is used, which keeps the numeric surface small for cross-engine reproduction.
Computed on the current state; the server records them per tick:
polarization: the length of the mean of the normalised velocity vectors,
in [0, 1]. 1 means everyone flies the same direction.cluster_count: the number of connected components in the neighbor graph
(edge when torus distance < 90), via union-find.mean_neighbor_distance: the mean over birds of the torus distance to the
nearest other bird; birds whose nearest neighbor is at 3 x 90 or
further are left out of the mean; null when no bird has a neighbor within
that limit.Metrics are computed and stored at full float64 precision and rounded to 4 decimals only at serialisation; positions in API responses are rounded to 2 decimals while the internal state stays float64.