Files
Cinderwild/docs/ARCHITECTURE.md

117 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Architecture
This is the big-picture design. It's deliberately written before heavy coding so
the hard decisions (networking authority, addon sandbox) are made up front, not
bolted on.
## 1. Guiding principles
1. **Server is authoritative.** The client is a renderer + input device. It never
decides game state (health, inventory, block placement, hits). This is the
anti-cheat baseline — you cannot bolt it on later.
2. **Same binary, two modes.** One Godot project runs as the client *and* as the
headless dedicated server (`--headless -- --server`). No separate codebase.
3. **Addons can never hurt the host.** Mods run in a sandbox (Lua) with a capped
API, CPU/memory quotas, and no filesystem/network/host access. Designed in from
day one.
4. **Low-poly + lighting, not textures.** Art pipeline stays cheap so a solo dev
can actually finish.
## 2. Process topology
```
┌────────────────────────────────────────────┐
│ Dedicated Server (headless Godot) │
│ - owns ALL game state │
│ - runs the simulation tick (fixed timestep) │
│ - loads & sandboxes addons │
│ - persists the world (save system) │
└───────────────▲───────────────▲──────────────┘
│ ENet/UDP │
┌───────────┴───┐ ┌───────┴─────────┐
│ Client A │ │ Client B │
│ render+input │ │ render+input │
│ client-side │ │ client-side │
│ prediction │ │ prediction │
└────────────────┘ └──────────────────┘
```
Single-player = the client spawns an in-process server (loopback). So
single-player and multiplayer share the exact same code path — no "SP special
case" that rots.
## 3. Networking
- **Transport:** Godot's built-in high-level multiplayer over **ENet** (reliable
UDP). Good for 2–16 players, which is the realistic self-hosted survival scale.
- **Model:** server-authoritative with client-side prediction + reconciliation for
the local player's movement (so it feels responsive), and interpolation for
remote entities (so they look smooth).
- **RPC discipline:** clients send *intents* ("I want to place a wall here",
"I swung at this"), never *results*. The server validates, applies, and
broadcasts the authoritative result.
- **Scale target:** 2–16 players per server. NOT Rust's 200. That's a deliberate
scope cut — 200-player netcode is a multi-year problem on its own.
## 4. World
- **Terrain:** heightmap-based mesh, chunked. Each chunk is a mesh the server
generates deterministically from a seed, so clients can regenerate geometry
locally and the server only syncs *edits* (not the whole mesh).
- **Generation:** deterministic noise (seed → biome map → heightmap → object
placement). Deterministic = client and server agree without syncing megabytes.
- **Biomes:** start with 2–3 (meadows, forest, maybe a harsher zone) à la Valheim.
- **Streaming:** load/unload chunks around each player. Server keeps a slightly
larger radius than clients.
## 5. Entities & simulation
- Fixed-timestep simulation tick on the server (e.g. 20–30 Hz). Rendering runs at
the client's framerate, decoupled.
- Entity types: player, resource node (tree/rock), dropped item, creature,
building piece, projectile.
- Each entity has a network id; the server owns it and replicates state deltas.
## 6. Building system
- **Snap-together prefabs:** walls, floors, roofs, stairs — each with snap points.
- **Structural rules (Valheim-style):** pieces need support; stability falls off
with distance from the ground, unsupported pieces collapse. Great emergent
gameplay, and it's a clean server-authoritative calculation.
- Placement is a client *intent*; the server validates snap + support + resource
cost, then commits.
## 7. Survival systems
- Health, stamina, hunger (and later temperature/comfort like Valheim).
- Crafting: recipes (inputs → output + required crafting station + skill level).
- Inventory: grid or slot-based, server-authoritative.
- Day/night cycle + weather driving lighting and creature behaviour.
## 8. Persistence
- World save = seed + chunk edits + entity states + player inventories.
- Server writes periodic snapshots + on clean shutdown. Format: Godot resources or
a simple binary/JSON hybrid. Keep it moddable-inspectable where cheap.
## 9. Addon SDK — the differentiator (full spec in ADDON_SDK.md)
- Addons are **Lua scripts** run inside a sandboxed Lua VM embedded in the server.
- The host exposes a **deliberately limited API surface** — the only things an
addon can touch. No `os`, no `io`, no `require` of host files, no raw sockets.
- **Quotas:** instruction-count / wall-time caps per callback (so an addon can't
hang the tick), and a memory ceiling per addon VM.
- **Event model:** addons register handlers (`on_player_join`, `on_block_place`,
`on_tick`, …). The host calls them inside the sandbox with the quota enforced.
- **Content model:** addons can also *declare* data (new items, recipes, prefabs)
via manifest files the host validates before loading.
- Addons run **server-side** (authoritative). Clients receive the resulting state
like any other. (A later client-side cosmetic addon lane is possible but separate
and even more locked down.)
## 10. Why Godot 4 + GDScript here
- Free, open-source, no licensing worry, exports to all three desktop OSes.
- Godot 4's renderer (SDFGI / voxel GI, volumetric fog) is enough for the Valheim
atmosphere without expensive assets.
- GDScript keeps iteration fast for a solo dev; drop to C++ GDExtension only for
hotspots (terrain meshing, noise) if profiling demands it.
- The Lua addon VM is embedded via a GDExtension or a Lua-in-Godot addon
(e.g. `godot-luaAPI`), keeping mods off GDScript (so a mod can't call engine
internals).
## 11. Deliberate scope cuts (so this can actually ship)
- 2–16 players, not 200.
- Desktop only first (no console/mobile).
- A handful of biomes, items, creatures for the vertical slice — breadth comes later.
- No photoreal art. Low-poly + lighting only.