Berthier

For Programmers

Berthier is a single-file React application, about five and a half megabytes, with no build step: it runs in a browser from a web server or from a local file, compiling its own JSX at load. Online play goes through a small Node.js WebSocket relay.

Architecture

The umpire’s browser holds the true state of the campaign. Players never receive it: the relay carries per-role packets that the umpire filters down to what each commander could know, so fog of war is enforced by what is sent, not by what is hidden in the interface. Assistant umpires are assigned players or team colours and take full responsibility for that traffic; if one drops, their players fall back to the head umpire automatically, and hosting can be handed over mid-game. The intelligence tables for a campaign, including the planted false reports, are kept outside the served directory and reach the umpire over the relay socket; the relay refuses any request that would name an intelligence file.

Maps

The campaign maps are period sheets. A companion tool, the pixel mapper, traces towns, roads and rivers on scanned historical maps, georeferences them, and exports the road graph the engine uses for movement and courier travel.

How it is kept honest

Every change is made by a script that checks the code it expects to find before it touches anything, keeps a pre-image, and can be run again safely. About three hundred regression harnesses gate each change. The 1809 Danube scenario, which carries a great deal of hand-built work, is pinned byte-identical: its starting state and a scripted day of play are replayed with randomness stubbed and must match exactly. Every file in the working tree is recorded in a hash ledger, so any copy can be checked against the record.

A.I.-assisted development

Berthier was developed over several hundred working sessions with Claude (Anthropic) as the principal coding assistant, writing code under the author’s direction and review. The test harnesses, the patch-script discipline and the hash ledger exist partly for that reason: code a person did not type line by line has to be proved, not trusted.