Authoritative dungeon hostHerbmail Server
The authoritative shared-world host for Herbmail — an axum WebSocket router paired with the simgrid headless Bevy simulation on tokio, with guest and Supabase-account admission.
Seed-derived world
The dungeon is a pure function of DUNGEON_SEED and is never transmitted. Server and client each derive it, pinned against shared parity vectors.
- Auth — Supabase JWKS (HS256 + ES256) or server-minted guests.
- Lifecycle — Agones Ready / Health / Shutdown.
What it gives you
Features
Terminate /ws + admit
Terminates the WebSocket upgrade and admits either a Supabase-verified account or a server-minted guest identity.
Drive the sim tick
Runs the simgrid sim tick at 20 Hz on a tokio multi-thread runtime, fanning out authoritative 10 Hz snapshots.
Derive, never transmit
The dungeon is generated from a seed on both sides and pinned by parity vectors, so no geometry crosses the wire.
Agones lifecycle
Runs the Agones SDK lifecycle (Ready / Health / Shutdown); degrades gracefully outside Agones for local dev.
Responsibilities
Overview & layout
herbmail-server is the authoritative shared-world host for the Herbmail dungeon crawler. It pairs an axum WebSocket router with the simgrid headless bevy simulation, so movement validation and snapshot framing stay server-owned.
Responsibilities
Section titled “Responsibilities”- Terminate the
/wsWebSocket upgrade and admit either a Supabase-verified account or a server-minted guest. - Drive the
simgridsim tick (20 Hz) on a tokio multi-thread runtime, fanning out 10 Hz snapshots. - Derive the dungeon from
DUNGEON_SEEDrather than transmitting it, byte-identically with the client. - Run the Agones SDK lifecycle (
Ready/Health/Shutdown); degrades gracefully outside Agones for local dev.
Deployment
Fleet & routing
An Agones Fleet in the herbmail-game namespace runs the GameServer pods behind a ClusterIP Service with sessionAffinity: ClientIP, reached through the Cilium gateway on game.herbmail.com. The autoscaler is pinned to a single replica: a Service round-robins, and multiple Ready pods would split players across separate worlds.
There is no UDP lane. The Herbmail client is browser-only and cannot open a raw UDP socket, so only the TCP WebSocket port is exposed.
Guest identities
Section titled “Guest identities”A connection presenting an empty token is admitted as guest-NNNN, minted by the server. The client cannot choose its own guest name — the name a player sees comes back in Snapshot.players, keyed by the slot in Welcome. Account names carrying the guest- prefix are rejected outright, so a guest can never present as a signed-in player.
Not yet authoritative
Section titled “Not yet authoritative”The server does not yet reproduce the client’s seed-derived walls; it runs an open map and logs authoritative_collision=false. Collision arbitration waits on the geometry port and its parity harness.
Questions
Frequently asked
What is the Herbmail server?
herbmail-server is the authoritative shared-world host for the Herbmail dungeon crawler. It pairs an axum WebSocket router with the simgrid headless Bevy simulation on a tokio multi-thread runtime, keeping movement validation and snapshot framing server-owned.
Can players join without an account?
Yes. When guests are enabled the server mints its own guest identity for a connection that presents no token, so the client can never choose its own guest name. Signed-in players are verified against Supabase via the jedi JWKS verifier, which accepts both HS256 and ES256.
Is the server authoritative over collision yet?
Not yet. The dungeon is a pure function of a seed and is never transmitted, so the server must derive byte-identical geometry before it can arbitrate walls. Until that port lands the server logs authoritative_collision=false and runs an open map.