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 parison | sagging, if you stop turning |
|---|---|---|---|
| 1100 °C | 280 | 15.6 mm/s — gone in a breath | 9.8 mm/s |
| 1000 °C | 1 400 | 3.2 mm/s | 2.0 mm/s |
| 920 °C | 6 800 | 0.65 mm/s | 0.41 mm/s |
| 850 °C | 39 000 | 0.11 mm/s | 0.07 mm/s |
| 750 °C | 1 200 000 | nothing | nothing |
(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
- Radiative cooling, per ring, off its own surface area. A thin wide ring has more skin and less glass than a thick narrow one, so it goes off first. That is the only thing damping the inflation runaway, and it is not enough.
- Centrifugal hoop stress, ρω²r². Negligible at 70 rpm and worth a fifth of a full breath at 150. Spinning a hot piece flat is a real move and it is the reason the roll gauge has an upper band as well as a lower one.
- Convective cooling from the breath itself, about 25 W/(m²·K) — a fifth of what the piece is already losing to the room, landing on the inside of the thinnest wall, which is exactly where you needed the heat.
- The glory hole at 1350 °C, heating by σ(T_hole⁴ − T⁴) like anything else. Twenty seconds in there and you will not be able to hold what you make.
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.





