The Naval Gaming spec
Draft for Marlinspike's review, written 2026-10-06. Nothing in it is approved until Marlinspike signs it off, and no sim code is written before then. This page is the spec; it is served on dev only.
This is the rebuild's specification for the launch: single-player Battle Builder. It describes what the game does, in player terms, and the shape of the code that will do it. It covers only what Marlinspike kept for launch on 2026-10-06; everything else is listed under Later and Dropped.
1. Rules
For every number
- History is the starting point; play decides the value (Marlinspike, 2026-10-06: "we are not trying to simulate history"). Each value carries two layers: the historical base with its citation, and the game value, if different, with why and when.
- A value with no source says so: "tuning guess, set by play". A source that was looked for and not found is "citation needed". Neither is ever dressed up as a fact.
- Tune with global scales first. Time compression covers most of the gap between history and play. Per-value changes are the exception and always carry their reason.
- Historical units stay historical in the spec (feet, pounds, knots, yards). Code converts them in one place.
- Polars and other tables live in JSON data files, where
bin/cleanroom_check.shcompares them as tables. A number written into prose or code is checked only one value at a time.
For every word
- A ship is "it", never "she" (Marlinspike, 2026-10-01): in player text, comments, tests and docs.
- No served file and no player text names another game (Marlinspike, 2026-09-24).
- The world is fictional (Marlinspike, 2026-09-30). The Crown and the Cabal are its sides. Real ships appear only as the cited source of a class's numbers, never as names in play.
The gate
bin/cleanroom_check.sh (in the station repo, run from the projects root) passes on
this repo, and Marlinspike signs off. Hits cleared by a citation are listed in
cleanroom-accepted.txt at the repo root.
2. Behaviour
What the player sees and does at launch. Dates and "Marlinspike" mark his decisions; "proposed" marks a choice made in this draft for him to confirm.
The game
Naval Gaming is "something people play for its own sake" (Marlinspike, 2026-09-24), not a testbed for a sailing model. At launch it is one product, Battle Builder: you set up two lines of ships and fight in one of them, alone in your browser, with no account (Marlinspike, 2026-09-29).
Battle Builder
- You choose the ships on each side, any mix of the five classes, up to 8 a side, and for each whether you or an NPC captain commands it (Marlinspike, 2026-10-01). A side is never empty.
- You command one ship. The first ship marked Player is yours, and it may be on either side. At launch only one ship can be marked Player.
- Nothing is stored. The battle is encoded in the page address, so a reload or a copied link restores it exactly (Marlinspike, 2026-10-01).
- The layout is fixed: two lines abreast, facing each other, under a steady wind (Marlinspike, 2026-10-01). Wind, range and map are not choices. The starting range and the wind's direction across the lines are tuning guesses, set by play.
- The sides are the Crown and the Cabal (Marlinspike). Each line flies its side's ensign; the ensign goes by side, not by ship. At launch the Cabal is "the Cabal" under a plain placeholder ensign; its real ensign, and any full name, are Marlinspike's to design later, from scratch (2026-10-06).
- The sheet shows each ship drawn in plan, a Player/NPC switch, add and remove, and a tally per line of ships, guns and broadside weight. Its wording, the battle's title and its briefing are Marlinspike's to write. Until he does, the sheet uses plain functional labels and has no title or briefing; the code invents no copy (2026-10-06).
Sailing: the helm
- The helm turns the rudder to port or starboard. Holding the key moves the rudder over at the rate a crew could put the helm across; letting go eases it back amidships. A double tap holds it hard over until the helm is touched again (Marlinspike, 2026-10-06).
- The rudder works only with water flowing past it, so it bites in proportion to speed through the water. Going astern, its effect reverses smoothly, with no snap at zero (Marlinspike, 2026-09-23).
Sailing: sail
- Three sail levels: none, topsails, full (Marlinspike, kept 2026-10-06). Each step up or down is an order to the men aloft, not an instant change (see Crew).
- Ship-rigged and brig-rigged classes trim with yards, in two groups: the fore yards, and the main and mizzen yards together. Each group is braced on its own.
- Auto-trim braces both groups to the wind for you. Touching either group by hand turns it off; one key turns it back on.
- Each yard group drives the ship according to its angle to the wind. A group with the wind on the front of its sails is aback and pushes the ship astern.
- Each group also turns the ship: sail forward of the pivot pushes the bow off the wind, sail aft of it pushes the stern. So the age-of-sail tack works: haul the main yards round as the bow crosses the wind, and hold the fore yards aback until the bow is past it. Split yards can turn a ship that has no way on.
- The cutter trims with sheets, not yards (Marlinspike, 2026-10-04). A backed mainsail gives it only a little sternway. The jib's sheet is limited so the jib can't fly out ahead. A boom hauled across to windward stays backed until it is eased or auto-trim takes it.
- Sternway is real (Marlinspike, 2026-09-23). Speed is signed. A square-rigged ship head to wind stops, then gathers sternway; the speed display says "astern".
- The no-go zone is shown on the compass rose as the limit of how close the ship can point ("in irons").
Wind
The wind is steady for the whole engagement: one direction, one strength (Marlinspike, 2026-10-06). Its strength is a tuning guess, set by play.
Gunnery
- You don't aim. You steer. Where you put the hull decides what the guns hit; the crew lays and fires them (Marlinspike, 2026-09-24).
- Each side of guns has three orders (Marlinspike, 2026-10-06), cycled in turn:
- Stand Down: the side is unmanned; its crew goes to the sails. Loaded guns stay loaded.
- Load: the side is manned; the crew loads and holds.
- Fire at Will: the side is manned; each loaded gun fires as it bears.
- Gun crews are sized by the guns, from period quarter bills (Marlinspike, 2026-09-25). They fill first from men off station, then from the sail crew. So fighting both sides under full sail starves one or the other, and that is the point.
- Guns start an engagement empty. Reloading goes on whether a side is firing or holding. An unmanned side's loaded guns can still fire, but don't reload.
- Fire at Will ripples. Each loaded gun fires the moment it bears, so a broadside ripples down the side as the target comes into each gun's arc. Leaving Fire at Will mid-ripple holds the guns that haven't fired; holding at Load and then going to Fire at Will gives the full broadside at once (Marlinspike, 2026-09-24).
- "Bears" means a ship that hasn't struck is inside the gun's arc and range, nearest first. A gun holds fire while a friendly ship fouls its range. The firing rule is one replaceable rule; Marlinspike plans a later one that scores each shot.
- Round shot only at launch (Marlinspike, 2026-10-06).
- Smoke: every shot makes a puff at the muzzle that grows, fades and drifts downwind, so a broadside leaves a bank to leeward. It is visual only.
- Gunport lids are open while a side is manned or loaded. Guns recoil and run out again as they reload.
Hits
- Shot hits shapes, not the drawn ship. Each ship has a hull shape and a rig shape for hits, kept apart from the model you see, so redrawing a ship never changes a fight (Marlinspike, 2026-09-27). See Physics: hits.
- A hull hit costs men, not planks. There is no hull health and no sinking (Marlinspike, 2026-09-24). A ball that goes through the side kills and wounds in proportion to its path inside the hull, so a rake, end to end, is the great killer; a ball that glances off does little. Each hit leaves a visible mark.
- A rig hit holes the sails (Marlinspike, 2026-10-06). Each one takes a little of that ship's drive, for good. Round shot can't bring a mast down at launch.
- No repairs during an engagement (Marlinspike, 2026-09-24).
Crew
- Every ship has a complement (see Ships). Casualties come off it.
- Men are at stations: sail, port guns, starboard guns, or off station. The station bar shows each with men present over men needed.
- Sail handling needs men aloft. An order waits while the topmen go up, then the canvas moves. Its speed is the men at the sail station over the men the sails need. Full sail needs more hands than topsails; furled sails need none.
- Casualties slow everything they touch: guns reload more slowly with fewer men, and sails are handled more slowly (Marlinspike, 2026-09-24).
Morale and striking
- Morale falls with casualties and recovers in lulls (Marlinspike, 2026-09-24, kept 2026-10-06). Recovery is always slower than the slowest reload, or fights run to near-total casualties (a consistency rule; see Pacing).
- A ship strikes when morale breaks. Striking is an event (Marlinspike, 2026-10-01): the ship loses its commander, stops firing, furls its sails, hauls down its colours, shows a white flag and drifts. It keeps its side. Nothing fires on it.
- Engagements never end (Marlinspike, 2026-09-29). There is no victory, defeat, result screen or time limit. Allies fight on after you strike.
- When your ship strikes (Marlinspike, 2026-10-06): the strike notice shows, the camera stays free so you can watch the fight go on, and the pause menu offers Fight again (a fresh start of the same battle) and Leave. Marlinspike's notice, with the boat taken out until boats exist: "We are sorry, captain, but the crew is exhausted and cannot continue. We must strike our colors." (Confirmed by Marlinspike, 2026-10-06.)
- Ship status, shown on its label: Commander, Status (Under command, In squadron, Unattended) and Side (Marlinspike, 2026-10-01). Conditions such as dismasted or aground come later with those features.
NPC captains
- A captain sails every ship but yours, enemies and allies alike (Marlinspike, 2026-09-28).
- A captain issues the same commands a player does, through the same command layer, and can do nothing a player can't (Marlinspike, 2026-09-25; architecture 2026-10-06).
- It is scripted, then tuned: a hand-written captain whose few parameters are tuned later by headless self-play. No neural net (Marlinspike, 2026-09-25).
- What a captain does at launch: choose a target, the nearest enemy, and keep it rather than flip between ships; pick a heading from scored candidates, ruling out the no-go zone and collisions; wear, never tack (Marlinspike, 2026-10-06; tacking can come once it is reliable); shorten to topsails when close; and man the side the enemy will bear on, early, because clearing takes time.
- Allies keep clear of you and hold fire while you foul their range.
The squadron and signals
- Every captained ship on your side is in your squadron from the start (Marlinspike, 2026-10-02). Before any signal, a squadron ship fights as it would alone.
- Six signals (Marlinspike, 2026-10-01 and 2026-10-03; all kept 2026-10-06):
- line abreast to starboard; line abreast to port; line ahead; line astern: each names a station relative to you, the flagship, with ships stacked outward at equal intervals, nearest first. In line, a ship keeps station and fires as its guns bear, but does not manoeuvre for a shot;
- engage at will: releases the squadron to fight freely;
- heave to: each ship lies to where it is, sails in, firing as its guns bear.
- A signal goes to the whole squadron; ships can't be singled out.
- Station-keeping: on station, a ship matches your sail; behind, it sets more; ahead, less. An equal ship can't catch a flagship under full sail; that is a fact of sailing, not a bug.
- Signals take time (Marlinspike, 2026-10-01; kept without drawn flags, 2026-10-06). Each ship answers after a delay that grows with its distance from you, and only with a clear line of sight; it obeys as it answers. The HUD shows which ships have answered. An overtaken signal, or one made by a flagship that strikes, is lost. The delays are tuning guesses, set by play.
- The signal list opens without pausing; the helm stays live. It shows each signal and the one in force. Choose with ↑/↓ and make it with Enter, or click a signal (Marlinspike, 2026-10-06).
The view
- One 3D chase view with sky, sea, wakes, splashes and smoke (kept 2026-10-06).
- Ships are generated from their data, not modelled by hand, so yards and sails move with the physics (Marlinspike, 2026-09-24). Simpler at first; at distance only masts, yards, sails and shrouds are drawn. Flags stream in the apparent wind.
- Ships heave, pitch and roll on the swell. This is visual only; the physics keeps the water flat.
- The camera (Marlinspike, 2026-09-23): above and behind, horizon near the top; it lags the heading in a turn, by the same amount at any time scale; drag to look around and it swings back on release; the wheel changes the distance.
- The compass rose turns with the ship: the card, the points, the wind arrow and the yards drawn over the hull. It shows the no-go limit.
- The station bar, bottom centre: port guns, sail, starboard guns, each with men present over needed and, while that side loads, a bar of its mean load (Marlinspike, 2026-10-02). Each gun side shows its order (Stand Down, Load, Fire at Will); clicking it cycles the order, the same command as the key.
- The tally, top centre: misses, hull hits and rig hits for your own ship's shot, reset on a fresh start (Marlinspike, 2026-10-02; his wording, which he may change). Every number shown comes from the sim's state, never from sums done for the display.
- Start screen, pause menu, controls panel. Any screen pauses the sim, except the signal list. The pause menu has the time scale, Controls, Fight again and Leave. The controls panel lists every key and is generated from the real bindings, so it can't drift from them.
- The time scale: 1×, 2×, 4×, 8×.
- Without WebGL the page says the game needs it and links the devlog (Marlinspike, 2026-10-06; the old fallback was the 2D view, now dropped).
3. Controls
The sailing keys are Marlinspike's (2026-10-06): helm and sail on A/D and W/S, yards on Q/E and Z/C, auto-trim on F, a double tap for hard over. The gun and signal keys are his too (2026-10-06). The rebuild plan asked for controls designed fresh; these are Marlinspike's choice as owner, made deliberately. The controls panel is generated from the bindings, so this table and the game can't drift apart once the code exists.
The idea: the left hand sails and trims, the right hand fights, the mouse looks.
Keyboard
| Action | Key | Notes |
|---|---|---|
| Helm to port / starboard | A / D, or ← / → | Hold to put the helm over; release eases it back amidships. |
| Helm hard over, held | double tap A / D | Stays hard over until the helm is touched again (Marlinspike). |
| Make more sail / take in sail | W / S, or ↑ / ↓ | One step: none, topsails, full. |
| Brace fore yards to port / starboard | Q / E | Turns auto-trim off. On the cutter: the jib sheet (Marlinspike). |
| Brace main and mizzen yards to port / starboard | Z / C | Turns auto-trim off. On the cutter: the mainsheet (Marlinspike). |
| Auto-trim on | F | Both yard groups follow the wind again (Marlinspike). |
| Port guns: Stand Down → Load → Fire at Will | J | Each press moves to the next order; the order in force shows on the station bar. |
| Starboard guns: Stand Down → Load → Fire at Will | L | |
| Signal list | Tab | Opens without pausing; ↑ / ↓ choose, Enter makes the signal; Tab or Esc closes it. |
| Slower / faster time | , / . | 1×, 2×, 4×, 8×. |
| Pause menu | Esc | Time scale, Controls, Fight again, Leave. |
| Controls panel | H |
While the signal list is open, ↑ / ↓ move through the list instead of setting sail, and ← / → do nothing. A / D / W / S, the yards and the gun keys stay live (Marlinspike, 2026-10-06).
Mouse
| Action | Input |
|---|---|
| Look around | Drag; the camera swings back behind the ship on release. |
| Camera distance | Wheel. |
| Station bar | Click a gun side to cycle its order; the same command as the key. |
| Signal list | Click a signal to make it. |
Not bound at launch
Gamepad, rebinding, and touch. Keys for later features (boats, the telescope, the minimap, range rings, ammunition) are not reserved; they are chosen when those features are specified.
4. Ships
Five classes at launch (Marlinspike, 2026-10-06): four square-rigged, sharing one rig model, and one fore-and-aft cutter with its own. Each class takes its numbers from one real ship or class, cited below. Where armament varied from ship to ship, the class takes its cited ship's exactly and notes the variance (Marlinspike, 2026-10-06). The real ship is the source, not a name in play: in the game a class is "the First Rate", "the Seventy-four" and so on, and individual ships get placeholder names and numbers (Marlinspike, 2026-10-01).
Confidence: H consistent across sources or from a primary or academic text; M one secondary source; L an uncited page or a clash. Source keys are in Sources. Draught is missing for four of the five and best speed for three. Those cells say so; they are not to be filled from memory.
First Rate: HMS Victory (1765), as at Trafalgar, 1805
Source: [VICTORY], which cites Goodwin, Lavery and Winchester.
| Value | Conf. | |
|---|---|---|
| Length on the gundeck / keel | 186 ft / 152 ft 6⅝ in | H |
| Beam / depth in hold | 51 ft 7½ in / 21 ft 6 in | H |
| Burthen | 2,142 bm | H |
| Draught, victualled | 24 ft 3 in forward, 25 ft 6 in aft | M |
| Lower gundeck | 30 × 32-pdr | H |
| Middle gundeck | 28 × 24-pdr | H |
| Upper gundeck | 30 × 12-pdr | H |
| Quarterdeck | 12 × 12-pdr, 2 × 68-pdr carronades | M |
| Forecastle | 2 × 12-pdr, 2 × 68-pdr carronades | M |
| Complement | about 850 | M |
| Rig | ship, three masts; 6,510 sq yd of sail | M |
| Speed | "up to 11 knots"; 7–8 knots in a topgallant gale (point of sail not given) | M |
Seventy-four: the Arrogant class
Source: [ARROGANT], which cites Winfield 2007, pp. 64 and 77, and Lavery 1984, p. 176.
| Value | Conf. | |
|---|---|---|
| Length on the gundeck / keel | 168 ft / 138 ft 10 in | H |
| Beam / depth in hold | 46 ft 9 in / 19 ft 9 in | H |
| Burthen | 1,614 bm | H |
| Draught | citation needed | |
| Lower gundeck | 28 × 32-pdr | H |
| Upper gundeck | 28 × 18-pdr | H |
| Quarterdeck | 14 × 9-pdr | H |
| Forecastle | 4 × 9-pdr | H |
| Complement | 550 (first batch), 600 (second) | H |
| Rig | ship | H |
| Speed | citation needed |
Frigate: HMS Shannon (1806), a 38 of the Leda class
Sources: [SHANNON], [LEDA], citing Winfield 2007 and Gardiner 2000 (no pages given).
| Value | Conf. | |
|---|---|---|
| Length on the gundeck / keel | 150 ft 2 in / 125 ft 6½ in (the class page: 150 ft 1½ in / 125 ft 7⅞ in) | H |
| Beam / depth in hold | 39 ft 11⅜ in / 12 ft 11 in (the class page: 12 ft 9 in) | H |
| Burthen | 1,065 bm | H |
| Draught | citation needed | |
| Upper deck | 28 × 18-pdr | H |
| Quarterdeck | 2 × 9-pdr, 12 × 32-pdr carronades, Shannon's own and the figure used (armament varied by ship; the class page gives 8 × 9-pdr, 6 × 32-pdr carronades, noted only) | M |
| Forecastle | 2 × 9-pdr, 2 × 32-pdr carronades | M |
| Complement | 284, later 300 | M |
| Rig | ship | H |
| Speed | "13 knots running large, 10 knots close-hauled"; "unweatherly" against frigates of British lines (Gardiner, via [LEDA]) | M |
Shannon is also the source of the best-recorded single-ship action of the period: it took Chesapeake in 11 minutes (see Pacing).
Brig: the Cruizer class brig-sloop
Source: [CRUIZER], which cites Winfield 2008, pp. 282 and 291.
| Value | Conf. | |
|---|---|---|
| Length overall / keel | 100 ft / 77 ft 3½ in | H |
| Beam / depth in hold | 30 ft 6 in / 12 ft 9 in | H |
| Burthen | 382 bm | H |
| Draught | citation needed | |
| Armament | 16 × 32-pdr carronades, 2 × 6-pdr bow guns, one deck | H |
| Complement | 121 | H |
| Rig | brig: two masts, square-rigged | H |
| Speed | "fast sailers and seaworthy"; no figure | M |
The brig's broadside is all carronade: heavy at close range and short-ranged. That is a real difference between classes, and play should keep it.
Cutter: HMS Surly (1806), Cheerful class
Source: [SURLY], which cites Winfield, British Warships in the Age of Sail 1817–1863, 2014, p. 267 (the later volume). Kept (Marlinspike, 2026-10-06): built in 1806, it is in period; an earlier cutter replaces it only if a better-suited one turns up.
| Value | Conf. | |
|---|---|---|
| Length overall / keel | 63 ft / 46 ft 9⅜ in | M |
| Beam / depth in hold | 23 ft 6 in / 10 ft | M |
| Burthen | 137 bm | M |
| Draught | citation needed | |
| Armament | 10 × 12-pdr carronades, 2 × 4-pdr | M |
| Complement | 50 | M |
| Rig | single-masted, fore-and-aft: citation needed (general knowledge, not yet sourced) | |
| Speed | citation needed |
What each class needs that history doesn't give
These are tuning guesses, set by play, until a source turns up:
- best speed for the Seventy-four, the brig and the cutter;
- draught, used only for drawing and for hit shapes below the waterline;
- the pivot point for turning, and how the yard groups' push divides between bow and stern;
- the hull and rig hit shapes, derived from the particulars above (see Physics: hits).
5. Physics
How the sim works out speed, turning, shot, hits and morale, and where each number comes from. Every quantity below is either cited (source keys in Sources), derived by stated physics from cited quantities, or marked tuning guess or citation needed.
The sim core runs on a fixed step with a seeded random number generator, so the same inputs give the same battle (Architecture). The water is flat for physics; swell is drawn, not simulated.
Speed: the polar
Each class has a polar: its best speed through the water at each angle off the true wind, under full sail, in the engagement's wind. Polars are generated by a small sail-force model and stored as JSON tables, one per rig, so the clean-room check can compare them as tables. The model has few inputs, each with its source:
| Input | Square rig | Fore-and-aft (cutter) | Source |
|---|---|---|---|
| Closest angle at which the sails fill | between 6 points (67.5°) for the best ships and 7 points (78.75°) for most | 4 points (45°) | Willis 2003, H |
| Leeway, close-hauled | about 1 point (11¼°) for most ships; ¼ point for the best | citation needed | Willis 2003, H |
| Close-hauled speed as a share of best | 10 of 13 knots for the frigate's class | citation needed | [LEDA], M |
| Best speed | First Rate "up to 11 knots"; frigate 13 knots running large | citation needed | [VICTORY], [LEDA], M |
| Angle of best speed | tuning guess (wind on the quarter) | tuning guess | |
| Dead before the wind | tuning guess (below best: the after sails blanket the fore) | tuning guess |
Leeway matters: at 7 points close-hauled with a point of leeway, a ship makes good 8 points and gains no ground to windward (Willis 2003). The sim models leeway as a sideways drift, so this comes out of the model rather than being written in.
The frigate's class was "unweatherly" (Gardiner via [LEDA]), so it sits nearer 7 points than 6. Where each other class sits in that range is a tuning guess.
Speed: from polar to speed
- Sail level scales the drive: topsails give a share of full sail's drive (tuning guess), none gives only the drift of the hull and rig.
- Yard angle scales each group's drive by how well it is trimmed to the apparent wind; a group with the wind on the front of its sails drives astern (aback). How hard a ship aback drives astern is a tuning guess.
- Rig damage takes a share of drive per rig hit, for good (Marlinspike, 2026-10-06). The share is a tuning guess (the hit-effect lever, Pacing).
- The ship accelerates toward the speed the sails give, at a rate set by its displacement (burthen, cited per class) and a tuning guess for hull resistance.
Turning
- The rudder's turning force grows with the square of speed through the water (a foil's lift; physics), so a ship with no way on can't steer, and the turn rate grows with speed.
- The turning circle is on the order of a few ship lengths: even the handiest ships of the period "would only wear in four times the ship's length" (Willis 2003, H). Each class's circle is a tuning guess against that anchor.
- The yards turn the ship too. Each yard group's sideways force acts at its mast, forward or aft of the pivot, so it pushes the bow or the stern (physics). This is what makes the age-of-sail tack and a turn from rest possible.
- How fast the helm goes over is a tuning guess.
- Tacking took about 5 minutes for a well-trained crew: citation needed (found only in search summaries). Wearing turned the ship through 20 points, 8 more than tacking (Willis 2003).
Sail handling
- A squadron "made all sail in fourteen minutes"; a lieutenant reckoned "five minutes to strike and stow all of the topgallants and the staysails" in a 90-gun ship (Willis 2004, H). Once the gaskets were off, sail could be set "in a flash".
- These are the historical base for how long sail-level changes take with a full sail crew. The game value comes from the time-scale lever, not from editing them.
- With fewer men at the sail station, handling slows in proportion to men present over men needed (Marlinspike's rule, 2026-09-24; the proportion is a tuning guess).
Guns: rate of fire
- "A typical broadside… could be fired 2–3 times in approximately 5 minutes" ([ARTILLERY], M). "Three broadsides in five minutes were considered to be the mark of a very well worked up ship, and few warships attained such" ([DRILL], M).
- So the historical base for a full crew is 100 s per round for a crack crew, 150 s for a typical one (derived). The game value comes from the time-scale lever.
- Whether bigger guns reload more slowly: citation needed. At launch, every long gun has the same base; carronades are tuning guesses.
Guns: crews
| Gun | Crew | Source |
|---|---|---|
| 32-pdr | 9–14 | [GUN32], M |
| 24-pdr | 12 and a powder boy | [GUN24], [DRILL], M |
| 18-pdr | citation needed | |
| 12-pdr | 8 and a boy | [DRILL], M |
| 9-pdr | citation needed | |
| 6-pdr, 4-pdr | 6 and a boy (6-pdr) | [DRILL], M |
| Carronades | "a much smaller crew"; number citation needed | [DRILL], [CARRONADE] |
A gun with fewer men than its crew reloads more slowly, in proportion (tuning guess).
Guns: the shot
- Each ball weighs its nominal pounds; its diameter follows from the density of cast iron (physics). Check: the 1790s Blomefield 32-pdr had a 6.41 in bore with 0.233 in of windage (McConnell 1988, p. 67, via [GUN32], H), so its ball was the bore less the windage.
- Muzzle velocity: the 32-pdr long gun fired a 10 lb charge at about 487 m/s (Goodwin, via [GUN32], H). Other long guns: tuning guess near that. Carronades used ¼–⅓ of the long gun's charge ([CARRONADE], M); their velocity is derived from the charge (physics), then tuned.
- Flight: under gravity, with air drag on a sphere (physics). The drag
coefficient is a tuning guess, set so these ranges come out:
- 32-pdr long gun, extreme range about 2,000 yd ([BROADSIDE], M);
- 68-pdr carronade, 1,280 yd at 5° elevation with a 5 lb charge ([CARRONADE], M);
- a 24-pdr carronade's point-blank range "only about 218 yards" (Douglas 1829, pp. 118–19, H).
- Laying: the crew sets elevation for the range to the target and aims where it is now, with no lead (Marlinspike, 2026-09-24), plus dispersion. Dispersion grows with range and is the accuracy lever's job (tuning guess). Roll, heel and ricochet are left out.
- Maximum range is where maximum elevation stops reaching (Marlinspike, 2026-09-24). Maximum elevation is a tuning guess, set to give the cited extreme ranges.
- Battle ranges for context: decisive actions were "generally fought at ranges under 100 yd" ([CARRONADE], M); a pistol shot was 25–30 yd, a musket shot about 200 yd, a "gunshot" about 1,000 yd ([BROADSIDE], M).
Hits
- Hit shapes (Marlinspike, 2026-09-27): each ship's hull shape is built from its cited length, beam and height of side; its rig shape from its masts and sail area. Neither depends on the drawn model, and a test enforces that.
- Hull hits: a ball either goes through the side or glances off. Whether it goes through depends on its speed at impact and the angle of the hit; side thickness is citation needed, so the threshold is a tuning guess. A ball that goes through causes casualties in proportion to its path inside the hull (Marlinspike, 2026-09-24), times the crew's density (complement over the hull's volume), times the hit-effect lever. So a rake, end to end, is the great killer, and a full ship suffers more per hit than a short-handed one.
- Rig hits hole the sails and take a share of drive (see Speed).
Morale
- Morale falls with casualties, as a share of the complement, and recovers in lulls (Marlinspike, 2026-09-24).
- The historical base for breaking: the losing British ships in four single-ship actions of 1812–13 struck at roughly 29–38% killed and wounded (computed from the figures in [GUERRIERE], [MACEDONIAN], [JAVA], [CHESAPEAKE]; no source states a rule). The trigger was more often dismasting or an unanswerable rake than a set loss. So the base breaking point is about a third of the complement, and the breaking-point lever tunes it.
- At Trafalgar, Redoutable struck "with 99 fit men out of 643" ([TRAFALGAR], H): a ship could fight far past the base. Marlinspike may want captains or crews that do (officers, later).
- Recovery in lulls is a tuning guess, and must stay slower than the slowest reload (the consistency rule in Pacing).
6. Pacing
"I loved the idea of pacing and testing of pacing and making adjustments accordingly" (Marlinspike, 2026-10-06). Pacing is a design principle: how long fights last is measured, given a target, and adjusted by a few known levers, never by editing ship data.
History as the anchor
Real actions ran from minutes to hours. These are the anchors the time scales start from:
| Action | Duration | Losses, killed / wounded | How it ended | Source |
|---|---|---|---|---|
| Shannon vs Chesapeake, 1 June 1813 | 11 minutes | Shannon 23 / 56; Chesapeake about 60 / about 60 of 379 | boarded and carried | [CHESAPEAKE], M |
| Constitution vs Guerriere, 19 Aug 1812 | about 15 minutes of close broadsides | Constitution 7 / 7; Guerriere 15 / 78 of 272 | all three masts gone | [GUERRIERE], M |
| United States vs Macedonian, 25 Oct 1812 | about 3 hours | United States 7 / 5; Macedonian 43 / 71 of 301 | dismasted | [MACEDONIAN], M |
| Constitution vs Java, 29 Dec 1812 | about 3 hours from sighting | Java 22 / 102 of 426; Constitution 9 / 57 | dismasted, about to be raked | [JAVA], M |
| Glorious First of June, 1794 | about 3–3½ hours of main action | about 1,200 British | 7 French ships of the line taken | [FIRSTJUNE], M |
| Trafalgar, 21 Oct 1805 | about 5¾ hours (11:50 to 17:30) | British 458 / 1,208 | 17 ships taken, one burning | [RMG], [TRAFALGAR], H |
A close frigate action could be decided in a quarter of an hour; manoeuvring to it took hours. The game compresses the manoeuvring far more than the fighting.
Targets
Set later by Marlinspike, possibly more than one: a first-rate's fight may run longer than a cutter's. Whether a target fails the test suite is decided when it is set. Until then the pace tool reports and nothing fails on time.
The pace tool
Built from the start, alongside Studio. It runs fights headless and deterministically, for every pair of the five classes (ten class pairs, each fought both ways where sides matter) over fixed seeds and set scenarios, and reports how long each took and what each side lost, against the targets once they exist.
The four levers
Pacing is adjusted only through these, kept in one file:
- Time scales: reload, crew movement between stations, sail handling. Symptom it fixes: everything is too slow, or too fast, overall.
- Accuracy: what share of a broadside hits, by range. Symptom: nobody hits, or every shot hits.
- Hit effect: casualties per hull hit, drive lost per rig hit. Symptom: fights are too bloody, or hits do too little.
- Breaking point: the losses that make a ship strike, and how fast morale recovers. Symptom: ships strike too soon, or fight to the last man.
Each lever has a global value and optional per-class overrides, so classes can have different targets without forking the model. Naming the symptom first stops pulling whichever knob is nearest.
The log
Every lever change is logged with the pace tool's report before and after, on the same seeds, and its reason. A lever change with no log entry fails review.
Consistency rules
Tests between levers, run with the suite:
- Morale recovery is slower than the slowest reload. When it wasn't, a frigate duel ran 51 minutes to 95% casualties (rebuild plan, 2026-10-06).
- More may be added as play finds them; each comes with the fight that showed the need.
7. Architecture
The shape of the code. These are lessons stated as design (rebuild plan, 2b), not a description of any earlier code. Where a choice is mine rather than the plan's, it says "proposed".
Stack
- Plain ES modules in the browser, no build step. The served files are the source files.
- Types without a build:
// @ts-checkand JSDoc in every module, withtsc --noEmitrun as part ofnpm test. - 3D with three.js, vendored into the repo and served from it, never from a CDN (proposed).
- Tests with
node --test, beside each module from its first commit. - The site around the game stays plain PHP.
One pure sim core
- No DOM, no clock, no
Math.random. The core advances by a fixed step and draws every random number from a seeded generator it is handed. The same seed and the same commands give the same battle, every time. - The same core runs everywhere: in the browser, in the pace tool, in Studio, and later in a room server. Nothing outside the core repeats its logic.
- A size budget of about 400 lines per module. A module that grows past it is split by responsibility, not by line count.
One command layer
- Keyboard, mouse, station bar, NPC captain, and later the network, all issue the same commands to a ship: helm, sail level, brace a yard group, auto-trim, a gun side's order (Stand Down, Load, Fire at Will), signal. A command is plain data.
- A captain can do nothing a player can't, because it has no other way to act.
- Commands are applied at step boundaries, so a recorded list of commands and a seed replays a battle exactly. That record is also what Studio and the tests use.
One ship-state shape
- The core owns ship state. Renderers and the HUD only read it; they never write it or keep their own copy of anything the sim decides.
- Hit shapes are separate from the drawn model, and a test enforces that changing the drawn model can't change a fight (Marlinspike, 2026-09-27).
Ships as data, with a schema
- Each class is a data file. A schema, checked in
npm test, requires that every value carries its historical base and citation, and its game value and tuning reason where they differ, or is marked a tuning guess. - Field names are chosen fresh for this game and recorded in the schema.
- Polars live in JSON tables generated by the sail-force model (Physics), with the model's inputs and their citations stored beside them.
- The global time scales and the four pacing levers live in one file, not spread across modules (Pacing).
Every tunable stat is derived
- A stat's effective value is its base value with a list of modifiers applied. Each modifier names the stat, how it changes it (multiply or add), and where it came from.
- The core reads only effective values. A test enforces that no module reads a base stat directly.
- This is the hook for officers (later: collectable cards based on historical warrant and petty officers, Marlinspike, 2026-10-06). An officer is a set of modifiers attached to a ship, so the core never knows about cards. Morale, rig damage and later weather use the same hook.
Studio
- Studio stages scenes and writes stills and video, for us first: devlog images, video and promotion (Marlinspike, 2026-10-06). It may open to players after launch.
- A scene file names the ships, the commands over time and the camera, and a seed. It is the record of the asset; published videos live in the repo with their scene (Marlinspike, 2026-10-03).
- Studio runs the same core and the same step loop as play, never its own copy of the captain or anything else (Marlinspike, 2026-10-03). Captains sail by default; ships can be frozen.
- It renders through the game's own 3D view in a headless browser, MP4 with no sound (proposed: the only way to get pictures identical to play). A screen mode shoots the real page with its HUD, for guide pictures.
- Because the core is deterministic, a scene doubles as a regression test: the same scene must put the same ships in the same places.
Tests from the first commit
- Each module has its tests beside it.
- The schema check for ship data, the derived-stat check, the hit-shape check, and the pacing
consistency rules all run in
npm test. - A test that no served file names another game (Marlinspike, 2026-09-24).
bin/cleanroom_check.shruns from the projects root, outside this repo, before each commit of data or sim code is pushed.
Layout (proposed)
www/ the docroot (as now)
play/ the game page and its modules
core/ the sim core: no DOM
view/ 3D view, HUD, menus: read the core's state
input/ keyboard, mouse, station bar: issue commands
data/ ship classes, polars, levers (JSON)
spec/ this spec
vendor/three/ three.js, vendored
tools/ pace tool, Studio, polar generator: run the core under Node
test/ or beside each module; decided with the first module
8. Sources
Every source cited in this spec. Pages marked fetched were read on 2026-10-06; books and articles marked read were read in full text. Nothing here comes from a game or game data.
Web pages (fetched 2026-10-06)
| Key | Page | What it cites |
|---|---|---|
| [VICTORY] | HMS Victory | Goodwin; Lavery; Winchester |
| [ARROGANT] | Arrogant-class ship of the line | Winfield 2007, pp. 64, 77; Lavery 1984, p. 176 |
| [SHANNON] | HMS Shannon (1806) | Winfield 2007 |
| [LEDA] | Leda-class frigate | Winfield 2007; Gardiner 2000 |
| [CRUIZER] | Cruizer-class brig-sloop | Winfield 2008, pp. 282, 291 |
| [SURLY] | HMS Surly (1806) | Winfield 2014, p. 267 |
| [ARTILLERY] | Naval artillery in the Age of Sail | |
| [GUN32] | 32-pounder gun | Goodwin, HMS Victory Pocket Manual; McConnell 1988 |
| [GUN24] | 24-pounder long gun | |
| [CARRONADE] | Carronade | |
| [DRILL] | navyandmarine.org: gun drill | |
| [BROADSIDE] | nelsonsnavy.co.uk: broadside | |
| [GUERRIERE] | USS Constitution vs HMS Guerriere | |
| [MACEDONIAN] | USS United States vs HMS Macedonian | |
| [JAVA] | HMS Java (1811) | |
| [CHESAPEAKE] | Capture of USS Chesapeake | |
| [TRAFALGAR] | Battle of Trafalgar | Goodwin; Adkins |
| [FIRSTJUNE] | Glorious First of June | |
| [RMG] | rmg.co.uk, the Trafalgar timeline |
Books and articles
- Willis 2003: Sam Willis, "The Capability of Sailing Warships, Part 1: Windward Performance", The Northern Mariner XIII no. 4 (2003), pp. 29–39. Read.
- Willis 2004: Sam Willis, "The Capability of Sailing Warships: Manoeuvrability", The Northern Mariner XIV no. 3 (2004), pp. 57–68. Read.
- Douglas 1829: Sir Howard Douglas, A Treatise on Naval Gunnery, 2nd ed., 1829 (archive.org scan). Pp. 118–19 read; Tables VIII and XV (pp. 294, 302) unreadable in the OCR, to be checked against page images.
- Cited through the pages above, not read directly: Rif Winfield, British Warships in the Age of Sail 1714–1792 (2007), 1793–1817 (2008) and 1817–1863 (2014); Robert Gardiner, Frigates of the Napoleonic Wars (2000); Brian Lavery, The Ship of the Line (1984); Peter Goodwin's works on Victory; McConnell 1988.
Looked for, not found
- Draught for the Seventy-four, frigate, brig and cutter.
- Recorded speeds for the Seventy-four, brig and cutter.
- Crew per gun for the 18-pdr and 9-pdr, and for carronades.
- A sourced tacking time.
- John Harland, Seamanship in the Age of Sail (1984): not reached; nothing from it is used.
- Range-by-elevation tables with a reliable source (two uncited pages give them; not used).
Not used
- A search summary crediting a 3½-minute broadside to Collingwood "in 1812". Collingwood died in 1810.
9. Later and dropped
Later (Marlinspike, 2026-10-06, plus sound the same day): staysails; shifting wind and a building sea; grounding; the brigantine, launch and jolly boat; chain and double shot; dismasting; range rings; the ship's boat, prizes by boarding, and taking to the boat when struck; crew carried between battles; crew figures; drawn signal flags; real-nation ensigns; multiplayer rooms; all of Corona del Mar; carved ends; telescope; minimap; shipyard pages; tutorials; sign-in and saved progress; a welcome video; gun sound.
Dropped (Marlinspike, 2026-10-06): riding as a passenger on an ally's ship; the explored chart; the 2D chart view; frame reports; any tool that builds numbers from another game's data; the inherited admin, dossier, rank, register and decoration pages.
10. Open for Marlinspike
Nothing open: all eight items were decided by Marlinspike on 2026-10-06.