DAINER.AI · build notes · № 16

a smaller bank, syncing live · synchrony 0.15

How the river was computed.

Kelip-Kelip is not a video of fireflies. Every flash on the home page is a small clock, solving the same problem the real insects on the Selangor river solve each night — how a crowd of strangers finds one beat with no one in charge. These are the notes on how it was built, and what three passes of a hostile eye had to fix.

01The brief it received

One brief, handed to a single builder. No wireframe — a place and a premise, and the fiction answered the rest.

NameKELIP-KELIP · the firefly river, Kuala Selangor
ConceptTen thousand fireflies on a dark river learning to blink in sync — a real phenomenon, computed live. Your lamp is the thing that breaks it.
Palette#060b10#d8f25a#1e4a44#c7cdd4
TypeSpectral (display) + Assistant (text)
SignatureSynchronised swarm agents — fireflies as coupled oscillators that drift toward synchrony (Kuramoto-style); a sync meter shows the river finding rhythm.
InteractionsCursor = boat lamp (nearby flies scatter and desync) · stillness restores the rhythm · a patience easter egg at full sync.
Mood · voiceBioluminescent, hushed, patient · the boatman who asks for quiet
Tagline"Ten thousand fireflies learn to blink together — try not to scare them."

02The signature technique

Each firefly carries a phase — a clock hand going round. Left alone it runs at its own slightly-wrong speed. But every hand is also pulled toward the average of all the others: the more of the bank that already agrees, the harder the pull to join them. That single rule, written down by Yoshiki Kuramoto in 1975, is the whole engine.

The order parameter is how the model measures agreement — average every clock hand as a little arrow on a circle, and the length of the sum is a number from nought (chaos) to one (perfect unison). That number is what the corner meter reads, live, every frame. Coupling ramps in slowly, so the river arrives scattered and gathers over about twenty-six seconds instead of starting already solved — and your lamp cuts the coupling to zero for the flies nearest it, tearing a hole in the rhythm you have to wait to heal.

index.html — the coupling loopreal excerpt
// the mean field — how aligned the whole river is, 0 → 1
let sc=0, ss=0;
for (let i=0; i<N; i++){ sc+=Math.cos(th[i]); ss+=Math.sin(th[i]); }
sc/=N; ss/=N;
order = Math.hypot(sc, ss);      // the synchrony meter reads this
opsi  = Math.atan2(ss, sc);      // the crowd's shared phase

// coupling ramps in — the bank arrives scattered, gathers over ~26s
const K = 0.55 + 2.1*Math.min(1, t/26);

// each firefly nudges its clock toward the crowd (Kuramoto, 1975)
const effK = K*(1-inf);          // your lamp drops coupling to inf
th[i] += (om[i] + effK*order*Math.sin(opsi - th[i]))*dt;

Nine hundred hands on the desktop, three-hundred-sixty on a phone, each solving that one line sixty times a second — no library, no shader, one canvas.

03What each pass found

The first draft is never why a scene like this reads real. The loop is: shoot the live page, read it like an art director who wants to hate it, fix everything, then add one deliberate upgrade. Four times.

  • PASS 01First light

    Built the swarm on nine berembang trees and wired the order parameter to the corner meter.

    Found: the first painted frame was a black void — the river looked dead before the eye arrived — and the moon was a hard silver disc fighting the headline for the top-left. Fix: pre-warm nine steps so the opening frame is already mid-blink; feather the moon into a haze and move it clear of the type.

  • PASS 02The arrival

    Found: starting at full coupling meant the river was already solved on load — no story, nothing to watch gather. And the white lede text floated illegibly over the brightest fireflies. Fix: ramp coupling in over ~26s so it arrives scattered and visibly finds its beat; add the bottom scrim plus a text-shadow so every line holds AA contrast over the live light.

  • PASS 03The air

    Found: the scene read flat — bright dots on black paint, no depth, no place. Fix: drift low fog along the waterline, lay four bands of water shimmer, and reflect the brightest flies on the river's surface. Upgrade: the boatman — hold the bank at full sync for a few seconds and he speaks.

  • PASS 04The hand and the phone

    Found: on a phone the scroll cue and lamp control hid behind the fixed synchrony meter, and on a tall desktop the keyboard-lamp affordance sat below the fold. Fix: lift the hero clear of the meter on mobile and tighten the display rhythm so the control clears the fold. Upgrade: the lamp control is now a live gauge — its underline fills toward chartreuse as the river agrees, so "keep still" finally has a visible reward.

  • PASS 05The hand and the whole

    Found: the boat-lamp fiction stopped at the glow — the water beneath it never answered — and the footer stat sat too faint over the dense firefly field. Fix: a text-shadow lifts the ship stats clear of the light. Upgrade: the lamp now trembles on the water in concentric ripples, and at full sync — the moment the bank flashes as one — faint chartreuse threads knit near neighbours into a single organ of light, then fade with the beat.

04What shipped

Concept study of a fictional boat house on the Kampung Kuantan jetty. The phenomenon, the species and the mathematics are real; the brand is not.

~35 KB
page weight
0
CDN · images
900
live oscillators
0
console errors

Reduced-motion serves a complete, posed frame with the bank near unison. The canvas caps device-pixel-ratio at two and pauses when the tab is hidden. Every flash is computed; nothing is a loop of video.