# Phase 4 — Server Hardening Architecture ## Overview Phase 4 turns the bare dedicated server into a community-hostable, administrable, and discoverable service. Four components work together to create the full server ops experience: ``` ┌─────────────────────────────────────────────────────┐ │ GODOT SERVER │ │ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │ │ │ RCON Admin │ │ Config │ │ Anti-Cheat│ │ │ │ Console │ │ System │ │ Validation│ │ │ │ (TCP/28960) │ │ (cvars.cfg) │ │ Layer │ │ │ └──────┬───────┘ └──────┬───────┘ └─────┬──────┘ │ │ │ │ │ │ │ └──────────┬──────┘─────────────────┘ │ │ │ │ │ ┌──────────▼──────────┐ │ │ │ Server Browser │ │ │ │ Heartbeat Sender │ │ │ │ (POST /heartbeat) │ │ │ └──────────┬──────────┘ │ └────────────────────┼────────────────────────────────┘ │ HTTP (every 60s) ┌────────────────────▼────────────────────────────────┐ │ MASTER SERVER (Python/Go) │ │ ┌──────────────────────────────────────────────┐ │ │ │ REST API: /api/v1/heartbeat │ │ │ │ /api/v1/servers │ │ │ │ /api/v1/servers/:id │ │ │ │ /api/v1/status │ │ │ └──────────────────────────────────────────────┘ │ │ ┌──────────────────────────────────────────────┐ │ │ │ SQLite: servers table, TTL-based expiry │ │ │ └──────────────────────────────────────────────┘ │ └────────────────────┬────────────────────────────────┘ │ HTTP ┌────────────────────▼────────────────────────────────┐ │ GODOT CLIENT │ │ ┌──────────────────────────────────────────────┐ │ │ │ Server Browser UI │ │ │ │ GET /api/v1/servers → list → connect │ │ │ └──────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘ ``` ## Dependency Graph ``` Phase 4 (orchestrator — this doc) ├── build:rcon-admin-console [coder] — TCP remote admin ├── build:server-config-system [coder] — cvars + cfg loading ├── build:server-browser-api [coder] — master server + heartbeat └── build:anti-cheat-basics [coder] — input validation ``` All 4 tasks are **independent** — they can be worked in parallel. The only soft dependencies: - RCON depends on the config system for its cvars (rcon_enabled, rcon_port, rcon_password) — handle by reading from the shared cvar registry - Browser heartbeat depends on config system for `sv_master_server` cvar - Anti-cheat depends on config system for its cvars No hard ordering constraints. Each task creates its own files and registers its cvars. ## Communication Between Components | Source | Target | Mechanism | Data | |--------|--------|-----------|------| | RCON | Game Server | GDScript signals | `rcon_command` signal (cmd, args) | | RCON | Config System | Direct cvar read/write | `CvarRegistry.get/set` | | Browser Heartbeat | Master Server | HTTP POST | JSON heartbeat payload | | Client Browser | Master Server | HTTP GET | JSON server list | | Anti-Cheat | Game Server | Per-tick validation callback | Player state snapshots | | Config System | All | Parse-time cvar registration | cvars.gd static dict | ## File Structure ``` server/ ├── scripts/ │ ├── rcon_server.gd — TCP listener, auth, command dispatch │ ├── rcon_command_handler.gd — Command implementations │ ├── server_browser.gd — Heartbeat sender (HTTP POST) │ └── anti_cheat.gd — Main anti-cheat coordinator ├── data/ │ ├── server_config.gd — Cvar registry, config loader │ ├── cvars.gd — Static cvar definitions with metadata │ ├── server_default.cfg — Default config shipped with binary │ └── rcon_password.cfg — RCON password file (chmod 600) ├── server-browser-api/ — Standalone master server service │ ├── main.py — Python/FastAPI master server │ ├── requirements.txt │ └── master_config.json client/ └── scripts/ └── server_browser_ui.gd — In-game server browser UI ``` ## Config Loading Pipeline ``` 1. Hardcoded defaults (cvars.gd) │ 2. server_default.cfg │ 3. --config (default: server.cfg) │ 4. Command-line overrides (+cvar value) │ 5. Map-specific cfg (cfg/.cfg) │ ▼ Final cvar state → Game loop ``` ## Anti-Cheat Validation Pipeline (per tick) ``` Client input packet arrives │ ▼ Input sequence validation (timestamp monotonic, seq# dedup) │ ▼ Movement validation (speed limit, teleport, multi-jump) │ ▼ Fire rate validation (interval, ammo) │ ▼ Command validation (whitelist, rate limit) │ ▼ Log → Correct → Warn → Kick (based on sv_ac_level) ``` ## CVars Introduced by Phase 4 | Cvar | Default | Range | Module | Description | |------|---------|-------|--------|-------------| | rcon_enabled | 0 | [0,1] | RCON | Enable RCON TCP server | | rcon_port | 28960 | [1024,65535] | RCON | RCON listen port | | sv_master_server | "" | string | Browser | Master server URL | | sv_server_id | auto | string | Browser | Unique server token | | sv_heartbeat_interval | 60 | [10,300] | Browser | Heartbeat period (s) | | sv_server_tags | "" | string | Browser | Comma-separated tags | | sv_server_password | "" | string | Browser | Server join password | | sv_ac_level | 2 | [0,3] | Anti-Cheat | Enforcement level | | sv_ac_speed_tolerance | 1.2 | [1.0,3.0] | Anti-Cheat | Speed violation multiplier | | sv_ac_max_aim_snap | 180 | [10,360] | Anti-Cheat | Max deg/tick aim change | | sv_ac_fire_tolerance_ms | 10 | [0,100] | Anti-Cheat | Fire interval tolerance | | sv_ac_kick_threshold | 5 | [1,20] | Anti-Cheat | Violations before kick | ## Exit Criteria - Community member can download server binary, configure via `server.cfg`, and run it - RCON is functional: operator connects via `nc`/`telnet` and runs admin commands - Server registers with master server via heartbeat and appears in the browser - Client opens server browser, sees the server, and connects - Anti-cheat corrects speed-hack attempts at enforcement level 2 - Everything is controllable via cvars in config file or command-line overrides