# Tech stack (baseline decision) **Status:** Baseline for **prototype through early pre-production**. Revisit before vertical-slice freeze if tooling or hiring assumptions change. **Constraints from product vision:** Solo operator, server-authoritative critical paths, fixed isometric 3D client, tab-target combat, data-driven skills/items/recipes/quests, optional PvP zones, eventual scale-out (not day one). **Server runtime (locked):** **C# / .NET 8** — primary author has ~10 years C# experience; authoritative game logic, persistence, and ops stay in this stack. **Other operator skills:** **JavaScript** and **TypeScript** remain useful for content tooling, client-side scripting in Godot (GDScript on client for fast iteration), and one-off scripts—**not** the authoritative server. ## Summary | Layer | Choice | Role | |--------|--------|------| | Game client | **Godot 4.x** | Rendering, input, camera, local prediction (if any), UI, telemetry emit | | Game server | **C# / .NET 8** (ASP.NET Core) | Authoritative simulation, zones, combat/crafting resolution, persistence boundaries | | RPC / messages | **Protobuf** (or **JSON** for earliest spike only) | Versioned contracts between client and server | | Primary database | **PostgreSQL** | Characters, inventory, progression, economy ledger, idempotent transactions | | Cache / presence (when needed) | **Redis** | Sessions, rate limits, hot read models—**defer** until second scaling pain | | Content data | **JSON or YAML + JSON Schema** (or **CUE** later) | Skills, items, recipes, quests; validated in CI (can use Node or `dotnet` validators) | | Repo / CI | **Git** + **GitHub Actions** or **Gitea Actions** | `dotnet build`, schema validation, optional Godot export | ## Client: Godot 4 **Why** - Strong fit for solo iteration: fast reload, small install, no revenue cap. - 3D isometric camera (orthographic or perspective), zoom, and **no rotation** are straightforward in a single-camera rig. - **GDScript** for rapid client prototyping; **Godot C#** available if you want client/server language alignment in hot paths. - Networking: treat **WebSocket** or **TCP** as transport only; **authoritative logic stays on the ASP.NET Core server**, not in Godot’s high-level multiplayer templates, to avoid fighting engine assumptions. **Prototype discipline** - One contained district; no multi-region streaming in engine until pre-production handoff slice. - Client sends intents (`MoveIntent`, `UseAbilityIntent`, …); server emits state deltas or snapshots. **Plan B** - **Unity** (6000 LTS track) if the art pipeline shifts; **server stays C#**—reuse patterns and types where practical. **Defer** - **Unreal** for this phase unless art direction *requires* it. ## Server: C# (.NET 8) **Why** - **ASP.NET Core** (minimal APIs or controllers) + **Kestrel**; WebSockets, gRPC, or raw TCP alongside HTTP health/metrics. - **PostgreSQL** via **Npgsql**; **EF Core** (migrations) or **Dapper** + **FluentMigrator** / **DbUp**—pick ORM vs hand-written SQL and stay consistent. - **Protobuf:** **Grpc.Net** or **protobuf-net**; JSON is acceptable for the first spike only. - **Prototype shape:** single `GameHost` (or named) process—in-memory zone state + PostgreSQL for durable character/inventory; split processes only when metrics demand it. **Pre-production** - Optional read replicas or separate presence service; job queues only when needed. ## Server alternative (not default) **TypeScript / Node** remains viable for tools-only or a secondary BFF; avoid splitting authoritative state across two runtimes unless there is a clear boundary (e.g. web shop vs simulation). ## Other server languages (optional later) | If you… | Consider | |---------|----------| | Want a tiny deploy binary for a worker | **Go** — isolated sidecar, not replacing the main C# sim without a decision doc | | Experiment | **Rust** — only for proven hot paths | ## Data and persistence - **PostgreSQL** as source of truth for anything that must survive restarts or be audit-able (inventory, trades, progression). - Migrations: **EF Core** or **FluentMigrator** / **DbUp** with **Npgsql**; keep migrations in-repo. - **Avoid** client-trust for economy: craft outcomes, loot grants, and trades commit only after server validation + DB transaction where required. ## Content pipeline - Author in **JSON/YAML**; validate with **JSON Schema** in CI (Node-based **ajv**/CLI, **dotnet**-based validators, or **CUE** later). - Server loads tables at boot or hot-reloads in dev; client may receive **bundles** or hash-versioned blobs to avoid drift. - Epic 3/7 decomposition modules (`RecipeDef`, `QuestDef`, …) map directly to these files. ## Observability - **Serilog** and/or **OpenTelemetry** for .NET from early prototype. - Align event names with `E9.M1 TelemetryEventSchema` in the vision doc; client batches to server or OTLP endpoint as capacity allows. ## Security (proportionate to phase) - **Prototype:** TLS on public endpoints if exposed; auth token or session secret; minimal PII handling. - **Pre-production:** Rate limits, input validation on all RPCs, admin tools behind separate auth. ## Explicit non-goals for stack selection - Choosing a commercial “MMO middleware” that locks data formats or hosting. - Client-authoritative combat or inventory. - Full anti-cheat and bot defense before core loop fun is proven (track with E9.M4 workflows later). ## Revision triggers Revisit this document if: - Target platforms add **console** or **mobile** with hard certification constraints. - Art pipeline commits to an engine not listed above. - Co-op session model forces **P2P** or large physics sync (unlikely for tab-target isometric). - Simulation CPU bottlenecks justify a **Go/Rust worker** for isolated workloads—document the split; **keep C# as orchestration** unless you rewrite the decision. ## Related docs - [`cyberpunk_mmo_vision_86a57ef3.plan.md`](../cyberpunk_mmo_vision_86a57ef3.plan.md) — product locks and phase gates - [`docs/decomposition/README.md`](../decomposition/README.md) — epic/module decomposition