Loading
A beautiful pattern is a discovery prompt, not a result. The project needed measurements that could disagree with my eyes.
Launch the simulation
0505 / 09For a long time, I tuned Particle Life by watching it.
Change a force value. Wait. Decide whether the motion felt richer. Change friction. Wait again. Keep the version that looked more alive.
Visual judgment is excellent for noticing that something unexpected has happened. It is terrible at telling you why. It is sensitive to bloom, color, recent expectations, and the one seed that happened to produce a dramatic shape. It encourages a simulation to become a performance optimized for its author.
The project needed measurements capable of disagreeing with my eyes.
The shipped metric fixes radius at 40 px and minimum membership at 15. This sensitivity view uses the same same-type, toroidal, transitive union-find rule.
The live interface exposes six values, each answering a different question:
| Metric | Question |
|---|---|
| Particle count | How many bodies are active? |
| FPS | How often is the current state rendered? |
| Cluster count | How many substantial same-type groups exist? |
| Stability | What fraction of particles is moving below 5 px/s? |
| Average speed | How much motion exists on average? |
| Simulated time | How much physics was actually computed? |
FPS is a performance measure, not a physics measure. Simulated time counts fixed steps, not wall-clock time. Keeping those distinctions visible prevents a slow machine from appearing to produce slow physics.
A cluster is defined operationally, not visually: same-type particles connected through neighbor links shorter than forty pixels, with at least fifteen members.
The implementation uses union-find. Each particle begins as its own set. Nearby same-type pairs are joined. After processing, roots whose set size is at least fifteen count as clusters.
This definition allows indirect structure. Particle A need not be within forty pixels of particle C if both connect through B. It also ignores tiny coincidences that would make the counter flicker.
Clustering allocates temporary arrays and performs more work than speed measurement, so it runs every thirty analysis frames rather than every frame. The displayed number is slightly sampled; the simulation state is not.
Average speed is the mean magnitude of all particle velocities, smoothed over a sixty-frame ring. Motion diversity is the standard deviation of per-particle speeds, used in the tuning harness and Discover search.
Two worlds can share average speed while behaving differently. Uniform drift gives low diversity. A world containing settled islands and fast pursuers gives higher diversity.
Stability is intentionally simpler: the fraction of particles currently below 5 px/s. A value near one means most particles are settled. It does not mean the structure is robust, alive, or permanent.
Measured after 15 simulated seconds with seed 42. Cells is intentionally slow; Chaos is intentionally unclustered.
The dashboard shows why success must remain preset-specific. With seed 42 after fifteen simulated seconds, Galaxy forms eight clusters at 14.7 px/s. Cells forms eleven clusters at only 1.7 px/s. Chaos forms one counted cluster but moves at 19.6 px/s.
Calling every slow world “dead” would misclassify Cells. Calling every fast world “alive” would reward noise.
The original specification suggested forceScale = 40 and R = 80. Under friction of 0.85 per fixed step, those values put every preset below the intended 5 px/s lower motion bound.
The problem was not a bad matrix. Friction limited terminal speed so strongly that the requested band was physically unreachable. A measured grid search across the permitted values found the operating point used now:
forceScale = 80
R = 100 px
β = 0.3The acceptance test runs every preset for fifteen simulated seconds across seeds 42 and 1337. Structured presets need at least three clusters and must stay below 60 px/s. Chaos is exempt from clusters because structurelessness is its purpose. Custom is an empty canvas and exempt from behavioral acceptance.
Cells required one honest correction. It consistently formed ten or eleven clusters around 2 px/s. The original lower speed limit called that a failure even though settled tissue was the preset's intended result. The lower bound was removed for Cells once, documented in code, while the explosion-preventing upper bound remained.
Changing a threshold after seeing data can be abuse. Here the alternative would have been worse: keeping a metric that contradicted the declared behavior, or secretly tuning Cells to move when it should settle. The recalibration is acceptable only because the reason, scope, and one-time nature are explicit.
Large worlds are visually persuasive but difficult to diagnose. The strongest force tests use two particles.
An attractive pair must settle near βR, never collapse to zero. A repulsive pair must separate toward R and stop accelerating beyond it. At the tuned defaults, a dedicated measurement test verifies the 30 px equilibrium.
Other tests protect experimental invariants:
±0.9 matrices remain finite and speed-clamped;The repository currently runs 89 tests across 15 files. The number matters less than the boundaries they defend.
Cluster count cannot distinguish a membrane from a blob. Speed diversity cannot distinguish a food chain from random collisions. Stability cannot tell whether a structure would survive perturbation. None of them measures reproduction, adaptation, semantic novelty, or open-ended evolution.
The rule, code path, and serialized state.
Pair spacing, speed, clusters, stability, and test outcomes.
Whether visual aliveness implies novelty, agency, or life.
A scientific interface should make uncertainty visible at the same level as its strongest result.
These are low-level structural metrics. They make tuning reproducible and reject obvious collapse, explosion, or stasis. They do not settle the question that motivated the project.
That limitation becomes central in Part 6. The Discover button searches automatically, but every search is only as intelligent as the score it is asked to maximize.
More to read
The renderer is not decoration. It makes distance, motion, relationships, and failure legible without changing the physics underneath.
Random rules are easy. Finding random rules that remain structured and in motion requires a definition of interesting—and exposes its limits.
Fixed time, deterministic seeds, a toroidal world, and the spatial hash that lets two thousand particles remain an experiment.