1. High-level architecture

┌────────────────────────┐         WebSocket (JSON)         ┌──────────────────────────┐
│  Browser client (JS)   │  ── ClientMessage ───────────▶   │     Rust server          │
│  PixiJS renderer        │                                  │  axum + tokio            │
│  - lobby UI             │  ◀─ ServerMessage ──────────     │  - static file serving   │
│  - input / selection    │                                  │  - /ws upgrade           │
│  - camera / minimap      │                                  │  - Lobby (rooms)         │
│  - fog overlay (local)   │                                  │  - Game (authoritative)  │
└────────────────────────┘                                   └──────────────────────────┘

Compatibility policy

The game is pre-alpha and latest-version-only. Do not preserve obsolete protocol, replay, client/server, map, or asset behavior just for backwards compatibility unless a specific migration or debugging workflow requires it. Breaking changes are acceptable when the design docs and all current Rust/JS mirrors are updated together.

Workspace crate boundaries

The Rust server workspace is split by dependency direction. Lower crates must not depend on higher crates:

rts-server  -> rts-ai, rts-sim, rts-rules, rts-protocol, rts-contract
rts-ai      -> rts-sim, rts-rules, rts-protocol, rts-contract
rts-sim     -> rts-rules, rts-protocol, rts-contract
rts-protocol -> rts-contract
rts-rules
rts-contract

rts-server is the only crate that may own Axum/Tokio WebSocket/static-file serving and lobby room tasks. rts-sim owns Game, tick systems, deterministic replay, map/fog/entity state, and simulation perf accounting without importing server transport. rts-ai owns live controllers and self-play harnesses and drives the sim only by observing snapshots and enqueueing ordinary SimCommands. rts-rules owns pure vocabulary, balance data, terrain, economy, and combat formulas. rts-protocol owns serde wire DTOs and compact snapshot transport. rts-contract owns shared semantic DTOs that are below the wire and sim layers.

The server wiki belongs to rts-server because it is an Axum route and because generated reference HTML is a presentation of lower-crate data. Wiki prose comes from repository Markdown files; wiki stats rows come from rts-rules definitions and faction catalogs. After changing docs links, allowlisted docs, rules definitions, faction catalogs, upgrades, or ability metadata, run node scripts/check-wiki.mjs to cover route safety, link integrity, generated table completeness, and client catalog parity.

scripts/check-crate-boundaries.mjs enforces the implemented Cargo package graph and rejects server-only imports in lower crates. Any intentional graph change must update this section, the script, and the affected context capsule in the same change.

Tick & networking model