Watershed¶
Watershed is the pure CRDT showcase: a real-time territory game with no turns, no hidden information, and no authoritative game server. Players place, merge, and split tokens concurrently. The board is derived from active token records, so two valid writes to one cell remain a contested cell rather than a last-write-wins replacement.
Run it¶
npm run relay
# in another terminal
npm run watershed:web
The web script builds the bundle and serves it on http://localhost:8080.
The browser client defaults to the relay URL documented by the example; adjust
the client configuration when the relay is elsewhere.
Rules and sync tests are available directly:
npm run test:watershed:rules
npm run test:watershed:sync
State model¶
doc.watershed.tokens is a token map. Parent tokens are never deleted: actions
record tombstones in consumed and create children with _mergedFrom or
_splitFrom provenance. deriveBoard() and scoring materialize a plain clone
before inspecting state, avoiding Automerge proxy pitfalls. Energy is partly
derived from stored energy and elapsed time; lobby presets select energy and
duration.
The action surface is watershed:init, register, start, place, merge,
split, and end, dispatched through the TypeScript ActionRegistry. Handlers
validate phase, bounds, registration, energy, adjacency, and strength before
field-level writes. ConsensusCore exchanges sync blobs through the relay;
peers converge, but the relay does not decide which placement is legal.
Caveats¶
Watershed intentionally has no secrecy and no global turn arbitration. A modified client can attempt invalid writes, and concurrent valid actions may produce contested state that the game must score explicitly. The example is a good fit for collaborative, merge-friendly play—not for games requiring a trusted referee, private decks, or strict serial transactions.