docs(docs): record D-020 engine decision and rejected alternatives

D-020: Godot 4 client + Rust/bevy_ecs simulation server via
subprocess/IPC. MessagePack serialization. Kill switch at week 8.
Q-001 resolved. Rejected alternatives R-004 through R-010 (pure
Bevy, pure Godot, GDExtension, C++ GDExtension, Fyrox, custom
framework, protobuf).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-09 23:06:11 +01:00
co-authored by Claude Opus 4.6
parent ff7c781d45
commit ee36321f7d
+68 -7
View File
@@ -217,6 +217,44 @@ This document tracks confirmed decisions, open questions, and rejected alternati
- **Raised by:** Full team across Rounds 8-10.
### D-020: Engine and architecture selection — Godot client + Rust simulation via subprocess/IPC
- **Date:** 2026-02-09
- **Decision:** The game uses a split architecture: **Godot 4** (GDScript) as the rendering client, **Rust** with **bevy_ecs standalone** as the simulation server. The two communicate via **subprocess/IPC** (local socket for single-player, TCP for multiplayer). **NOT via GDExtension.**
- **Architecture:**
- The Rust simulation is a standalone binary with zero Godot dependencies. It runs the ECS world, perception queries, AI, storyteller, combat — all game logic.
- The Godot client is a pure renderer: receives `ObserverSnapshot` data, draws tiles/sprites/fog, plays audio, shows UI, captures input. No game logic in GDScript.
- Single-player: Godot launches the Rust binary as a child process. Local Unix socket or localhost TCP.
- Multiplayer: Godot connects to a remote Rust server. Same protocol. The simulation binary doesn't know the difference.
- This IS the D-010 client-server architecture — literally, not simulated.
- **Serialization:**
- **MessagePack** for all client-facing communication (Rust↔Godot). Dynamic structure supports variable HUD composition driven by perception modes (D-017). Cross-language, debuggable.
- **bincode** reserved for future Rust↔Rust server-to-server sync (same binary, hot path, zero overhead).
- **protobuf** rejected — solves deployment/versioning problems we don't have, poor GDScript support.
- **Why subprocess over GDExtension:**
- Eliminates entire risk categories: gdext pre-1.0 API churn, Godot version ABI breakage, FFI thread safety (`Gd<T>` is `!Send`), cross-boundary memory management.
- Decouples learning: build and test Rust simulation standalone, build Godot renderer standalone, connect when both work.
- Maps directly to D-010 client-server with no simulation — it IS client-server from day one.
- Either side can be upgraded, replaced, or scaled independently.
- Cost: ~1-5ms serialization latency per tick. Acceptable for a detective/strategy game, not a twitch shooter.
- **Key patterns:**
- `ObserverSnapshot`: the only data structure crossing the boundary. Contains visible entities, fog state, sound events, monologue triggers, HUD widget data. Variable shape per character build.
- `PlayerInput`: semantic actions (MoveNorth, Interact, UsePerceptionMode), not raw key events. Timestamped for deterministic processing.
- `SimBridge` trait: abstracts transport. `LocalBridge` (subprocess, channels) and `NetworkBridge` (TCP, MessagePack) implement the same interface.
- **Kill switch:** If no working prototype (character + fog + one NPC) exists by week 8 of development, pivot to pure Godot. If bridge/sync code exceeds game logic for 3 consecutive sprints, the architecture tax is too high.
- **Development sequence:**
1. Build Rust simulation as standalone binary (testable via terminal/logs)
2. Build Godot renderer as standalone project (hardcoded test data)
3. Connect via MessagePack protocol
- **Project structure:**
```
simulation/ # Pure Rust, bevy_ecs, zero Godot deps
client/ # Godot 4 project, GDScript only
protocol/ # Shared message definitions (MessagePack schemas)
```
- **Evaluation reports:** `docs/architecture/eval-godot-rust-bridge.md` (Tyre), `docs/architecture/risk-godot-rust-bridge.md` (Troblum)
- **Raised by:** Team Leader (Jeroen) proposed Godot client + Rust backend. Tyre designed architecture. Troblum's risk assessment shifted integration from GDExtension to subprocess/IPC. Full team endorsed.
- **Dissent:** None. Troblum's CRITICAL risk flags on GDExtension were accepted; subprocess approach addresses them.
### D-004: Team composition confirmed
- **Date:** 2026-02-08
- **Decision:** Team of 8 agents + Team Leader.
@@ -238,12 +276,7 @@ This document tracks confirmed decisions, open questions, and rejected alternati
## OPEN QUESTIONS
### Q-001: Game engine selection
- **Status:** Not yet discussed - NEXT PRIORITY
- **Options under consideration:** Godot, Bevy (Rust), custom lightweight engine, others TBD
- **Key factors:** 2D/2.5D presentation, strong event/simulation systems, UI framework quality, AI-assisted dev friendliness, Team Leader's comfort
- **Hard requirements from decisions:** Client-server friendly (D-010), chunk-based map loading (D-012), LOS shadowcasting (D-011), deterministic simulation (D-010)
- **Context update:** Rimworld-style systems-driven game. No 3D engine needed. Godot is front-runner.
- **Assigned to:** Tyre to lead discussion, full team input
- **Status:** Resolved → D-020
### Q-002: Scope of v0.1 playable prototype
- **Status:** Map spec resolved (D-014). Remaining: mechanics, characters, interactions for minimum playable build.
@@ -308,6 +341,34 @@ This document tracks confirmed decisions, open questions, and rejected alternati
- **Rejected:** 2026-02-08
- **Reason:** Each captures at most 40% of what's needed. Smaller modding communities, less mature tools, and none solve the core CK3+Stellaris hybrid requirement.
### R-004: Pure Bevy (Rust) — no Godot
- **Rejected:** 2026-02-09
- **Reason:** No visual editor (level design is code-only). UI framework in flux. API breaks significantly between versions. For a solo developer who needs visual tools for hand-crafted buildings (D-014), Godot's editor is a massive productivity advantage. Bevy's ECS is used — just not its renderer.
### R-005: Pure Godot (GDScript or C#)
- **Rejected:** 2026-02-09
- **Reason:** Scene tree paradigm fights ECS-style simulation. Perception queries (D-017) and information boundaries (D-010) map naturally to ECS component queries, not scene tree traversal. Multi-core scaling for expanded content impossible in GDScript. Kept as kill-switch fallback if Rust architecture exceeds time budget.
### R-006: Godot + Rust via GDExtension
- **Rejected:** 2026-02-09
- **Reason:** gdext is pre-1.0 with breaking API changes. Godot version upgrades break GDExtension ABI. Thread safety at FFI boundary is CRITICAL risk (`Gd<T>` is `!Send`/`!Sync`). Couples Rust and Godot learning curves. Subprocess/IPC achieves the same architecture without the FFI risk surface, and maps directly to D-010 client-server. See `docs/architecture/risk-godot-rust-bridge.md` for full analysis.
### R-007: Godot + C++ via GDExtension
- **Rejected:** 2026-02-09
- **Reason:** More mature bindings than gdext, but trades Rust's safety guarantees for C++ memory unsafety. No advantage over subprocess/IPC approach. Developer not experienced in C++.
### R-008: Fyrox (pure Rust engine)
- **Rejected:** 2026-02-09
- **Reason:** Single maintainer. ~1/50th of Godot's community. Less documentation, fewer tutorials, weaker AI training data for Claude Code. Single-maintainer risk unacceptable for multi-year project.
### R-009: Custom framework (Rust + raylib/macroquad)
- **Rejected:** 2026-02-09
- **Reason:** Maximum control but you build everything — tilemap rendering, camera, UI, audio, input, asset pipeline. Months before testing a mechanic. The game's hard problems are simulation, not rendering — don't reinvent the rendering wheel.
### R-010: protobuf for client-server serialization
- **Rejected:** 2026-02-09
- **Reason:** Schema evolution across independent deployments is a problem we don't have (one developer, client and server ship together). Poor GDScript support. Rigid schema fights dynamic HUD composition driven by perception modes (D-017). MessagePack's schema-optional nature fits better.
---
*Document maintained by SCRIBE. Last updated: 2026-02-08*
*Document maintained by QATUX. Last updated: 2026-02-09*