From 200adcaf5af1c1344dfeb96009d44e564179bea9 Mon Sep 17 00:00:00 2001 From: beezm Date: Fri, 7 Aug 2026 06:20:48 -0400 Subject: [PATCH] feat: config-gated flat-scalar sea level (D-033, terrain-water task 04) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SeaLevelModel: "flat" (one scalar, SeaLevelValue) or "field" (the legacy latitude Lerp 0.26..0.15). Only GetSeaLevel's body changes — all nine call sites (crater carve target, both flood fills, biome split, beach band, Capitol window, town filters, A* zero-point) inherit the model automatically; no consumer re-tuning. Default: flat 0.15, pinned in ServerConfig.json. Co-Authored-By: Claude Fable 5 --- Core/Scripts/ConfigManager.cs | 21 +++++++++++++++++++++ ServerConfig.json | 4 +++- Tools/Scripts/MapGenerator.cs | 8 +++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Core/Scripts/ConfigManager.cs b/Core/Scripts/ConfigManager.cs index 36800e9..35e77c7 100644 --- a/Core/Scripts/ConfigManager.cs +++ b/Core/Scripts/ConfigManager.cs @@ -19,6 +19,13 @@ namespace IslaApocalypse.Core // Change this if your namespace is different // not a shippable world. Default false. public static bool SkipRoads = false; + // Sea-level model (D-033, terrain-water task 04): "flat" = one scalar sea + // level everywhere (SeaLevelValue); "field" = the legacy latitude Lerp + // (0.26 north .. 0.15 south). Generator-only — the runtime never computes + // sea level. Default: flat 0.15. + public static string SeaLevelModel = "flat"; + public static float SeaLevelValue = 0.15f; + public static void LoadConfig() { string path = "res://ServerConfig.json"; @@ -74,6 +81,20 @@ namespace IslaApocalypse.Core // Change this if your namespace is different SkipRoads = (bool)data["SkipRoads"]; } + // Extract the sea-level model + if (data.ContainsKey("SeaLevelModel")) + { + string model = (string)data["SeaLevelModel"]; + if (model == "flat" || model == "field") + SeaLevelModel = model; + else + GD.PrintErr($"[ConfigManager] Unknown SeaLevelModel '{model}'. Keeping '{SeaLevelModel}'."); + } + if (data.ContainsKey("SeaLevelValue")) + { + SeaLevelValue = (float)data["SeaLevelValue"]; + } + switch (profile) { case "4K": diff --git a/ServerConfig.json b/ServerConfig.json index b9af832..7949049 100644 --- a/ServerConfig.json +++ b/ServerConfig.json @@ -2,5 +2,7 @@ "WorldSeed": 1409879727, "MapProfile": "8K", "TownDensity": "Normal", - "ChunkRadius": 32 + "ChunkRadius": 32, + "SeaLevelModel": "flat", + "SeaLevelValue": 0.15 } diff --git a/Tools/Scripts/MapGenerator.cs b/Tools/Scripts/MapGenerator.cs index f2fb4e0..a281436 100644 --- a/Tools/Scripts/MapGenerator.cs +++ b/Tools/Scripts/MapGenerator.cs @@ -1212,7 +1212,13 @@ public partial class MapGenerator : TextureRect return astar.GetPointPath(from, to); } - private float GetSeaLevel(float t) => Mathf.Lerp(0.26f, 0.15f, Mathf.Clamp(t, 0f, 1f)); + // Sea-level model gate (D-033, task 04): "flat" returns the configured scalar; + // "field" is the legacy latitude Lerp. Pure numeric mapping either way (D-035); + // all nine call sites inherit whichever model config selects. + private float GetSeaLevel(float t) => + ConfigManager.SeaLevelModel == "flat" + ? ConfigManager.SeaLevelValue + : Mathf.Lerp(0.26f, 0.15f, Mathf.Clamp(t, 0f, 1f)); private Vector2I FindClosestPixel(Vector2 pos, HashSet set) { Vector2I closest = new Vector2I(0,0); float min = float.MaxValue;