WHAT IS THIS?
A glass ball painted by numbers. The number π = 3.14159265… goes on
forever, and nobody can predict its digits. This machine reads those
digits, one small handful at a time, and turns each handful into one
glowing dot inside the ball. You choose the rules; the number does the
painting. There are no wrong answers here — you are the author.
HOW A DOT IS BORN
The ball's skin is covered in about 200,000 tiny cells. Each cell
reads 5 digits: two say how deep its dot sits (00 = the very
centre, 99 = the skin), one picks the colour, one the
brightness, and the last digit decides whether the dot appears at
all — small digits mean no dot, which is why the ball has airy
gaps instead of grey mush.
THE KNOBS
- SOURCE — which endless number does the painting: π, e, √2 and
friends, C₁₀ (a number that counts: 1 2 3 4 5…), CE (all the prime
numbers glued into one endless number), SQ (the square numbers
1 4 9 16 25… glued together), f∞ (a 0-and-1 pattern that never
repeats, built from the same golden rule as the ball's skin), or RND (a
repeatable "random" — its SEED picks which random universe you get).
- SPLICE — weave two or three numbers together like braided hair.
Each one's PICTURE tick says whether it paints; untick one and it
leaves the picture but can still sing.
- MODE — EPOCH shows a whole ball at once and can flip to the next
"page" of digits; BEAM paints dot by dot with a little moving head, like a
plotter drawing.
- CUTOUT — more threshold, more empty space.
- MOTION — gives every dot its own orbit, so the whole ball swirls.
- ❚❚ / ▶ — the round button on the picture freezes everything —
the turning, the swirling, the song — and starts it all again, without
opening the panel. You can still turn the frozen ball to look around.
ON A PHONE
Drag with one finger to turn the ball, pinch with two to zoom. The ☰
button opens the control panel and ✕ tucks it away again. If the sound
goes quiet after your screen has slept, one tap anywhere brings it back.
MAKE IT SING
Every number you choose gets its own singer. Each has a wide
VOICE switch with its name on it, and everything that shapes its
sound sits in the panel attached below; switching a voice off takes its
panel away. Splice in a second number and a second voice appears, singing
alongside the first — turn either on or off, and give each its own tempo,
scale and echo. VOLUME voicing sings the dots (gaps become silence, deep
notes sound dark and near ones bright); SURFACE sings every cell. Try
TOP-DOWN order to make the melody rain from the top of your screen. A
little flash in the voice's own colour shows where each note is.
Each voice reads its number from its own PHASE — a different
starting point gives a different tune from the same number — and a
number does not have to be in the picture to sing. And every note
sounds different, because the SOUND FROM DIGITS boxes (ticked
from the start) let each note read a few more digits just for its sound.
TIMBRE picks the note's texture — from a pure whistle to a buzz —
and whether a puff of hiss or rumble rides along. ENVELOPE shapes
each note in time: a sharp pluck, a slow swell, a long ring.
MODULATION makes notes wobble in pitch, pulse in volume, or go
wah. Untick all three and the voice plays the plain instrument, with
the WAVE you choose.
THE NUMBER RIBBON
The strip at the bottom shows the actual digits being used right
now. Colours tell you each digit's job (the key sits at the strip's top
right). Click any group to see exactly how those digits made their dot —
and hear each singing voice play that spot. The strip shows the
picture's digits; a voice reads digits of its own, and the box in the
panel lists them, voice by voice.
IF IT RUNS SLOWLY
Your graphics card draws this sphere and barely notices — a couple of
per cent of a modern machine. But some browsers are set to draw with the
processor instead, and that costs roughly thirty-five times more:
fans spin up, everything stutters. If that happens here, the page notices
and slows how often it redraws — and tells you it has. Nothing about your
pattern changes: the same cells, the same cutout, the same picture, simply
refreshed fewer times a second. That is the only thing that genuinely
helps, and it helps a lot — at four redraws a second the cost falls to
about a quarter.
The real cure is one browser setting. Look for “Use graphics
acceleration when available” — in Chrome and Edge it is under
Settings → System — switch it on and reload. If you would rather have
every frame regardless, tick FULL SPEED in the panel and the page
will stop easing. That choice belongs to this device: it is never saved
into your recipe, and never travels in a shared link.
KEEP IT · SHARE IT
SAVE remembers your creation on this computer (it returns when you come
back). SHARE opens a little window with a link that regrows your creation
anywhere — copy it, email it, or send it with your phone's own share
sheet. The link stores your recipe, not a picture, so it is only a
few hundred letters long. FILM records a movie, REC records the sound of
every voice together.
A film stops at a size limit, so for a longer one set FILES
beside FILM to more than 1: when one file is full the next starts on the
very next frame, up to that many files, numbered part01, part02 and so
on, ready to be joined end to end in any video editor. Your browser may
ask once whether this page may download several files — say yes, or
only the first arrives. The line just under the size box tells you how
much disk space it will take — each file, and all of them together — so
you can check there is room first; real files can come out smaller.
Ask for more than 10 files and the page shows you that total and waits
for you to say yes before it starts.
The box beside FILM chooses the movie's size. Leave it on STAGE for
something to watch here; pick 1080p, 1440p or 4K to record a proper
upload — the stage becomes a letterboxed preview of the frame being
filmed, and the file that lands is at YouTube's own recommended rate,
ready to go up untouched. Bigger films cost more per second, so each one
has its own length limit, shown under the button.
The second box is the format. PLAY ANYWHERE writes MP4, which
Windows opens by double-clicking. BEST DETAIL writes WebM/VP9,
which only a browser or VLC will play here — but the sphere's rim is a
field of dots about a pixel wide, and that is the one thing MP4 handles
badly: decoding a take back and comparing it with the frame that went in,
MP4 keeps 47% of the rim's fine contrast where WebM keeps 64%, in a file
a third smaller. YouTube accepts either, so if the film is for uploading,
choose BEST DETAIL.
SMOOTH ×2 draws each frame at twice the size and averages it back
down, which is what stops the sphere's rim breaking into hard specks —
the dots there are smaller than a pixel, and this lets one arrive as a
fraction of its colour rather than as all or nothing. It costs four times
the drawing, so a 4K film is really being drawn at 7680×4320; if your
machine will not give a surface that big the film simply records without
it and says so.
Windows plays MP4 out of the box and has no decoder for WebM, so a
.webm that refuses to open there with "the specified procedure could
not be found" is a missing codec, not a damaged film — it will still
upload, and any browser will play it.
THINGS TO TRY
- Switch SOURCE between π and C₁₀ — one looks like confetti, the other
grows stripes and shells. Both are "normal" numbers. That difference is
the whole mystery.
- BEAM mode + PAINTED surface, INTERIOR off — watch the skin being woven.
- MOTION on + VOICE on + TOP-DOWN — a swirling, singing rainstorm.
- A/B TWIN — can you tell π from fake randomness? (Nobody can.)
- SOURCE π, SPLICE e, then untick π's PICTURE: the ball is painted by e
alone while π and e sing a duet. Give e's voice a different PHASE and a
slower TEMPO and listen to the two numbers answer each other.
- f∞ only speaks in 0s and 1s, so its dots hug a few inner shells and
most of the ball goes dark — but slide CUTOUT around and watch golden
spirals appear that no other number can make: the number and the ball's
skin are built from the same golden ratio, and they interfere.
- CE looks like C₁₀'s stripes gone weathered — the counter skips
because primes do. And its gaps hide a real secret: neighbouring primes
avoid ending in the same digit, so the voids avoid clumping in a way no
RND seed can fake.
- SQ is C₁₀'s cousin that counts in squares: the stripes stretch
(squares grow new digits twice as fast), and every square must end in
0, 1, 4, 5, 6 or 9 — so wherever a square's last digit lands on a job,
that job inherits the comb.
THE FAMILY
DigitHorizon is the fifth machine in a family that all ask the same
question — can you tell a famous number from randomness? The others:
NormalNumber ·
UniverseSignal ·
GeometrySignal ·
DigitLoom.
And say hello any time — GET IN TOUCH lives at the bottom of the
control panel.
THE HOLOGRAPHIC PREMISE
Black-hole thermodynamics says a region's maximum entropy scales with
its surface area, not its volume (S = A/4 in Planck units). This app
enacts that as budget honesty: a boundary of N ≈ 4πn² cells is all the
information there is; the interior is reconstructed — each cell
projects one point inward along its own radius. A volume at the same
resolution would need ~n³ digits no genuine constant can supply. This is a
radial projection with the right entropy scaling, not AdS/CFT bulk
reconstruction (which is non-local over the whole boundary) — the app never
claims otherwise.
THE BOUNDARY LATTICE
Cell i of N sits at the Fibonacci sphere point:
y = 1 − 2(i+½)/N, θ = i·2π(2−φ) — near-equal-area
(a lat/long grid would oversample the poles, a visible density lie), closed
form at absolute position, and the golden spiral is the raster order the
BEAM head walks. Equivalent radius n ≈ √(N/4π).
THE DIGIT PIPELINE
Cell i reads the contiguous group at address
PHASE + epoch·N·DPC + i·DPC. PHASE (the PICTURE PHASE box;
each voice has its own) is where the reading
starts: 0 is the stream's first digit, and a larger value opens every
cycle that much deeper in — the same number, a different sphere. It
shifts the addresses only; nothing else about the paint path changes,
and wrap counting follows it. CE alone is bounded here, to 1,000,000,000:
it has no closed form and must sieve forward to reach a digit.
Group order: depth 2 (t = d/99 → r = t·n
PROJECTED, or ∛t·n UNIFORM — linear depth piles density as 1/r², the
emergent core), hue 1 (36° steps), brightness 1, cutout 1 (digit/9 ≥
threshold paints, else the cell projects nothing), then optional sat 1,
size 1, motion 3. DPC runs 5–10; the budget box recomputes live. The
voices read their own numbers at their own rates and never touch it.
projectCell(i, N, base, out, tap) is pure — deterministic in
(digits, recipe, position); no Math.random anywhere in the paint path.
SOURCES & STREAMING
π, e, √2, φ (8M digits) and ζ(3) (2M) ship as packed-nibble assets (2
digits/byte, high nibble first), head-validated, fetched by HTTP Range in
256 KiB chunks only as the address stream needs them — never fully
resident; wraps counted and announced. C₁₀ (provably normal) computes any
digit by closed form over the counting sequence. CE (Copeland–Erdős,
provably normal) concatenates the primes — no closed form exists, so a
forward segmented sieve grows an index (a checkpoint every 2¹⁴ primes)
and one segment is re-sieved and decoded on demand: computed, never
stored whole; the budget box reports the frontier. Prime last digits past
5 are only {1,3,7,9}, so a cutout of 0.55 paints exactly the 7s and 9s —
and consecutive primes avoid repeating last digits (Lemke Oliver–
Soundararajan 2016), an anti-correlation no counter hash reproduces.
SQ (Smarandache — the squares; normality conjectured, NOT proven, and
the budget box says so) shares C₁₀'s closed form:
⌊√(10^d−1)⌋ − ⌊√(10^(d−1)−1)⌋ squares have d digits, so the band walk
skips straight to m and the digit falls out of m² — exact Numbers to
10¹⁵, BigInt beyond. Square last digits are the quadratic residues
mod 10, only {0,1,4,5,6,9} — a lawful comb wherever they land.
f∞ is the Fibonacci word
(fixed point of 0→01, 1→0; deliberately NOT normal): any digit by exact
descent of the concatenation tree Sk = Sk−1Sk−2
— no floating-point φ, no drift at large addresses. Its 1s sit at Beatty
positions ⌊kφ²⌋, quasiperiodic with the same ratio the boundary lattice
spirals by — the one source that can moiré against the sphere. Binary
digits mean depth reads only 00·01·10·11: the dots live on four shells,
and CUTOUT paints exactly the 1s (density 1/φ² ≈ 38%). RND is a counter hash:
digit(i) = h(seed, i) — deterministic, absolute-position, shareable. The
A/B twin's control reads the same addresses through seed⊕0xA5A5.
THE SPLICE
A braid of T ≤ 3 threads presents as one tap. CELL grain: block b
belongs to thread b mod T, reading that thread's own stream at block
⌊b/T⌋. DIGIT grain: digit w of cell e comes from thread (e+w) mod T — the
rotation stops any thread being locked to one property role; each
contributes exactly DPC digits per period T·DPC. Honest braid length =
T·DPC·min⌊lent/DPC⌋ over bounded threads. The braid is made of
the threads ticked PICTURE, and only those: untick one and T falls by one,
the braid re-forms over the rest — so the picture changes — and the
thread lives on as a voice. At least one thread always paints; with one
left there is no braid, just that number.
MOTION
Two digits pick an orbit axis from a 100-direction Fibonacci lattice;
one digit a quantized angular speed ω = (d/9)·rate (0 = still). Orbital
rather than linear because a straight velocity exits the sphere and would
need wrap/bounce rules the digits never chose; rotation preserves radius
(the core stays the core) and every path is exactly periodic. Rodrigues
rotation runs in the vertex shader from per-point (axis, ω, birth)
attributes; the clock consumes no digits. Picking, markers, flashes and
TOP-DOWN order all evaluate positions at current orbit time.
THE VOICES
One voice per thread of the splice, each reading its own number alone —
never the braid — from its own PHASE: voice k's cell i sits at
phasek + cycle·N·Dk + i·Dk, where
Dk is 5 plus that voice's sound groups. It shares the picture's
lattice, so cell i of every voice lies on cell i's ray, and its first five
digits keep the picture's layout (hue unread): a voice with its sound
groups off, reading a lone painting number at the picture's PHASE, sings
exactly the points it paints. Pitch: depth digits → degree over the chosen
scale spanning two octaves from 110·2^(root/12) Hz. VOLUME voicing: cutout
voids rest; velocity ×(1−0.45r); low-pass 500+4500r Hz (core loud/dark,
rim quiet/bright); pan = the cell's x. SURFACE sings every cell. EPOCH:
each voice's head walks the spiral at its own tempo (or its TOP-DOWN sort:
cells counting-sorted into 1024 bands by the height of its own notes along
the camera-up axis, re-sorted as the view drifts). BEAM: each voice sings
its own reading of the last-painted cell; PAUSE silences because frozen
heads consume nothing. The flash marks where a note sits, on its ray at
its own depth — the painted point when the voice reads what the picture
paints, its own place otherwise. Each voice has its own level and echo
into one mix.
Sound from digits is ticked by default and costs the voice's own
reading, never the picture's: each group lengthens that voice's cell, so
its cells move along its number while the picture stands still. TIMBRE — wave digit: one of ten band-limited
PeriodicWaves, amplitude 1/nᵖ over 48 harmonics, odd-only for 1–4
(triangle p=2 → square p=1 → reed p=0.7), all harmonics for 5–9 (round
p=2 → saw p=1 → buzz p=0.4), 0 a pure sine; it overrides WAVE. Noise digit:
0 clean, then brown · pink · white in threes, each light · medium · heavy
(0.12 · 0.3 · 0.6 of the tone), from buffers grown by a fixed xorshift, so
a recipe regrows the same hiss. ENVELOPE — ADSR against the note's gate g
(NOTE LENGTH at TEMPO): attack 2 ms·(g/2 ms)^(d/9), so 9 swells for the
whole note; decay 10 ms·(g/10 ms)^(d/9), cut short by the gate; sustain
d/9 of peak; release 15 ms·(R/15 ms)^(d/9) with R = min(2 s, 3 beats).
Off, a note keeps its fixed pluck: 12 ms up, exponential fall over g.
MODULATION — each digit 0 is off. Vibrato ±5d cents at 4.5–8 Hz on the
oscillator's detune; tremolo depth d/9 at 3–12 Hz; wah ±(d/9)·2 octaves on
the low-pass's detune at 1.5–6 Hz, with resonance Q 1→8 so the sweep is
heard. Phase starts all three LFOs at d·36°: a lone tone's own starting
phase is inaudible, but where a wobble starts is not — tremolo from its
trough swells in, a wah from closed says wah and from open
yow.
ECHO is a 0.28 s feedback delay on each voice's bus; every bus meets
in one mix, and REC (WAV) and FILM tap that mix, so they capture what you
hear. A FILM run is up to FILES files: each is a fresh MediaRecorder on
one unbroken capture stream, and when a file reaches its cap the next is
started and the full one stopped in the same task, so the handover falls
between two frames rather than across one. Each file is capped and freed
on its own, so memory never holds more than one. Under the size box, the
disk each file and the whole run will take: a full file is its cap at the
target bitrate, (video + 192 kbps of voices) × cap / 8 — about 600 MB
for every preset, since the cap is set by that budget. It is an estimate,
not a bound: the encoder aims at the rate, and can come in under it on
this mostly dark field. Above 10 files the page states the total and
waits for a yes. FILM writes H.264+AAC
in MP4 or VP9+Opus in WebM, your choice, each falling back to the other
where MediaRecorder will not offer it — YouTube ingests both, Windows
decodes only the first, and VP9 holds the rim's sub-pixel dots far better
(47% of its neighbour contrast survives H.264, 64% survives VP9, measured
by decoding a take and comparing it with the frame that went in). Its presets pin the
drawing surface to 1920×1080, 2560×1440 or 3840×2160 for the take
(8/12/16/24/40/60 Mbps, 30 or 60 fps — YouTube's recommended bands); the
frame rate is whatever the page actually redraws, so the guard's cap is
the real ceiling and FULL SPEED lifts it. SMOOTH ×2 renders the take into
an offscreen target at twice the export size and resolves it down with a
four-tap box filter — exact for a factor of two. Measured at the rim, the
same light then arrives spread over 42% more pixels with neighbour
contrast down by a third. The point-size floor and ceiling ride on
uPx, the drawn surface's height over 600 — the same factor
the size itself uses — so a dot too small to register covers the same
fraction of the frame at any size, and the stage and a 4K film of it no
longer disagree about how dense the rim is.
THE TRACK & PROVENANCE
Every dot has a computable stream address, so the strip is a window
over a formula, not a log. Digit colours (key at top right):
depth ·
hue ·
brightness ·
cutout ·
sat ·
size ·
orbit; under a
splice, badge bars beneath each digit name its thread. The strip is the
picture's stream; each voice's own reading of a cell appears in the
provenance box instead, one row per singing voice — its address, its
digits, the note, and what its sound digits chose. Clicking a group — or
a point in the ball — recomputes that cell through the real projection:
marker, radial ray, digit breakdown, and its notes on demand.
DETERMINISM & PERSISTENCE
The saved object is the recipe (version 1, sanitised through a
migrations gate): source/splice, which threads paint, mode, cells,
mapping, thresholds, properties, and every voice's settings — on or off,
phase, sound groups and all. A link from before the voices were per
thread keeps its one voice's settings flat on the recipe; they come back
as the SOURCE's voice, reading from the picture's PHASE with no sound
digits, as it was made. Recipes-not-outputs: any machine regrows the
identical pattern from pass zero (GPU rasterisation isn't bit-identical
across machines, but the computed points are). One PatternStore port:
localStorage + base64url #p= links. Rendering: raw WebGL1
points, additive blending, gain deliberately below white — full-precision
everything is grey mush; form needs restraint.
THE PERFORMANCE GUARD
The main thread sits ~97% idle while a few hundred thousand blended
sprites are drawn, so the cost is all in the raster. On a GPU that is ~2%
of an eight-core machine; on the CPU cores it measured ~35× dearer — every
core pinned at 13 fps. Two signals catch it.
WEBGL_debug_renderer_info names the driver before a frame is
drawn (conclusive where exposed — Firefox hides it, Safari generalises
it), and the achieved rate is sampled in 2 s windows: below 25 fps
uncapped, or below 80% of the ceiling once capped, twice running. The
clock is what catches a mid-range phone on a real GPU, which no driver
string would flag.
The guard caps redraw rate and nothing else, which is a
measured choice rather than the obvious one. Easing resolution to 45% of
device pixels moved per-frame cost from 85 ms to 86 ms — the load is
vertex-bound at ~600k point sprites, not fill-bound — and since the loop
draws as fast as frames complete, a cheaper frame only buys more frames
and CPU never falls. CPU = per-frame cost × frames per second, and only
the second term is ours: capping measured 2.3× cheaper at 8 fps and 4.2×
at 4. The ceiling is set from what the device actually managed (half,
then a quarter), the dt clamp rises with it so time does not
run slow, and cells, cutout and depth are never touched — those are the
recipe, and editing the artifact to buy frames would be exactly the
dishonesty the rest of this page avoids. Being a property of the device
rather than the pattern, it is excluded from the recipe and from
#p= links.