One page, one artefact: the Williams–Kilburn tube of Manchester, 1948 — the first random-access memory — run as a genuine simulation in raw WebGL. Its single job is to let you feel the tube’s central bargain: this memory only exists while something keeps re-reading it.
Concept
Wave 11 is about media taught to hold the past, and the Williams tube is the purest case in the set: bits stored as spots of charge that leak away in a fraction of a second, kept alive only by a refresh beam re-reading and re-writing every spot forever. The site’s signature is the honest failure — HOLD REFRESH pauses the sweep and the entire memory visibly dies through a marked readability threshold into noise, with the losses counted from the framebuffer itself.
Palette
This palette lives deliberately next to the laziest default in generative design — near-black plus a single acid-green accent — and it has to earn its place there. The argument: green-on-black is not a style here, it is the artefact’s own emission spectrum. The Baby’s store rode on radar-surplus CRTs whose green persistence phosphor put this exact colour on this exact black half a century before it became a hacker trope; the trope is a memory of hardware like this. What disciplines it into period furniture rather than terminal cosplay is everything around the glow: a bakelite chassis brown that owns the page margins, a valve-heater amber for warnings and thresholds, and the rule that phosphor green is reserved for marks and lines — body copy is set in a derived pale-afterglow ink dimmed to contrast spec, never in the accent.
Type
Chivo, a grotesque with mid-century engineering-plate bones, carries the identity — 900 for the wordmark and section heads (the one moment of typographic loudness per band), 400 for body. Fragment Mono is the machine’s own voice: every measured value, HUD line, cell address and threshold is set in it, so a reader can tell at a glance which words are prose and which are instrument.
Techniques
Raw WebGL 1, two fragment programs, no libraries. A 32×32 RGBA8 state texture holds, per spot, a 24-bit re-arm timestamp (millisecond fixed-point) plus bit-value and alive flags. A field pass evaluates the physics per spot in GLSL — charge = 2^(−(t−t₀)/T½), continuous exponential decay from the moment of last write — into a 32×32 framebuffer. That FBO is then sampled two ways: the display pass reads it to draw the face, and readPixels reads it to produce every number in the HUD — the bits-lost count, the inspector’s live decay curve, and the measured half-life, which is fitted from two sampled points of a decay segment and shown beside the shader constant it must match. The closed-form time base sidesteps the 8-bit iterative-decay quantisation stall, and the CPU keeps only bookkeeping: which spot the beam re-armed, and when.
The display pass draws each bit as the literature’s two charge wells — a round dot for 0, an elongated dash for 1 — as elliptical gaussians scaled by charge, dissolving into hash-noise flicker below the readable threshold. The comet tail behind the raster beam is not an effect: it is simply the freshest charge, already leaking. The bakelite chassis, superellipse glass edge and vignette are all in the same shader. On boot the tube starts dark and the beam writes the program in, line by line, at 4× scan rate.
The store’s resting pattern is the amended 18 July 1948 listing of Kilburn’s highest-factor routine from Geoff Tootill’s notebook (the 21 June original was never recorded), encoded in real SSEM order code — operand in bits 0–12, function in bits 13–15, least-significant bit leftmost — with the historic argument −218 in line 23. A QA assert samples the framebuffer and checks line 1 decodes back to LDN 24.
Honest numbers
The sim is openly slower than the artefact so the race is visible to an eye; the page says so where the numbers appear. Every figure above either comes out of the running framebuffer or is hedged exactly as the sources hedge it.
Iteration log
Screenshot review caught a defect the framebuffer asserts had sailed past: the display was vertically mirrored. GL’s bottom-left UV origin put store line 0 at the bottom of the face while picking and the inspector put it at the top — data, clicks and readback were all mutually consistent, so 29 asserts passed while the dense constant rows (lines 20–27) rendered in the wrong third of the tube. One-line flip in the display shader. Also fixed: at 375 px the HUD cards covered nearly the whole face (restaged to a stacked wordmark / square tube / HUD flow on small screens), and a HUD throttle that could show a stale lost-count for a few frames after a rewrite.
The harness exposed a real physics flaw: with the beam resuming at normal scan rate after a hold, every cell’s age at its next visit is identical (hold + one full period), so a released store survived or died all-or-nothing on a knife edge — “survivors persist” was undemonstrable. Fix in the mechanism, not the caption: on release the beam sprints one rescue sweep at ×4 scan rate, which produces genuine partial survival (measured: 2.7 s of hold → 214 of 1,024 re-armed). Added the boot write-sweep (the tube loads its own program on arrival), the phosphor ring on the inspected cell, and shift-click to inspect without writing.
Reduced motion renders the settled frame — pattern held at full charge, no sweep — verified static by hashing two screenshots. DPR capped at 2, rAF paused on document.hidden, context-loss poster paired with a [hidden]{display:none !important} guard and asserted invisible while the scene runs. 375 px probe checks the wordmark, nav and controls sit inside the viewport, not just scrollWidth. Chanel rule: removed the glass-highlight band from the shader — the bevel already argues bakelite; the highlight argued nothing. Final read re-checked every guide number against the shipped constants.