# 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 10** — primary author has ~10 years C# experience; authoritative game logic, persistence, and ops stay in this stack.

**Client scripting (locked):** **GDScript** in Godot—fast iteration, native engine integration; server remains the only **C#** game-logic surface.

**Other operator skills:** **JavaScript** and **TypeScript** remain useful for content tooling and one-off scripts—**not** the authoritative server.

## Summary

| Layer | Choice | Role |
|--------|--------|------|
| Game client | **Godot 4.x** + **GDScript** | Rendering, input, camera, local prediction (if any), UI, telemetry emit |
| Game server | **C# / .NET 10** (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

The [`client/`](../../client/) Godot project targets **4.6** (`config/features` in `project.godot`). Older 4.x may work but 4.6 is the baseline for editor and manual testing.

**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 (locked)** for all client gameplay and UI code—quick reload, examples and addons match; share contracts with the server via **Protobuf** or **JSON** (spike), not shared C# assemblies.
- 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 10)

**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. **PII, sampling, retention, reload:** [`docs/decomposition/modules/data_and_ops_policy.md`](../decomposition/modules/data_and_ops_policy.md).

## 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

- [`neon_sprawl_vision.plan.md`](../neon_sprawl_vision.plan.md) — product locks and phase gates
- [`docs/decomposition/README.md`](../decomposition/README.md) — epic/module decomposition
- [`docs/decomposition/modules/contracts.md`](../decomposition/modules/contracts.md) — contract kinds (wire, content, telemetry), repo layout, versioning vs. register “Contract needed”
- [`docs/decomposition/modules/client_server_authority.md`](../decomposition/modules/client_server_authority.md) — intents vs authoritative state; movement, camera, combat, economy ownership
- [`docs/decomposition/modules/pvp_combat_integration.md`](../decomposition/modules/pvp_combat_integration.md) — E5.M1 combat engine × E6.M1 PvP eligibility (single pipeline, deny reasons)
- [`docs/decomposition/modules/quest_scope_and_party.md`](../decomposition/modules/quest_scope_and_party.md) — quest state per character, party credit, turn-in, instance deferral
- [`docs/decomposition/modules/data_and_ops_policy.md`](../decomposition/modules/data_and_ops_policy.md) — content boot load vs dev reload, telemetry PII/sampling/retention, baseline events vs vision plan
- [`docs/decomposition/modules/documentation_and_implementation_alignment.md`](../decomposition/modules/documentation_and_implementation_alignment.md) — module register Status vs code, implementation tracking table
