Skip to content

Messaging & NATS

The cluster's bus is NATS. Every inter-crate call rides a NATS subject; the gateway is the only crate that speaks the WoW wire protocol directly.

Envelope

Messages are JSON with hex-encoded binary packets:

{
  "session_id": "…",
  "opcode": "CMSG_CAST_SPELL",
  "payload_hex": "0a1b2c…",
  "ctx": { "map_id": 0, "instance_id": 1 }
}

The hex encoding keeps NATS payloads valid UTF-8 for tooling without giving up the original byte layout — handlers decode hex back to bytes before parsing.

Subjects

Subjects are namespaced by feature and direction:

  • world.<map_id>.<instance_id>.in — gateway → world
  • world.<map_id>.<instance_id>.out — world → gateway
  • guild.req, guild.resp — guild RPC
  • social.chat.in, social.chat.out — chat fan-out
  • auction.req, auction.resp — AH RPC
  • orchestrator.spawn, orchestrator.drain — instance lifecycle

Each crate's lib.rs declares the subjects it owns; splintertree-common exposes the envelope types.

Queue groups

Crates that scale horizontally subscribe to their subjects through a queue group so NATS load-balances messages across replicas. The orchestrator, the matchmaking service, and the web API are deployed this way.

JetStream

Durability-sensitive subjects (audit, ticket, mail) use JetStream streams so messages survive subscriber restarts. Ephemeral RPC subjects (most game traffic) stay on core NATS for lower latency.

Observability

Every NATS publish increments a Prometheus counter labelled by subject. The Grafana dashboard ships under monitoring/ in the repository.