# Server Module Authoritative world building. Turns the static `WorldBlueprint` in RAM into physical 3D chunks. In a future multiplayer setup this is the side that dictates terrain and ships chunk data to clients. ## `ServerChunkManager.cs` Attached to the `World` root node of `Scenes/Main.tscn`. Runs the whole 3D world at boot. ### Startup 1. Loads `ServerConfig.json` and the seed's `.dat` blueprint (v2 or legacy v1 — the parser dispatches automatically; see `Core/Scripts/BLUEPRINT_FORMAT.md`). 2. **Cross-checks the blueprint's embedded params** (v2 only) against the config and logs a prominent `BLUEPRINT/CONFIG DESYNC` warning if the seed or MapSize disagree — a config edited after generation is loud now, not silent. 3. **Finds the Capitol** in the parsed town list and uses it as the world origin point. 4. Converts its pixel position to chunk coordinates (`pixel / CHUNK_SIZE`). 5. Builds a `(2 × ChunkRadius)²` grid of chunks around it — **synchronously, all at boot**. 6. Teleports the `Camera3D` to 120 m above the Capitol, looking down. ⚠ **Two things to know about startup.** The chunk grid is built in one blocking pass with no streaming or unloading, so `ChunkRadius` directly controls boot cost — 32 means 4,096 chunks and roughly 3.6 GB. And the camera `LookAt` points straight down, which is a degenerate case: the up vector ends up parallel to the view direction, so camera roll is undefined and Godot logs a warning. ### Per-chunk generation - **Road culling first.** Only the road segments whose bounding box reaches this chunk are kept, each tagged with its `RoadTier`. The padding is derived from the widest shoulder any tier has plus a margin, so widening a road cannot silently truncate it at chunk edges. - **Water per column** (tasks 13, 15) — the blueprint is the **authority** on where water is and at what level; the server only reads it. `WSRF` gives the surface level per pixel, and the `WBTB` body table is the fallback when a column is flagged wet but carries the `WSRF` no-water sentinel. **Presence takes two clauses.** `WBID` (the water stage's own classification output) OR *the rendered ground being under the ocean's surface*. The second exists because `WBID` was classified from the **uncurved** heightmap while the mesh renders the **curved** one. Outside the crater those agree exactly — the curve is identity at sea and monotonic, so `Apply(raw) < sea` iff `raw < sea`. Inside it they do not: the carve lerps two different bases toward one target (classify from `raw`, rendered from `Apply(raw)`, and `Apply(raw) < raw` in the lowland band), so the rendered surface sinks faster and leaves a ring rendering below the waterline that `WBID` still calls dry — 375,824 px on the C1 seed, all of it inside the carve. The second clause tests the height the mesh actually uses against the **ocean body's own level from `WBTB`**, so the runtime still derives nothing, and by the identity above it can only ever fire inside the carve. A body the table does not know leaves the column **dry** rather than guessing a level. The level is scaled by the same `HEIGHT_SCALE` as the terrain, so the sheet and the seabed cannot drift apart. Depth for shading is taken from **blueprint** heights, not rendered geometry — the terrain render clamps its floor at `Y = 2`, which would otherwise flatten every deep-ocean column to one value. Each run logs what it drew (`[Server] Water at rest: …`). - **Surface height per column** (`GetExactSurface`) — the blueprint height scaled into the chunk's usable vertical band, then modified by any road carving. - **Density per voxel** — `(y − surfaceY)` normalised by the local slope, giving a signed distance to the surface. Positive above, negative below. - **Block IDs per voxel** via `BiomePalette`, plus the per-column data the renderer needs. - Hands the finished chunk to a `ChunkRenderer`. ### Road carving All four tiers carve, each with its own character (widest and smoothest for highways, narrow and terrain-hugging for trails — values in `Constants.cs`). For each column, the carve finds **the nearest road whose shoulder actually reaches it** — not simply the nearest road, since tiers have different reach and a nearby footpath must not shadow a highway still covering the column. It then reads the roadbed height at the closest point *along* that segment, blending between a straight ramp between the segment's endpoints ("holds a grade") and the terrain directly beneath ("hugs the land") according to the tier. Inside the road radius the column is flattened to that height and flagged with the tier's surface material; out to the shoulder radius it eases back to natural ground with a smoothstep. `HeightAtPixel` samples the heightmap **bilinearly** — road path points are fractional, and nearest-cell sampling produced a metre-scale staircase along the roadbed. ## Not here yet No chunk streaming or unloading, no collision, no networking, no player. The "server" is currently a node in the same scene as the renderer — the server/client split is structural, not a process boundary.