M0 scaffold: Godot 4 survival game skeleton + architecture/addon-SDK docs

This commit is contained in:
dev
2026-11-03 22:23:20 +00:00
commit 180b776392
13 changed files with 724 additions and 0 deletions

116
docs/ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,116 @@
# 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.