# CrashNet Server 1.45.0

A headless WebSocket server that runs a CrashBASIC program and streams its
graphics/audio commands to connected clients over a typed protobuf channel.
The server is the source of truth in CrashNet multiplayer.

This package contains two binaries:

- `crashnet-server` — the headless CLI (use for systemd / Docker / scripted
  deployments).
- `crashnet-server-launcher` — an egui-based GUI that wraps the CLI with a
  settings form and a live log panel. Double-click on macOS / Windows;
  `./crashnet-server-launcher` on Linux.

## Quick start (CLI)

Place your game in a folder (or a `.crashcart` bundle) and run:

    .\crashnet-server.exe path/to/game_folder

By default it listens on `127.0.0.1:9005` for everything — WebSocket
(`/ws`), admin UI (`/admin`), and cart-download endpoints all share
this single listener. Point a CrashPlayer at it with:

    crashplayer --remote ws://localhost:9005/ws --name "Player1"

## Quick start (GUI launcher)

Run `crashnet-server-launcher` (no arguments). The launcher persists your
settings to `~/.config/crashbasic/crashnet-server-launcher.json`, so the
next time you open it the form is pre-filled. Pick a game folder, hit
**Start**, and the live server log streams into the bottom panel.

## Common options

| Flag                         | Description                                |
|------------------------------|--------------------------------------------|
| `-a, --addr <host:port>`   | WebSocket bind address (default 127.0.0.1:9005) |
| `-m, --max-players <N>`    | Max players per room (default 4)           |
| `-s, --simulation`         | Skip JWT auth — **local testing only**     |
| `--jwt-secret <SECRET>`    | HS256 secret for JWT validation            |
| `-g, --game-dir <DIR>`     | Game directory (alt to positional)         |
| `-p, --player-dir <DIR>`   | Serve WASM CrashPlayer from this directory |

## Environment variables

| Variable                   | Equivalent flag                |
|----------------------------|--------------------------------|
| `CRASHNET_JWT_SECRET`    | `--jwt-secret`               |
| `CRASHNET_MAX_PLAYERS`   | `--max-players`              |
| `CRASHNET_SIMULATION`    | `--simulation`               |
| `CRASHCORE_ADDR`         | `--addr`                     |
| `CRASHNET_WEB_DIR`       | `--player-dir`               |

## JWT token shape

Production deployments validate JWTs issued by the CrashBasic Arcade:

- Algorithm: HS256
- Issuer: `crashbasic-arcade`
- Audience: `crashbasic-client`
- Required claim: `features.crashnetMultiplayer = true`

Client URL: `ws://host:port?token=<JWT>&name=<display name>`

For local testing, pass `--simulation` to bypass JWT entirely.
