Backend Stack & Server Implementation
1. Summary
Flatland3’s backend is a Rust workspace with a hybrid protocol: binary streaming for real-time sim, HTTP/JSON for agent-facing ops. Durable state lives in PostgreSQL; hot ephemeral state in Redis. The gateway and region worker run as separate processes connected by an internal wire protocol (FL3W postcard over TCP). QUIC lands in a later phase.
See 22-runtime-architecture-and-implemented-features.html for process diagrams and per-feature status.
2. Rust workspace
flatland3/
├── crates/
│ ├── protocol/ # Wire types, postcard codec, version envelope
│ ├── sim/ # Tick loop, AOI, movement (no I/O)
│ ├── region-worker/ # Owns RegionSim @ 30 Hz
│ ├── gateway/ # Client terminate → region route (QUIC later)
│ └── client-lib/ # Bot + future TUI helpers
├── tools/
│ └── bot-harness/ # `flatland-bot` load harness
├── assets/world/segments/ # Seed + authored segments (YAML)
└── migrations/ # sqlx migrations (Phase 2)
Implemented (Phase 1 spike): protocol, sim, region-worker, gateway, client-lib, bot-harness, starter-plains segment.
Next crates: control-plane, world-build, region-orchestrator.
3. Database strategy
| Store | Role | Examples |
|---|---|---|
| PostgreSQL | Canonical durable state | Accounts, characters, inventory, banks, brokers, cartography, unique items, audit log |
| Redis / Valkey | Ephemeral + coordination | Sessions, gateway routing table, rate limits, deploy pub/sub, split/merge locks |
| Object storage | Large blobs | Segment terrain layers, schematic bundles, deployment artifacts |
Rules:
- Economy and unique-item mints require ACID — Postgres only.
- Chunk terrain at runtime is in-memory on region workers, loaded from deployed manifest — not queried per tick.
- sqlx + migrations; SQLite DSN for local single-process dev.
4. Communication protocols
4.1 Client ↔ gateway (game)
| Channel | Phase 1 | Phase 2+ | Format |
|---|---|---|---|
| Session | In-process / local | QUIC (quinn) | Versioned envelope |
| Tick stream | Tokio channel | QUIC unreliable stream | postcard |
| Intent channel | Tokio channel | QUIC reliable sequenced | postcard |
| Bulk snapshot | On connect | QUIC reliable | postcard + zstd |
Codec decision (benchmarked): postcard v1 — smaller payloads than bincode for TickDelta, serde-native, fast enough for 100×15 entities @ 30 Hz. Revisit FlatBuffers if encode becomes hot.
cargo bench -p flatland-protocol --bench codec_bench
4.2 Agent / ops APIs
| API | Protocol | Consumers |
|---|---|---|
| World build | HTTP/JSON | flatland-world CLI, agents |
| Deploy status | HTTP/JSON | CI, ops dashboards |
| Control plane admin | HTTP/JSON | Staff tools |
4.3 Internal cluster
| Link | Protocol |
|---|---|
| Gateway ↔ region worker | gRPC (tonic) or QUIC mesh |
| Region ↔ control plane | gRPC |
| Orchestrator ↔ workers | gRPC + Redis pub/sub |
5. Protocol types (v1)
Defined in crates/protocol:
| Type | Direction | Purpose |
|---|---|---|
Hello / Welcome |
C→S / S→C | Session + snapshot |
Intent |
C→S | Move, stop (sequenced) |
TickDelta |
S→C | AOI-filtered entity states |
Snapshot |
S→C | Region enter / reconnect |
Envelope<T> |
Both | protocol_version wrapper |
6. Simulation parameters (locked for Phase 1)
| Parameter | Value | Ref |
|---|---|---|
| Tick rate | 30 Hz | 01 |
| Chunk size | 16 m | 01 |
| AOI core radius | 32 m | 06 |
| AOI horizon | 64 m (2× core) | 06 |
| Interaction radius | 1.5 m | 03 |
| Item instance IDs | UUID v7 | 03, 18 |
| Seed segment | 64×64 m flat grass | assets/world/segments/starter-plains.yaml |
7. Performance targets
| Metric | Target | How we measure |
|---|---|---|
| Region tick | 30 Hz stable | flatland-bot ticks/bot/sec |
| AOI encode | < 1 ms for 100 entities | codec_bench |
| Intent → ack | p99 < 20 ms LAN | bot harness latency |
| 100 bots / region | No tick collapse | flatland-bot -n 100 |
8. Phase 1 commands
# Build everything
cargo build --workspace
# Unit tests
cargo test --workspace
# Codec benchmark (postcard vs bincode)
cargo bench -p flatland-protocol --bench codec_bench
# Sim AOI benchmark
cargo bench -p flatland-sim --bench aoi_bench
# Bot load harness (from repo root)
cargo run -p flatland-bot-harness -- -n 50 -d 10
9. Next implementation steps
| Step | Deliverable |
|---|---|
| 2a | QUIC gateway (quinn) — replace in-process channels |
| 2b | Postgres control plane — account, character, position checkpoint |
| 2c | Region orchestrator stub — metrics hooks for split |
| 2d | flatland TUI — human play on top of client-lib |
| 2e | World-build HTTP service — segment CRUD + validate |
10. Security notes
- JWT or opaque session in Redis; validated at gateway connect
- Workers reject undeployed segment drafts
- Rate-limit intents per session at gateway
Supersedes open protocol questions in 00-initial-vision.html §4.3 for codec and DB choices.