A practical orientation for working in the Sovereign Storm codebase: how to run it, host a session, and verify changes. The canonical source is the main repository at github.com/blamechris/sovereign-storm.
See also: Architecture · Game Design.
Prerequisites
- Node.js and pnpm — this is a pnpm workspace monorepo; use
pnpm, nevernpmoryarn. - For cross-network hosting: cloudflared on your PATH.
Running locally
pnpm install
pnpm dev # runs the server and client concurrently- Server:
http://localhost:2567 - Client:
http://localhost:5173
Every mode is playable solo against bots, so you can exercise the full loop without a second person.
Common commands
| Command | What it does |
|---|---|
pnpm dev | Server + client concurrently for local development. |
pnpm build | Builds in dependency order: shared, then server, then client. |
pnpm typecheck | Runs the TypeScript compiler across every package. |
pnpm test | Runs the unit and in-process end-to-end tests per package. |
pnpm e2e | Runs the Playwright browser end-to-end suite. |
pnpm host | Builds and serves the app behind a Cloudflare quick tunnel (see below). |
Hosting a session for friends
pnpm hostThis builds the client, starts the production server (which serves the single-page app and the WebSocket on the same port), and opens a Cloudflare quick tunnel so the game is reachable from outside your network. It prints a shareable trycloudflare.com URL. The tunnel lives as long as the terminal runs; quick tunnels are anonymous and short-lived, so re-run pnpm host for a fresh URL when one expires. This keeps casual co-op zero-config — no deployment, no accounts.
Testing philosophy
Automated tests cover two layers:
- Unit and in-process end-to-end tests exercise the shared validators, the resolver pipeline, and per-feature behavior through the game room. Determinism of the round resolver is itself tested.
- Playwright end-to-end specs drive the real browser client.
Because the resolver is the heart of the game, anything touching round resolution warrants both the automated suite and a manual smoke pass. A manual smoke checklist in the main repo walks the full loop — local solo, cross-network hosting, mobile, and targeted scenarios like reconnection and the custom map maker — and is the durable form of “does it actually play in a real browser.”
Code conventions
- Branch from the default branch, develop, keep the typecheck and relevant tests green, then open a pull request — never commit directly to the default branch.
- Commit format:
type(scope): summary. Types includefeat,fix,refactor,docs,test,chore,perf; scopes includeclient,server,shared,lobby, and others. - TypeScript strict mode is enforced; keep the typecheck clean per change.
Extension surface
The architecture is built so most additions are data plus a small, well-located edit, not engine surgery:
| You want to add… | Where it tends to go |
|---|---|
| A new vessel tuning or gameplay constant | the shared package constants |
| A new match mode | a new strategy entry implementing the common mode interface |
| A new themed expedition (Odyssey-style) | data bundles: map pack, enemy roster, sector data, lore voice |
| A new client message / protocol field | a message constant + validator in shared, handled in the room |
See Architecture for the package boundaries that make this possible.