feat: stepped river water + widen + lake-ender join + the task-22 nits (terrain-water task 23, C0b finale)
THE PAYOFF: rivers now carry water. Each carved main river becomes a chain of stepped flat water-body reaches — a new reach every RiverStepDropM (2 m) of bed descent, sitting RiverWaterDepthM (1.2 m) above its bed, strictly descending to the outlet. Reaches are ordinary water bodies (WBID cells + WBTB type 2 'river', fresh; WSRF derives from body levels as ever), so river water renders through the C1 path with the task-15 presence rule at its banks, untouched. Existing bodies are never overwritten — a river MEETS its lake or the sea. Measured on 1280587109: 298 reaches across 6 rivers, 184,620 wet px, levels stepping 278 m down to 39.5 m; in-engine, one valley frame renders surfaces 46.2-114.5 m. Beds widened (RiverWidthScale default 1.75). Lake-enders: the stem's pooling terminal IS a local minimum, so the first extension attempt (blind steepest descent) dead-ended in 0 steps — replaced with the lowground Dijkstra to the nearest classify-water cell; the E-lagoon river now joins its lake (87 px). Smoothing is applied ONLY to lowland routes: smoothing upland stems moved them off their carved valley floors into the walls (max cut 14.6 -> 27.3 m measured; split restores valley-floor fidelity). TYPE_RIVER added to the WBTB registry (parser validation extended; doc updated in the docs commit). Task-22 nits fixed: max-cut is now CUMULATIVE vs the pre-pass surface (the honest number: p95 carve 7.0 m; 339 cells island-wide exceed 20 m — localized outlet-gorge notches where stems cross deposit ridges, deepest 26 m); and 0_height/0_water are re-drawn and re-captured AFTER the river pass so the exported snapshots show beds and water. Guards: flood guard holds (water pixels unchanged around the carve; the water stage touches no heights), BIOME oracle md5-identical to the task-22 baseline, 0_water changed (that IS the river water), island top 457.65 m exact, crater core excluded. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
148602b4c5
commit
8f5767308a
4 changed files with 210 additions and 13 deletions
|
|
@ -119,9 +119,16 @@ namespace IslaApocalypse.Core // Change this if your namespace is different
|
|||
// absolute floor above sea — the erosion flood-guard discipline: no river
|
||||
// bed may create inland below-sea cells, so the rendered coastline cannot
|
||||
// move even with rivers carved.
|
||||
// RiverStepDropM/RiverWaterDepthM (task 23): the stepped-water dials — each
|
||||
// river is a chain of flat water-body reaches; a new reach starts every
|
||||
// StepDrop metres of bed descent and sits WaterDepth metres above its bed.
|
||||
// Smaller drop = more, finer steps = smoother water (the smoothing dial;
|
||||
// tilted continuous-slope water is the deferred model B).
|
||||
public static string Rivers = "off";
|
||||
public static string RiverRoutingStyle = "lowground";
|
||||
public static float RiverWidthScale = 1.0f;
|
||||
public static float RiverWidthScale = 1.75f; // widened at the task-23 gate's ask
|
||||
public static float RiverStepDropM = 2.0f;
|
||||
public static float RiverWaterDepthM = 1.2f;
|
||||
public static float RiverDepthScale = 1.0f;
|
||||
public static float RiverSeaMargin = 0.2f; // m above sea, bed floor
|
||||
|
||||
|
|
@ -330,6 +337,10 @@ namespace IslaApocalypse.Core // Change this if your namespace is different
|
|||
if (data.ContainsKey("RiverWidthScale")) RiverWidthScale = (float)data["RiverWidthScale"];
|
||||
if (data.ContainsKey("RiverDepthScale")) RiverDepthScale = (float)data["RiverDepthScale"];
|
||||
if (data.ContainsKey("RiverSeaMargin")) RiverSeaMargin = (float)data["RiverSeaMargin"];
|
||||
if (data.ContainsKey("RiverStepDropM")) RiverStepDropM = (float)data["RiverStepDropM"];
|
||||
if (data.ContainsKey("RiverWaterDepthM")) RiverWaterDepthM = (float)data["RiverWaterDepthM"];
|
||||
RiverStepDropM = Mathf.Clamp(RiverStepDropM, 0.25f, 10f);
|
||||
RiverWaterDepthM = Mathf.Clamp(RiverWaterDepthM, 0.2f, 5f);
|
||||
RiverWidthScale = Mathf.Clamp(RiverWidthScale, 0.1f, 5f);
|
||||
RiverDepthScale = Mathf.Clamp(RiverDepthScale, 0.1f, 5f);
|
||||
RiverSeaMargin = Mathf.Clamp(RiverSeaMargin, 0f, 5f);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ namespace IslaApocalypse.Core
|
|||
{
|
||||
public const byte TYPE_OCEAN = 0;
|
||||
public const byte TYPE_LAKE = 1;
|
||||
public const byte TYPE_RIVER = 2; // task 23: a stepped river REACH (one flat level)
|
||||
public const byte SALINITY_FRESH = 0;
|
||||
public const byte SALINITY_SALT = 1;
|
||||
|
||||
|
|
@ -432,7 +433,7 @@ namespace IslaApocalypse.Core
|
|||
body.SurfaceLevel = reader.ReadSingle();
|
||||
body.PixelCount = reader.ReadInt32();
|
||||
body.Centroid = new Vector2(reader.ReadSingle(), reader.ReadSingle());
|
||||
if (body.Type > WaterBodyInfo.TYPE_LAKE)
|
||||
if (body.Type > WaterBodyInfo.TYPE_RIVER)
|
||||
{
|
||||
GD.PrintErr($"[MapDataParser] ERROR: water body {i} has unknown type {body.Type}.");
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue