Wiki · main

coworld-mtg

Last edited by · ·

coworld-mtg

Magic: The Gathering as a Coworld: a Rust game named coworld-mtg, packaged behind the Coworld container contract so LLM agents can play MTG in local episodes, browser play, and hosted leagues with replays, scoring, and baseline players.

The original shared-tabletop prototype has been removed in favor of the pinned, Rust-native Phase rules engine so that mana, casting, priority, the stack, combat, triggers, replacements, layers, and state-based actions are engine-enforced. See the Phase port contract for the decision, Scryfall boundary and invariants.

Browser player, spectator, and current replay routes use the React client from that same pinned Phase revision. This repository adds only a thin Coworld transport/replay adapter and series chrome; the former local renderer is built only to keep version-2 Coworld replays readable. See the client migration spec.

The tracked web/ application is frozen compatibility code for version-2 replays. New player, spectator, and replay work belongs in phase-client/.

Development checks

Rust commands should run through scripts/cargo.sh; it selects the toolchain in rust-toolchain.toml even when another cargo or rustc appears earlier on PATH. Run the complete local/CI gate with:

scripts/check.sh

Generated Rust and frontend output can consume many gigabytes. Preview guarded cleanup with scripts/clean-generated.sh --all; add --execute only after reviewing the resolved paths and sizes it prints.

Fidelity harness

coworld-mtg-harness runs seeded games directly against phase-bridge, records exact actions, authoritative events, canonical state hashes, and RNG-preserving checkpoints, then replays every trace as a hard determinism gate. It also materializes hash-verified Phase/Scryfall/MTGJSON/17Lands artifacts, mines 17Lands only into soft workload signals, resumes deterministic seed shards, and deduplicates findings into a scoreboard.

See the harness operations guide for corpus, worker, replay, minimization, and aggregation commands.

Private runtime corpus

The generated Phase card database and 17Lands-derived deck lists are not distributed in this public repository. Authorized Softmax builds fetch the content-addressed private corpus pinned by corpus.lock.json:

scripts/fetch-corpus.sh

This materializes .private/corpus, verifies the archive and every contained file by SHA-256, and leaves all corpus content gitignored. Docker builds require that materialized directory. Public source builds remain available without it; run tests requiring real card data with scripts/cargo.sh test --workspace --features private-corpus-tests.

Play locally

From the repo root:

npm install
npm run build
scripts/fetch-corpus.sh
scripts/cargo.sh build -p coworld-mtg-server -p goldfish
mkdir -p tmp/local-play
cat > tmp/local-play/config.json <<'JSON'
{
  "tokens": ["tokA", "tokB"],
  "players": [{"name": "browser-0"}, {"name": "browser-1"}],
  "seed": 4242,
  "decks": ["lorehold_excavation", "fractal_convergence"],
  "games_to_win": 1,
  "clock_s": 360,
  "decision_cap_s": 30,
  "player_connect_timeout_s": 60
}
JSON
COGAME_HOST=127.0.0.1 \
COGAME_PORT=8080 \
COGAME_CORPUS_DIR="$PWD/.private/corpus" \
COGAME_CONFIG_URI=tmp/local-play/config.json \
COGAME_RESULTS_URI=tmp/local-play/results.json \
COGAME_SAVE_REPLAY_URI=tmp/local-play/replay.json \
COGAME_LOG_URI=tmp/local-play/log.txt \
COGAME_WEB_DIST="$PWD/web/dist" \
scripts/cargo.sh run -p coworld-mtg-server

Open these URLs in separate browser profiles (for example, a normal and an incognito window) to control both seats:

  • http://127.0.0.1:8080/client/player?slot=0&token=tokA
  • http://127.0.0.1:8080/client/player?slot=1&token=tokB

To play against the baseline instead, leave the second browser closed and run:

scripts/cargo.sh run -p goldfish -- --url 'ws://127.0.0.1:8080/player?slot=1&token=tokB'

The supplied decks are real 40-card SOS.PremierDraft lists captured from MTG Arena play data by 17Lands and supplied through the private runtime corpus. Published play consists of two single-game variants with deck assignments reversed, so each challenger pilots Lorehold Excavation and Fractal Convergence once. Published variants omit seed, which generates a fresh root seed when the episode config is loaded. Supply seed explicitly, as in the local example above, to reproduce the exact initial library orders and all later random outcomes.