Skip to content

Cuttle

Cuttle is a strategic card-combat example: players race to 21 points while playing point cards, permanents, one-offs, counters, and scuttles. The canonical rules live in the framework-agnostic examples/cuttle/CuttleGame.ts, whose state is a plain mutable object and whose public interface includes getValidActions(player) and getObservation(player).

Run it

npm run cuttle
node --loader ./test/ts-esm-loader.js examples/cuttle/cli.js --variant standard
node --loader ./test/ts-esm-loader.js examples/cuttle/cli.js --variant cutthroat

npm run cuttle:server       # authoritative room server
npm run cuttle:client       # client (use another terminal)

For the browser UI, open examples/cuttle/web/index.html with a static server. For serverless CRDT play, run a relay (npm run relay, on the configured port) and use:

npm run cuttle:crdt:host
npm run cuttle:crdt:client

Three integration modes

The local CLI calls CuttleGame.action(player, command) after checking the valid-action list. The authoritative server binds cuttle:* actions to a RoomAuthoritativeServer, projects per-player state, and serializes room dispatches. The CRDT client writes a sanitized snapshot under doc.cuttle and uses ConsensusCore for sync. Those modes share rules but are not identical state backends.

The CRDT mode encrypts private hands for their recipients, stores deck commitments, and uses expectedTurnNumber to reject stale actions. Opponents receive observations and counts, not another player's plaintext hand. Cuttle's encrypted mode deliberately has an honest dealer: commitments detect card substitution, but do not prove a fair shuffle or prevent a dealer from biasing the deal. Generic network E2E is not automatically enabled by the relay.

Variants and tests

Classic is the two-player default. Standard changes several card effects; cutthroat adds three-player rules and Jokers. The encrypted CRDT scope is classic two-player only. Relevant checks are:

npm run test:cuttle:sync
npm run test:cuttle:crypto
npm run test:cuttle:hardening