Runtime Architecture & Implemented Features
1. Summary
Flatland3 runs as separate processes in local dev and production-shaped deployments:
| Process | Binary | Default port | Role |
|---|---|---|---|
| Control plane | flatland-control-plane |
HTTP :7380, gRPC :7381 |
Accounts, auth, characters, checkpoint, item mint |
| Region worker | flatland-worker |
Wire :7391 |
30 Hz sim, AOI, gameplay rules for one region |
| Gateway | flatland-gateway |
TCP :7373 |
Player protocol, auth handoff, routes to worker |
| Play client | flatland3 |
— | Ratatui + agent CLI |
Embedded mode (no separate worker): omit FLATLAND_WORKER_ADDR or pass --embedded to gateway — worker runs in-process for flatland-dev and quick tests.
2. Process architecture (implemented)
2.1 Gateway ↔ worker wire (internal)
- Transport: TCP, length-prefixed postcard frames, magic
FL3W - Multiplexing:
link_idper player session on one gateway→worker connection - Messages:
OpenSession,SubmitIntent,CloseSession,DefaultSpawn,Checkpoint,Ping/Pong - Code:
crates/region-worker/src/wire.rs,crates/gateway/src/backend/remote.rs
2.2 Local dev startup
cp .env.example .env && make db-up
# Terminal 1
make dev-control-plane
# Terminal 2
make dev-worker
# Terminal 3
make dev-gateway
# Terminal 4 (optional)
make dev-play NAME=traveler
| Env var | Purpose |
|---|---|
FLATLAND_WORKER_ADDR |
Gateway → worker wire (127.0.0.1:7391) |
FLATLAND_WORKER_LISTEN |
Worker bind address |
FLATLAND_GATEWAY_LISTEN |
Player TCP bind (127.0.0.1:7373) |
FLATLAND_REGION_ID |
Worker shard id (r1) |
FLATLAND_CONTROL_PLANE_URL |
Auth + checkpoint HTTP base |
3. Implemented feature catalog
Each subsection describes what the current revision does and where it lives in code.
3.1 Control plane & auth
Implemented
- Email/password register, login, logout,
GET /v1/me - Scoped API tokens (
play,read,write) - Character CRUD; position + progression checkpoint on disconnect
- Game connect:
POST /v1/game/validate-connect,POST /v1/game/checkpoint - Item mint on harvest:
POST /v1/game/mint-item - gRPC
AuthService.ValidateCredentialon:7381 - Migrations: accounts, tokens, characters, inventory, progression JSONB
Code: crates/control-plane/, migrations/
3.2 Gateway & protocol
Implemented
- TCP game server, postcard framing
FL3\x01, protocol v2 - Session + API token auth via control plane
DevLocalgated byFLATLAND_ALLOW_DEV_LOCAL- Remote worker backend (
FLATLAND_WORKER_ADDR) or embedded worker - Intents: Move, Stop, Harvest, Use, Say, Craft, Interact, TestDamage, SetTarget, Attack, Cast, Dodge, Block, EquipMainhand, …
- Server messages: Welcome, Tick, IntentAck, Chat, HarvestResult, CraftResult, Death, Interaction
Code: crates/gateway/, crates/protocol/
3.3 Region worker & simulation
Implemented
RegionSim@ 30 Hz: movement, AOI, interaction radius 1.5 m- Chunk map (16 m), orchestrator split threshold logging
- World segment YAML: resource nodes, buildings, doors, NPCs, terrain zones, z-bands (
z_platforms,z_transitions,z_walls) - Timed harvest, node respawn, blocking nodes
- Nested inventory (instance UUID +
contents), mass/volume, worn back/belt containers - Placeable lockable chests + unique craft keys; dimensional pouch mass attenuation
- Wildlife + combat:
region_combat.rs, abilities, multi-slot targeting, 3D LoS + z-walls - NPC lifecycle: ground drops, carcass TTL, respawn scheduler (
25) - Content bundle hot reload (Tier 3.5):
Arcswap for blueprints, catalog, settings, NPC defs - Timed craft from blueprint packs (
assets/crafting/) - Broker hut (Ada), door enter/exit, resurrection shrines
- Death / respawn, test damage dev intent
- Player progression: primaries, skills (tier 0–10), vitals pools, activity growth, atrophy
- World clock on wire + TUI status line
- Server settings YAML (vitals, progression, day/night) — no hardcoded tuning
Code: crates/sim/, crates/region-worker/, assets/
3.4 Player attributes & persistence
Implemented
PrimaryAttributeson wire (internal 1–1000, display /10)- Hunger, thirst, mana, stamina, health pools +
PoolSpendhooks - Regen/drain modifiers; TUI character sheet (
i) - Postgres:
attributes,vitals_state,skillsJSONB oncharacters - Checkpoint roundtrip: disconnect → validate-connect restores attrs, pools, skills
- Skills start at tier 0 (internal level 0); tier 1 at internal 100
- Pristine
{}vitals treated as new character (full pools)
Code: crates/protocol/src/types.rs, crates/control-plane/, migrations/004_character_progression.sql
Smoke: cargo test -p flatland-control-plane --test progression_persistence -- --ignored
3.5 Play client (TUI)
Implemented
- In-TUI login (email/password) when no session
- WASD (world-relative; hold two keys for diagonal), sprint, climb/descend, context use (
f), craft (n), inventory (b) - Click-to-move (left-click) + map target mode (
m); Space hard-stops; Shift+Space lunge - Combat HUD, loadout (
l), rotation editor (o) - Stats overlay (
i): primaries, derived preview, pools, skills tiers 0–10 - HP/MP/STA bars; nearby chat (
t) and whisper-stone (g) - Map glyphs: resources, buildings, doors, NPCs, player first-letter labels; elevation tiers on terrain (
▴/^/▲) - Combat: Tab/Shift+Tab targets;
0/Shift+0clear T1/T2;1–9hotbar casts; auto (r/Shift+r); dodge (c); block (q); inventory equip (b→ Enter /u) - Storage: carry mass bar, inventory tree, place/pickup chests (
f), equip pouches/backpacks - Utility row:
bbag,ncraft,mmap,,keychain,.HUD,/or?help - Z-axis: PageUp/PageDown climb; HUD shows
z; click-to-move routes through stairs when goal is on another band
Code: tools/flatland/, crates/tui/, crates/client-lib/
3.6 World tooling & admin
Implemented
flatland-admin: segment/item/building/object CRUD, JSON schemas, audit verifyflatland-world: segment validate/showPOST /v1/segments/validate,/v1/admin/*- Starter segment
starter-plains.yamlwith broker hut, shrines, terrain zones
Code: tools/flatland-admin/, tools/flatland-world/, schemas/
3.7 Agents & ops
Implemented
flatland3 auth login, token create,capabilitiesflatland3 inventory --jsonFLATLAND_API_TOKEN+FLATLAND_CHARACTER_IDfor headless playflatland-botload harness; scenario YAML + audit expectations- Structured audit JSONL (
region_tick_sample,checkpoint_saved, …)
Code: tools/flatland/, tools/bot-harness/, crates/audit/
3.8 Combat system
Architecture
- Intents only — no input methods in sim (
SetTarget,Attack,Cast,EquipMainhand,AssignSlotPreset, …) RegionSim@ 30 Hz: combat pursuit → auto-attacks / NPC telegraphs → DoT tick → movement integrate- Ability templates in
assets/combat/abilities/*.yaml; items inassets/items/ - Client pathfinding (
crates/client-lib/src/navigation.rs) for click-to-move / map targets
Capability layers (implemented)
| Layer | Behavior |
|---|---|
| Mainhand weapon | EquipMainhand sets PlayerState.mainhand; slot-1 auto uses weapon_ability_id on that item |
| Auto-attack | Per-slot toggles; slot 1 drives pursue |
| Auto-pursue | Slot-1 target; band positioning from mainhand range_min_m / range_max_m |
| Manual weapon | Attack intent → mainhand ability |
| Manual spells | Cast { ability_id, target_id } — independent range/CD/GCD |
| Defense | Dodge (i-frames), Block (frontal melee reduction) |
| Multi-slot / loadout | T1/T2 targets; rotation presets; loadout assign; persist on StoredCombatProfile |
| Rotation editor | TUI o — create/edit/delete presets; UpsertRotationPreset / DeleteRotationPreset |
| Macros | ExecuteMacro { macro_id: "burst_opener" } |
| NPC abilities | Wolf wolf_bite / wolf_lunge from YAML; telegraphed lunge dodge window |
| DoT / on_hit | poison_dart / ability on_hit → status-effect catalog + periodic DoT ticks |
| Pacing | combat.pacing.* multipliers in server-settings.yaml |
Content shipped
| Ability | Kind | Notes |
|---|---|---|
unarmed |
weapon_attack | Default, no equip |
short_sword_slash |
weapon_attack | wooden_sword |
bow_shot |
weapon_attack | hunting_bow, short_bow; 3–22 m |
arrow_shot |
spell | Manual; same range band |
fireball |
spell | Channel + splash |
cone_frost, frost_nova |
spell | Cone / self sphere |
heal_touch |
spell | Friendly/self; Support preset |
poison_dart |
spell | on_hit DoT |
wolf_bite, wolf_lunge |
weapon_attack | NPC catalog; lunge telegraphed |
Weapons (assets/items/weapons.yaml)
wooden_sword→short_sword_slashhunting_bow,short_bow→bow_shot
Persistence
StoredCombatProfile: target instance id,target_slots[](preset_id, auto, rotation_index),rotation_presets[],in_combat, cooldowns,auto_attack_enabled,mainhand_template_id- Immediate
POST /v1/game/sync-combat-profileon loadout/rotation/auto/equip; checkpoint on disconnect - Characters: explicit
flatland3 character createonly — play never auto-creates
Movement / TUI (summary)
WASD (chord diagonals OK); click-to-move; map mode (m); Tab/Shift+Tab targets; 0/Shift+0 clear; 1–9 hotbar; l/o loadout/rotations; c/q dodge/block; Shift+Space lunge; r/Shift+r autos; f use world; n craft.
Vitals regen ramp (assets/config/server-settings.yaml)
Per-pool regen_ramp.health / .mana / .stamina — each with seconds_to_full, min_multiplier, max_multiplier, curve_power.
Code
crates/sim/src/region_combat.rs— pursuit, resolver, equip, NPC telegraphs, DoTscrates/sim/src/abilities.rs,combat_slots.rs,combat_status.rscrates/client-lib/src/game.rs,navigation.rscrates/tui/src/app.rs,loadout.rs,rotation_editor.rs
Principle: nothing is hard-coded per weapon name in Rust or the client. The server item catalog defines what an item does; equip/use intents resolve capabilities against the equipped instance.
3.9 Storage & carriers
Implemented
- Item templates:
base_mass,base_volume,packable,capacity_volume,equip_slot(back/belt) - Nested inventory graph on wire + Postgres sync; worn back/belt; placed chests in world snapshot
MoveItem, equip, place, pickup, lock intents; mass/volume caps; nest depth (default 4)- Lockable chests mint unique keys; dimensional pouch mass attenuation
- TUI: inventory tree, carry mass bar, scrollable overlays, chest glyphs on map
Code: crates/sim/src/containers.rs, region_containers.rs, inventory.rs; crates/tui/src/scrollable_list.rs
3.10 Z-bands & vertical dimension
Architecture
- Terrain elevation —
terrain_zones[].elevationsets groundzper rect; wired onTerrainZoneView.elevation - Z-platforms — extra walkable surfaces at fixed
z(z_platformsin segment YAML) - Z-transitions — stairs/ramps linking
z_from↔z_to(PageUp/PageDown while standing in rect) - Z-walls — axis-aligned volumes blocking 3D combat LoS
- Movement —
z_bands::resolve_horizontal_z/settle_z/apply_vertical_z(no snap-to-ground on platforms) - AOI —
query_radius_zwithAOI_Z_EXTENT_M(6 m) vertical half-extent - Client pathing —
navigation.rsblocks cells at wrong band; opens transition cells; auto-climbs stairs
Starter test slice (starter-plains.yaml v1.2.5): southeast mountain — south trail (z=0→4 in 1 m steps), plateau at ~(220–232, 158–166), north/east/west cliff faces block uphill; fall off rim to z=0. LoS wall on north rim.
Code: crates/sim/src/z_bands.rs, los.rs (has_line_of_sight_3d); crates/protocol ZPlatformView, ZTransitionView
5. Binary reference
| Command | Package | Notes |
|---|---|---|
flatland-control-plane |
tools/control-plane |
Requires Postgres + Redis |
flatland-worker |
tools/worker |
FLATLAND_WORKER_LISTEN |
flatland-gateway |
tools/gateway |
Set FLATLAND_WORKER_ADDR |
flatland-server |
tools/server |
Legacy; uses FLATLAND_WORKER_ADDR if set |
flatland-dev |
tools/flatland-dev |
Retired — embedded TUI play |
flatland3 |
tools/flatland |
Auth / agent CLI — not play client |
flatland3-gfx |
tools/flatland-gfx |
Only maintained play client (Macroquad + egui) |
flatland-bot |
tools/bot-harness |
Load / scenario driver |