# Client Module The visual layer. Takes finished chunk data and turns it into Godot nodes. It calculates nothing — no densities, no terrain, no collision. ## `ChunkRenderer.cs` A `MeshInstance3D` created per chunk by the server, which then calls `RenderChunk(data)`. - **Mesh generation.** Calls `MarchingCubes.GenerateMesh()`, passing the density field, the block IDs, and the per-column data the mesher needs to colour correctly: the true (unrounded) surface heights, the biome per column, and the road surface material per column. - **Vertex colouring.** Creates a `StandardMaterial3D` with `VertexColorUseAsAlbedo = true`, so Godot renders the per-vertex colours the mesher assigned rather than a texture. Colours fade between materials across a tunable band instead of switching at whole-metre steps. - **World positioning.** `ChunkPosition × CHUNK_SIZE × VOXEL_SCALE` on X and Z, `y = 0` — chunks are placed by their footprint and carry their full height internally. - **Backface rendering.** `CullMode` is disabled, so the world is still visible from underneath or from inside terrain. - **Water at rest** (task 13). `BuildWaterSurface` adds a second `MeshInstance3D` as a child, a flat sheet at each cell's water level, from the per-column water data the server read out of the blueprint. Skipped entirely for chunks with no water. **Why a separate mesh rather than a water block.** The terrain is a Marching-Cubes iso-surface over the density field. Putting water into that field would not lay a sheet on top of the seabed — it would move the iso-surface, fusing the sea into the terrain as if it were solid ground. A second surface is the only way water can sit at *its* level independent of the ground beneath it. That also makes translucency nearly free: a distinct `MeshInstance3D` carries its own `StandardMaterial3D`, so alpha is one flag and Godot sorts transparent surfaces after opaque ones itself. Colour and alpha both ramp with depth (shallow teal and clearer → deep navy and near opaque), so the shelved coast stays readable. Water is **flat and static** — no waves, no displacement, no animation. Those are Phase C2+. ## Notes - **One material instance per chunk.** Each renderer builds its own `StandardMaterial3D`. Since they are all identical, a single shared material would do — an easy win whenever performance work starts. - Chunk positioning is relative to this node's parent, so **moving the `World` node in the scene moves the entire rendered world** with it. ## Not here yet No textures or UV mapping (raw vertex colour only), no LOD, no player, no UI, no input handling.