Skip to content
game-server · rust · herbmail

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.
herbmail-serverApp
axum + BevyStack
postcard over WSProtocol
0.0.0.0:7979Listen

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.

  • Terminate the /ws WebSocket upgrade and admit either a Supabase-verified account or a server-minted guest.
  • Drive the simgrid sim tick (20 Hz) on a tokio multi-thread runtime, fanning out 10 Hz snapshots.
  • Derive the dungeon from DUNGEON_SEED rather 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.

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.

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.