Every README was read first, checked against the code in its directory, then rewritten to describe what the code actually does now. Corrected throughout: map size is config-driven (8192 default) not a fixed 4096; chunks are 24x24x256 not 32x32; road carving is implemented for all four tiers, not a 'next step'; Data/ and Resources/ are empty, not populated. Also fixed MATH_MARCHING_CUBES.md, which documented the density sign convention exactly backwards — it claimed positive was underground, where the code treats positive as above the surface and counts a corner inside when density < iso. Getting that backwards inverts every normal, a bug this project has hit before. The root README now carries accurate run steps: F5 runs the map generator (not the game), F6 on Scenes/Main.tscn runs the 3D world, and ChunkRadius is a load radius that should be dropped to 4-8 while iterating. Docs only. No code changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
52 lines
3 KiB
Markdown
52 lines
3 KiB
Markdown
# 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.
|
||
2. **Finds the Capitol** in the parsed town list and uses it as the world origin point.
|
||
3. Converts its pixel position to chunk coordinates (`pixel / CHUNK_SIZE`).
|
||
4. Builds a `(2 × ChunkRadius)²` grid of chunks around it — **synchronously, all at boot**.
|
||
5. 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.
|
||
- **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.
|