workshop private

← all creations

Gather

games · created 2026-09-19

Hot glass on the end of a pipe, and one rule underneath all of it — viscosity. Blowing wants it hot, holding a shape wants it cool, and the only thing standing between a piece and the floor is that you never stopped turning. Three shapes, a minute or two each, and the physics is soda-lime's own.

physicssimulationcanvasgame-feel

Hold D to keep the pipe turning. W and S tilt it. Space blows, Shift puts it back in the glory hole, Enter knocks it off and scores it. That is the whole control scheme, and none of the five verbs does what it looks like it does.

The whole game is one curve

Soda-lime glass has no melting point. It has a viscosity, and the viscosity is a function of temperature so steep that every decision in the shop is really a decision about where on that curve you want to be standing. src/glass.mjs carries the curve as a Vogel–Fulcher–Tammann fit,

log₁₀ µ(Pa·s) = −2.585 + 4215 / (T − 263)      T in °C

which puts the working point (10³ Pa·s) at 1010 °C and the softening point (10⁶·⁶) at 715 °C — where a real soda-lime batch puts them. Nothing else in the file is a difficulty setting. Here is what that one curve costs you:

Tµ (Pa·s)blowing a 16 mm parisonsagging, if you stop turning
1100 °C28015.6 mm/s — gone in a breath9.8 mm/s
1000 °C1 4003.2 mm/s2.0 mm/s
920 °C6 8000.65 mm/s0.41 mm/s
850 °C39 0000.11 mm/s0.07 mm/s
750 °C1 200 000nothingnothing

(Both columns are for the fresh gather: 16 mm radius, 4.83 mm wall, 85 g.)

Everything people say about glassblowing falls out of the gap between those last two columns. You cannot blow it at 850 and you cannot hold it at 1100, and the interval where you can do both is about twenty seconds wide and closing the whole time you are looking at it.

Why you never stop turning

The piece sags because it is a viscous shell on a steel pipe, so it creeps downhill off the pipe at roughly ρgLt/3µ. That is a real velocity — a centimetre a second at reheat temperature — and it does not care what else you are in the middle of.

What makes it survivable is that the slump is laid down in the frame that is turning. In that frame gravity points at (sin φ, cos φ), and a steady roll integrates that to zero. Turning does not resist gravity; it averages it. The residual is about v/ω, which is why the rule is not “turn” but “turn faster when it is hotter”. At 1100 °C and 76 rpm you are carrying 1.2 mm of wobble the whole time; at 1000 °C the same 76 rpm leaves 0.26 mm; at 850 °C it sags at 0.07 mm/s, so stopping dead would cost you four minutes to lose the piece and it will have gone rigid long before that.

Stop entirely and the amplitude just accumulates in one direction. The end-on inset, top right, is how a glassblower actually checks this — sighting down the pipe — and it is the only view where a wobble is unambiguous. It is drawn at four times life size, because a millimetre on a 30 mm piece is two pixels, and two pixels is not a warning.

Why blowing is not the shaping tool

Hoop stress in a thin shell is σ = p·r/t, the strain rate is σ/3µ, and the wall thins as the radius grows because the glass in that ring is conserved. So the growth rate goes as r³ and the fastest-growing ring only ever gets faster. Inflation is unstable by construction — there is no stabilising term to leave out, and one long breath instead of four short ones ends with a 22-centimetre bubble and a 0.69 mm wall. You can watch that happen in 05-the-runaway.png; it took seventeen seconds, and the piece was past saving long before it went.

Which means blowing cannot put glass anywhere. It only reveals where the glass already is: a thick wall inflates slowly, a thin one runs away. The tool that moves glass is the tilt, and the model for it is a viscous column hanging off the pipe —

∂u/∂z = F(z) / (3µA),   A = 2πrt,   u = 0 at both ends

— where F is the weight hanging below each station. Both ends are pinned: the neck is fused to the steel and the closed tip has nowhere to send glass on to. That second boundary condition earns its place. Without it the column necks itself apart against whichever end it is draining towards, in about a second, every time.

So: tip down pools glass at the closed end, which thickens it, which makes it refuse to open — and you get an ornament. Tip up drains it back to the base and leaves the lip thin, and the lip is then the first thing to run away — and you get a bowl. Same two keys, opposite shapes, and neither of them is a special case in the code.

Things that are real and are in here

Things that are not

GLASS.pBlow is the one tuned number. A sustained lungful down a pipe is about 2 kPa. Set it to 2 kPa and hold the blow in the glory hole and the piece bursts at t = 1.27 s; hold it on the bench with no reheat and it survives, at 17 cm across, which is not survival. That is correct — it is why real blowing is short puffs against a thumb, and why a glassblower’s actual pressure is a transient and not a level — and it is also not a game, so the constant is set to an eighth of it. Everything else on the page is a measured property of soda-lime glass or a consequence of one.

The shape of the slump along the pipe is asserted rather than derived — nothing at the pipe mouth, everything at the free end. The amplitude comes out of the material; that one curve does not.

The drawn outline gets five [1,2,1] smoothing passes. The single-ring wiggles are real — glass by the pipe does drain and blow thinner than its neighbours — but half a millimetre reads as a dent at this scale. Nothing the model or the score sees is touched.

Length is fixed. A real piece tilted tip-down gets longer; this one only redistributes glass along a fixed 70 mm, which is the largest simplification in the file and the first thing I would undo.

Reusing it

src/glass.mjs is framework-free and has no DOM in it. createPiece(i), stepPiece(p, dt, {rollAxis, tiltAxis, blow, heat}), evaluate(p). It substeps internally, so any dt up to about 50 ms is safe. viscosity(T) and wall(p, i) are exported on their own and are the two useful pieces if you want hot glass in something else. demo/ bundles its own copy, per ADR-0002.

node scripts/smoke.mjs runs the model headless and asserts the things above: that the VFT fit lands the working and softening points where the literature does, that a piece left alone goes off rather than exploding, that stopping the roll loses it, that blowing hot and hard bursts it, that the tilt flow conserves glass to machine precision, and that a played tumbler scores an A. node scripts/screenshot-demo.mjs boots the demo in a real browser and fails on any page error, which is how the pictures above stay honest.