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