A constant-weight freedive on a rope: down to a plate, grab a tag, come back, and stay conscious for fifteen seconds on the surface. One button, which is finning. Everything else in the game is two gas laws arguing with each other.
Boyle says the only compressible thing you own is the air in your chest, so your displacement — and therefore your buoyancy — is a function of depth. You leave the surface floating with five kilos of lift and arrive at sixty metres three and a half kilos negative. The descent stops being work about ten metres down and becomes a fall.
Dalton says the oxygen your body reads is the fraction left in your lungs multiplied by the ambient pressure. At the bottom that multiplier is five or six. So the number goes up while the thing it is measuring goes down, and it keeps going up for as long as you keep descending.
The first law makes the way down cheap and the way home expensive. The second makes you feel best at the moment you have least. They meet in the last ten metres, which is where this happens:
| where the lights went out | share of blackouts |
|---|---|
| on the surface | 8% |
| 0–5 m | 32% |
| 5–10 m | 19% |
| 10–20 m | 27% |
| below 20 m | 14% |
222 blackouts over 1155 simulated dives, every one to a depth the rig in question could plausibly have been asked for. Median blackout depth 7.5 m, on dives whose median deepest point was 56.2 m. You do not drown at the bottom. You drown having already climbed 87% of the way back.
The gauge that lies, and the one the sport does not have
Here is a single clean dive to 45 m on 2.5 kg of lead. Two columns matter: what the body is reading, and how much is actually left.
| moment | t | alveolar pO₂ | saturation | O₂ left | if you left now, at the surface |
|---|---|---|---|---|---|
| leaving the surface | 1 s | 117 mmHg | 98% | 99% | 98% |
| 20 m, descending | 13 s | 266 mmHg | 100% | 76% | 97% |
| 40 m, descending | 30 s | 410 mmHg | 100% | 70% | 92% |
| the turn, 45 m | 34 s | 443 mmHg | 100% | 69% | 89% |
| 30 m, ascending | 59 s | 232 mmHg | 100% | 50% | 88% |
| 20 m, ascending | 68 s | 153 mmHg | 99% | 44% | 88% |
| 10 m, ascending | 77 s | 91 mmHg | 98% | 39% | 89% |
| 5 m, ascending | 82 s | 65 mmHg | 96% | 37% | 89% |
| the surface | 85 s | 42 mmHg | 90% | 35% | 89% |
| four seconds later | 89 s | 98 mmHg | 93% | 83% | 93% |
Three things in there are the whole game.
The gauge peaks at the bottom. 443 mmHg at the turn is nearly four times what you had in your lungs on the surface with a fresh breath, and you have already spent a third of your oxygen to get it. The fraction at that moment is 0.107 — about 81 mmHg of real oxygen wearing a 5.5× multiplier. Nothing was added on the way down. The pressure was doing the flattering.
The collapse is not gradual. Between 45 m and the surface the store goes from 69% to 35% — it roughly halves. The reading goes from 443 to 42, which is a factor of ten. The extra ninefold is the multiplier being taken back, and it is taken back fastest in the shallows, because pressure falls fastest there in proportional terms: the last ten metres halve the ambient pressure, and halve the multiplier with it. It is exactly the halving the first ten metres bought you, handed back at the moment you can least afford it.
The last column is flat. That is the honest instrument: run the rest of the ascent forward at the economical effort and report what you will be reading when you arrive. It sits at 88–89% for the entire climb. It barely moves, because the climb was already priced in at the turn — everything after that is you paying an invoice you signed at the bottom. The demo draws both on one dial, in the same units, same scale: a solid bar for now and a dashed line for when you get there. Watching the dashed line sit in the red while the bar is still three-quarters up is the piece.
Real freedivers do not have that second line. They have the first one, which feels wonderful.
Three readings at the turn, and what came of them
Same plate at 55 m every time. Only the lead changes, which only changes how the descent was paid for.
| lead | pO₂ at the turn | saturation | O₂ pool left | projected at the surface | economical up | sprint up |
|---|---|---|---|---|---|---|
| 1 kg | 402 mmHg | 100% | 53% | 74% | clean | blackout, 18.6 m |
| 2.5 kg | 506 mmHg | 100% | 66% | 77% | clean | blackout, 13.3 m |
| 3.5 kg | 551 mmHg | 100% | 72% | 68% | clean | blackout, 12.7 m |
| 4.5 kg | 585 mmHg | 100% | 77% | 44% | blackout, 1.4 m | blackout, 13.6 m |
Read the bottom row against the top one. The dive that kills you arrives at the turn with a higher partial pressure, a fuller oxygen store, and the same perfect 100% saturation. Every instrument a diver actually carries reads better on the fatal dive than on the safe one, and they read better for a real reason: the extra lead got you down faster and cheaper, so you genuinely are less tired and genuinely do have more left. The only number that knows is the one nobody has, and it is the difference between 77% and 44%.
Then it blacks you out at 1.4 metres.
How much lead
Lead is the one dial that moves where the descent stops being work.
| lead | neutral | deepest clean dive | O₂ down | O₂ up | cheapest effort at 50 m |
|---|---|---|---|---|---|
| 0 kg | 27.6 m | 50 m | 1784 mL | 633 mL | 27% |
| 1 kg | 18.0 m | 60 m | 1341 mL | 786 mL | 34% |
| 1.5 kg | 14.8 m | 62 m | 1184 mL | 885 mL | 37% |
| 2 kg | 12.3 m | 61 m | 1057 mL | 988 mL | 41% |
| 2.5 kg | 10.2 m | 60 m | 950 mL | 1100 mL | 46% |
| 3 kg | 8.5 m | 58 m | 859 mL | 1234 mL | 50% |
| 3.5 kg | 7.0 m | 56 m | 783 mL | 1370 mL | 54% |
| 4 kg | 5.8 m | 53 m | 715 mL | 1532 mL | 59% |
| 5 kg | 3.7 m | 48 m | 604 mL | 1864 mL | 68% |
The two oxygen columns cross over between 2 and 2.5 kg, and the optimum sits just before the crossing. But the interesting comparison is 1.5 kg against 4 kg. The heavy rig spends 2247 mL on a 50 m dive and the light one spends 2069 — 8.6% more oxygen — and it costs nine metres of depth. The same oxygen buys less when you spend it going up, because going up is when the multiplier is leaving.
The last column is what lead really costs, and it is not a number the diver can feel. “Cheapest effort” is whatever setting moves a metre for the least oxygen, and it climbs from 27% to 68% across the table. Past about 4 kg the economical ascent has stopped being economical in any useful sense — it is most of a sprint, and it is the best available option rather than a mistake. Lead does not just make the ascent cost more. It removes your ability to be frugal on the way up, which is the half of the dive where frugality was the whole game.
The sprint
| policy | dive time | O₂ spent | lowest saturation | outcome |
|---|---|---|---|---|
| freefall, economical up | 85 s | 1898 mL | 89% | clean |
| freefall, float up | 87 s | 1912 mL | 88% | clean |
| fin all the way down | 78 s | 2268 mL | 74% | clean |
| economical, then sprint the last 10 m | 82 s | 2185 mL | 85% | clean |
| economical until the contractions, then sprint | 75 s | 2554 mL | 66% | clean |
| freefall, sprint up | 57 s | 2825 mL | 50% | blackout at 2.3 m |
And over fifteen rigs — three belts, five plates:
| policy | clean | samba | blackout |
|---|---|---|---|
| freefall, economical up | 93% | 0% | 7% |
| turn when you want to breathe | 93% | 0% | 7% |
| freefall, float up | 87% | 7% | 7% |
| economical, then sprint the last 10 m | 73% | 20% | 7% |
| fin all the way down | 47% | 7% | 47% |
| economical until the contractions, then sprint | 40% | 0% | 60% |
| freefall, sprint up | 20% | 13% | 67% |
Sprinting home saves 28 seconds and costs 49% more oxygen, and it takes you from a 7% blackout rate to 67%. Drag power goes as the cube of speed, so the cost per metre roughly doubles between the cheapest effort and a full sprint — at 40 m that is 21.4 mL per metre against 40.2. There is no depth in the table where it pays.
Which leaves the ugly reading, and it is the one the table is really for: the panic sprint is what a frightened diver does, it is the correct instinct for every other emergency anyone has ever been in, and it is close to the worst available option here. The dive was decided at the turn. Nothing you do on the way up is worth as much as the thirty seconds of patience that got you a cheaper turn.
The cheapest effort is never zero, either:
| depth | buoyancy | cheapest effort | mL O₂ per metre | at full sprint |
|---|---|---|---|---|
| 60 m | −3.5 kg | 48% | 24.6 | 41.6 |
| 40 m | −2.9 kg | 43% | 21.4 | 40.2 |
| 20 m | −1.6 kg | 32% | 15.9 | 37.7 |
| 8 m | +0.6 kg | 19% | 10.9 | 34.7 |
| 4 m | +2.1 kg | 13% | 8.8 | 32.9 |
At four metres the water is already pushing you up with two kilos and the right answer is still a light kick, because time itself costs oxygen and a free ride is a slow one. The demo puts a green mark on the effort bar at whatever the optimum is for your current depth, and the mark slides down the bar as you climb.
What the purge buys
Hyperventilating before a breath-hold is the single most reliably lethal thing in the sport, and the reason is not that it hurts you. It is that it works.
No plate on the rope here: the diver descends until they want to breathe badly enough to turn, which is how anyone not on a competition line actually dives.
| breathe-up | starting O₂ | wanted to breathe at | turned at | deepest | outcome |
|---|---|---|---|---|---|
| calm | 2932 mL | 38 s | 50.7 m | 53.4 m | clean |
| moderate | 2980 mL | 82 s | 80.0 m (rope) | 82.9 m | blackout at 19.0 m |
| heavy purge | 3008 mL | 113 s | 80.0 m (rope) | 82.9 m | blackout at 18.4 m |
| breathe-up | median depth reached | clean | samba | blackout |
|---|---|---|---|---|
| calm | 45.4 m | 67% | 11% | 22% |
| moderate | 82.7 m | 0% | 0% | 100% |
| heavy purge | 82.7 m | 0% | 0% | 100% |
Blowing off carbon dioxide adds 76 mL of oxygen — 2.6%, and only because alveolar gas gets marginally richer once the CO₂ leaves; haemoglobin was already 98% saturated and had nowhere to put more. It delays the urge to breathe by 75 seconds, from 38 to 113.
So the purge buys two and a half percent more fuel and triples the length of the drive. The urge to breathe is a CO₂ alarm, not an O₂ alarm, and a freediver navigating by it is using an instrument that has been silently recalibrated by the thing they did on the surface to feel comfortable. The model also moves the blackout threshold up a little with hypocapnia, since low CO₂ constricts the cerebral vessels and the same arterial saturation then delivers less oxygen to the brain — but that is the small effect. The large one is the missing alarm.
What the model is, and what it is not
src/dive.mjs is headless and framework-free. The split is worth being honest
about, because the two halves are not the same quality of physics.
The buoyancy is exact, in the sense that it is Archimedes applied to a list of volumes and it has no free parameters doing any work:
- lean tissue at 1062 kg/m³, which is denser than seawater — a diver who exhales fully sinks, and that is where the whole thing starts;
- a thin suit as 1.6 L of rubber plus 2.6 L of gas, compressing on Boyle with a stiffness term, because neoprene cell walls carry some of the load;
- lead at 11.34 kg/L, which contributes mass and almost no volume, which is the entire point of lead;
- lungs at 7.0 L on the surface, dividing by absolute pressure.
Sum, multiply by 10.066 N per litre, subtract weight. The neutral depth is not tuned, it falls out: 10.2 m on 2.5 kg. Real divers weight themselves to be neutral at ten to fifteen metres, and they do it by feel, not by arithmetic.
The gas model is a calibrated caricature. Real oxygen lives in four compartments with different time constants; this has one well-mixed pool of which the lungs hold 37%, so the alveolar fraction is a constant times the pool. Saturation is a Hill curve on alveolar pO₂ (P₅₀ = 26 mmHg, n = 2.7) with a four-second first-order lag standing in for lung-to-brain circulation time. Consumption is a resting draw plus a quadratic in effort, damped with depth because the dive response is real and does slow you down. The calibration anchor is a static breath-hold: at these numbers the same diver holds one to blackout in about three minutes, which is a decent club diver rather than a record holder. Halve the resting draw and you have an athlete.
That lag is not decoration. It is why the surface protocol exists:
the surface — 42 mmHg, 90% saturated, and rising four seconds later — 98 mmHg, and it went down first
You arrive, you breathe, you look fine, and then the blood that was at five metres finally reaches your head. 8% of the blackouts in the big table happen after the diver is already on the surface with their face out of the water. In the demo you cannot end a dive by touching the surface; you end it by staying conscious for fifteen seconds afterwards.
Playing it
Hold space, or hold the pointer, to fin — it is a level, not a switch, so it winds up while you hold and runs down when you stop, and a light touch really is a light kick. Shift sprints. X, or right-click, turns you for the surface wherever you are; the plate turns you automatically if you get there. R resets.
Pick a plate, some lead, and a breathe-up. Then:
- The first ten metres are the only ones you pay for. You are five kilos positive and you have to fight all of it, which is why real divers duck-dive hard and why the belt matters.
- Somewhere around the neutral depth the arrow in the corner flips and the water starts pulling instead of pushing. Stop finning. A 45 m dive on 2.5 kg of lead is 35 free metres. Every kick in there is oxygen spent on something gravity was doing anyway.
- Turn, and climb at the green mark.
- Watch the dashed line, not the bar.
The plate turns you, but it does not stop you. On a heavy belt you will overshoot it by two or three metres before the economical effort arrests 1.9 m/s of freefall, which is a real thing that happens to real divers and is the reason a competition lanyard has slack in it.
Reuse
Everything in src/dive.mjs is metres, seconds, kilograms, newtons, litres and
atmospheres absolute. No DOM, no canvas, no rendering.
createRig({ belt, lung, breatheUp })→ the diver plus what they chose to wear and how they breathed.pressureAt(d),displacementAt(rig, d),buoyancyAt(rig, d)→ the exact half.neutralDepth(rig)bisects for the crossing;terminalSpeed(rig, d, effort, dir)solves the steady state.createDiver(rig)/stepDiver(rig, s, dt, { effort, turn }, { target })→ the dive. Takes an effort and knows nothing about keyboards.saturationFor(p)/pO2ForSaturation(s)→ the Hill curve, both ways, so both needles can be drawn on one scale.economicEffort(rig, d, dir)→ the effort that moves a metre for the least oxygen, memoised on the half metre.projectSurface(rig, s, opts)→ the honest instrument. Runs the remaining ascent forward plus the fifteen seconds afterwards and returns the trough, not the arrival value, because the trough is the part that lands after you are already breathing.urgeFor(s)→ the CO₂ alarm, which is not the O₂ alarm.
node scripts/measure.mjs prints every table on this page; --csv gives one
row per run. node scripts/screenshot-demo.mjs regenerates the thumbnail and
the media shots by driving the demo’s own hooks in a real browser.
Gotchas
- Touching the surface is not the same as finishing. An early draft ended the dive the first frame the diver’s depth hit zero, which is the frame every dive starts on: you float, effort ramps from nothing, buoyancy wins for a tenth of a second, and the run was over before it began. The measurement policies never caught it because they all start at full effort. Surfacing now only counts if the dive went somewhere.
- The projection has to model the lag, or it is useless. Returning the saturation at the moment of arrival makes the dashed line optimistic by exactly the amount that kills people. It returns the minimum over the ascent and the surface interval.
economicEffortis called a few thousand times per projected ascent, and a projection runs several times a second. It is memoised on the half metre; the cost curve is flat near its minimum so the rounding costs nothing.- The figure is not drawn to the depth scale. At thirty metres on the rope a real diver is six pixels wide and there is nothing to look at, so the swimmer is drawn at a readable fixed size while the depth, the rope and the plate stay honest. The cost is that the monofin sometimes crosses the plate.
demo/bundles its own copy ofdive.mjs— self-contained by contract (ADR-0002). Re-copy after editingsrc/.
A note on the real thing
The safety diver in the demo meets you at 20 m and is the only reason a shallow blackout in this game is a bad afternoon rather than the other thing. That is not a game mechanic either. Freediving’s entire safety culture is one rule — never alone, ever, not in a pool, not in two metres of water — precisely because the failure mode is silent, it happens near the surface, and the person it happens to feels fine right up until it does. Nothing here is training.


