neon-sprawl/docs/architecture/tech_stack.md

6.1 KiB
Raw Blame History

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.

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 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 (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 Godots 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.