feat: shared water predicates + water-bodies stage + priority-flood diagnostics (terrain-water task 03)

IsWaterPixel/IsOceanPixel/IsLakePixel are the single per-pixel water
truth; AssignBiomesAndDraw's water branch now calls them (verbatim
rules — behavior-preserving, proven by the bit-identical-biomes oracle
at acceptance). New IdentifyWaterBodies stage between the masks and
biomes: ocean = body 1, lakes labeled 2..N with CalculateTrueOcean's
4-connectivity in deterministic scan order; one transitional surface
level per body (GetSeaLevel at the body centroid; ocean at map
centre). 0_water snapshot painted from the stage's own outputs.

Priority-flood pit-fill (heap + pit-queue variant) runs as validated
diagnostics only — serializes nothing, asserts filled>=original and
full-map non-ascending drainage (reverse BFS, no sampling), reports
closed-basin statistics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Stewart Howe 2026-08-07 01:29:51 -04:00
parent 81f7030140
commit d296ef30c4
2 changed files with 333 additions and 3 deletions

View file

@ -36,6 +36,28 @@ namespace IslaApocalypse.Core
public string GeneratorGitHash = ""; // short hash of the generator repo, "" if unknown
}
/// <summary>
/// One water body from the blueprint's WBTB section: the ocean (exactly one, id 1)
/// or a lake (ids 2..N). SurfaceLevel is the documented TRANSITIONAL rule — one flat
/// level per body, GetSeaLevel at the body's pixel centroid under the still-live
/// latitude field; superseded when the flat-scalar sea model lands. Salinity is a
/// provisional placeholder for the future fresh/salt mechanic (ocean salt, lake fresh).
/// </summary>
public class WaterBodyInfo
{
public const byte TYPE_OCEAN = 0;
public const byte TYPE_LAKE = 1;
public const byte SALINITY_FRESH = 0;
public const byte SALINITY_SALT = 1;
public ushort Id;
public byte Type;
public byte Salinity;
public float SurfaceLevel; // raw blueprint height units
public int PixelCount;
public Vector2 Centroid; // map pixels
}
public class WorldBlueprint
{
public int MapSize;