Everyone who has been bowling knows the ball “grabs” when it reaches the dry back end. The reading that turns out to be wrong is the obvious one — that the dry boards are what make it hook, so more friction means more hook.
They do not. The dry boards decide when. The amount was settled at the foul line.
One line of algebra, and the piece is downstream of it
A ball leaves the hand sliding: the surface under the contact point is moving relative to the lane, at a slip velocity u that is nothing like the ball’s travel direction, because the hand put spin on an axis that is not the axis of travel. Kinetic friction acts antiparallel to that slip. And it does two things with the same force — slows the centre of mass, and spins the ball up — which land on u along the same line:
u̇ = v̇ + R(ẑ × ω̇) = −(1 + mR²/I)·μg·û = −(7/2)·μg·û (I = ⅖mR²)
The right-hand side is parallel to û. So the slip vector shrinks and never turns. Measured across the whole slide, on three wildly different lanes, the drift is 0.00000°.
That is the whole piece, because a friction force whose direction never changes can be integrated without knowing anything about the lane. Over the entire slide, the total impulse is fixed by how much slip there was to burn:
Δv = −(2/7)·u₀
No μ in it. Not “approximately”; the harness checks it to one part in 10¹². Where the lane is dry, where the pattern ends, how rough the ball’s cover is — none of those terms exist in that equation. They only set how quickly the slip drains, and therefore how far down the lane the ball is when the turn finishes.
It is also the same 2/7 as in Tangent, which is not a coincidence and is slightly annoying: a bowling ball and a cue ball are both spheres going from sliding to rolling, so both convert exactly two sevenths of their contact-point slip into a change of direction, and both people who quote the number learned it as a rule of thumb.
Five lanes, one release, one angle
The second view throws one identical release — 7.6 m/s, 350 rpm, 45° of axis rotation — at five patterns and reports where the ball arrives and at what angle.
| pattern | reaches roll | entry board | entry angle |
|---|---|---|---|
| 44 ft house | 55 ft | 17.2 | 5.86° |
| 34 ft short | 46 ft | 28.4 | 5.86° |
| stripped bare | 14 ft | 40.6 — left gutter | 5.86° |
| 50 ft long | never | 11.1 | 5.37° |
| flooded | never | 6.4 | 0.21° |
The top three are the result. They put the ball 23.4 boards apart — more than half the width of the lane — and they deliver it at angles 0.0018° apart. The stripped lane finishes the turn by 14 feet and then carries the ball, dead straight and at the full 5.86°, into the left gutter. Same throw.
The bottom two are the only escape, and they escape the same way: the ball was still sliding when it ran out of lane. You cannot take the turn away from a bowling ball. You can only fail to give it enough room to finish. A 50 ft pattern delivers 92% of it. A lane flooded end to end delivers 0.21° of the 5.86° it was owed, which is a picture of why nobody hooks the ball on fresh oil and everybody assumes it is because the oil is slippery. The oil is slippery. That is not the reason.
So what does move the angle
Three things, and all three are in your hand before the ball is:
| dial | |||
|---|---|---|---|
| rev rate | 200 rpm → 2.85° | 350 → 5.86° | 500 → 8.53° |
| axis rotation | 15° → 1.12° | 45° → 5.86° | 75° → 9.29° |
| ball speed | 6.2 m/s → 7.31° | 7.6 → 5.86° | 9.2 → 4.69° |
Revs and axis rotation buy angle. Ball speed spends it — which is the one row
that surprises people, and it falls straight out of the algebra: speed goes
into u₀ as down-lane slip, so throwing harder makes the turn vector point
more backwards and less sideways. A harder throw is a straighter ball, not
a later one.
The 15° row is where the piece gets its name. Axis rotation is how much of the rev rate is pointed across the lane rather than along it; at 15° there is 1.12° of turn available in the whole throw, and a ball like that can be given the driest lane in the building and will still go straight, because there was never any slip across the lane for the friction to work on.
Roll out is the fail state, and it is the quiet one. A 200 rpm ball at 15° of axis and 6.2 m/s reaches full roll at 47 feet — thirteen feet of lane left, the ball travelling perfectly, nothing visibly wrong — and arrives at 0.36°. It rolls out: finishes its business early and then spends a quarter of the lane as a dead weight going in a straight line. The bowler sees a shot that looked fine and a rack that did not fall, and reaches for more hand.
The wall, which is why you average 190 at your local house
The third view sweeps the aim across the arrows a quarter-board at a time and plots where each shot ends up. On a flat pattern the answer is a straight line with a slope: one board of aim is 3.95 boards at the pins, and it is the same 3.95 wherever you measure it. Miss your target by two boards and you miss the pocket by eight. That is a sport pattern, and it is why they are hard.
A house shot — oil banked heavily through the middle, thin on the outside — gives a curve instead, and near the pocket the slope goes negative: −1.42. Push the ball a board right of target and it finds drier boards, turns harder, and comes back to the pocket anyway. Pull it a board inside and it holds in the oil. The pattern is running a negative feedback loop on your mistakes.
The pocket window is 2.50 boards of aim wide, against 0.50 on the flat pattern — 5.0× wider. That ratio is the entire difference between league night and a PBA regional, and none of it is the bowler.
And then it moves under you
Which is the mechanic. Every shot lifts oil off the boards it touched, and lays a fraction of it back down further along — the pickup is the ball’s, the carrydown is the lane’s answer. Throw twenty down the same line and the track burns: the breakpoint climbs from board 6.7 to board 11.1, the ball starts its turn earlier and earlier, and by the twentieth shot it arrives 8.5 boards further left than it did on the first. What was a pocket shot in frame one is a crossover by the end.
And across all twenty, the entry angle never moves. 0.0029° of spread.
That is the thing worth having built the simulation for. The lane transition — the reason bowlers move left through a session, the whole subject of lane play — is not the lane taking the hook away or handing more of it over. The hook is a constant the bowler set at the foul line. The lane is only ever moving the place where it gets spent, and the bowler’s entire craft is re-aiming so that a fixed turn keeps landing in the same 1.5 boards.
What is not modelled
The ball is a uniform sphere, and a real one is emphatically not: it has an
asymmetric core, the spin axis migrates over the course of the shot as the
cover hooks up, and that track migration is most of what a pro shop sells you.
Modelling it means an inertia tensor and a rolling contact patch, and it would
change the shape of the turn without changing the total, because
Δv = −(2/7)u₀ follows from the sphere’s I = ⅖mR² — a different core gives
a different fraction, not a different kind of answer.
Point contact, so no spin friction: ωz — the ball rotating about the vertical
— drops out of the slip entirely. Real covers have a contact patch a couple of
inches across and it matters a little.
Reactive resin is a chemical response to oil, not a coefficient, and it is here as a coefficient: μ interpolates between 0.020 on fresh oil and 0.28 on a dry back end. That range is tuned to put a 350 rpm shot’s breakpoint on board 7 at 45 ft and its roll at 55 ft, which is where a real one goes.
And carry() is a scoring model rather than ten rigid bodies, which is a
research project on its own. It is built on the two things the carry literature
does agree on — the ball has to arrive near board 17.5, and it has to arrive at
an angle, with strike probability peaking near 6° — and it is honest about
being a curve fit. The leaves it names (high, light, flat, ringing 10) are the
right names for the right misses, and nothing more.
Reuse
src/rollout.mjs is framework-free, has no DOM in it, and is SI throughout.
slip(v, ω)andskidTurn(v₀, ω₀)→ the closed form.skidTurnis fourteen lines and answers “where does this ball end up pointing” without integrating anything. If you want the physics and not the game, it is the only function you need.Oil→ the pattern, as a grid in (down-lane, board).mu(x, y)is what the integrator asks;wear(path)is what a shot does to it;reset()puts the machine back over it. The cross profile is the interesting parameter —outer,inner,shoulderandedgeare what separate a house shot from a sport pattern, and settingedge: 1with a wide plateau gives you the flat one.roll(release, oil)→ one shot. Returns the path sampled every 4 ms with the slip vector and local μ on each sample, plus the breakpoint, the roll transition and the entry. Fixed-step at 0.2 ms; the roll transition is detected by checking whether the step would carry|u|through zero, which is the only place the integration needs care.wallScan/dialSweep/frictionSweep/gameDrift→ the four studies, each returning plain rows. Every table above is one of these called once.carry/score→ pinfall and tenpin scoring, separable from all of it.
Port notes: the whole integrator is about forty lines and translates directly
into a tick method. Two things bit me and will bite anyone. The torque sign:
τ = r × F with r = (0, 0, −R) gives ω̇x = +fy/(kR), ω̇y = −fx/(kR), and
getting either backwards makes the slip grow — which at least fails loudly.
And carrydown has to conserve oil: the first version normalised the deposit
Gaussian wrong and put back nine times what it picked up, so the lane got
slicker the more it was used and the ball hooked less every frame. It looked
plausible. It was exactly backwards, and the only reason I caught it is that
the transition was pointing the wrong way in the one direction every bowler
knows by heart.
The harness
node scripts/screenshot-demo.mjs boots the demo in a real Chromium,
regenerates thumb.png and media/, and asserts 33 claims against the
running page, exiting non-zero if any stops being true. Every number above is
in there: the 0.00000° of slip drift on three patterns, Δv = −(2/7)u₀ to one
part in 10¹², the closed form and the integrator agreeing on 5.86°, the 17.5%
speed loss, all five lanes and the 0.0018° they agree to, each of the three
dial ladders, the flat pattern’s 3.95 and the house shot’s −1.42, the 5.0×
window, the twenty-shot drift with its breakpoint march and its flat angle, the
47 ft roll-out at 0.36°, and twelve shots going down a burning lane without the
demo falling over.




