diff --git a/Tools/Scripts/IslandFalloff.cs b/Tools/Scripts/IslandFalloff.cs new file mode 100644 index 0000000..710d4c1 --- /dev/null +++ b/Tools/Scripts/IslandFalloff.cs @@ -0,0 +1,33 @@ +using Godot; + +/// +/// The island-falloff shaping functions (terrain-water task 11) — pure numeric +/// functions of their inputs (D-035; a named future C++ candidate, kept standalone). +/// +/// SMOOTH CREST — the mountain spine's ridge axis is the line x = centre, and +/// `1 - |x - cx|` peaks there with a slope discontinuity. Measured on the shipped +/// terrain, that crease is the single largest slope step anywhere on the map once +/// the by-design Trench walls are excluded (top 4 of 5999 columns). SmoothAbs +/// rounds the crest without moving its height. +/// +public static class IslandFalloff +{ + // ---- centre-line crest ------------------------------------------------ + // Rounding radius in normalized spine-width units (1.0 = MapSize/2 * 1.15 + // ~ 4710 px at 8K). 0.03 ~ 141 px: it cuts the crest's 1-px kink by 99.3% + // (-7.64e-04 -> -5.41e-06 raw, against a natural profile curvature of ~1.1e-07) + // while filling at most 3.9 m, decaying under 0.5 m by ~1100 px from the axis. + public const float CREST_EPSILON = 0.03f; + + /// + /// A C¹ stand-in for |d|: exactly 0 with zero slope at d = 0, and converging to + /// |d| within e²/(2|d|) away from it. Replaces the V-shaped crest of the spine + /// with a rounded one WITHOUT lowering it — SmoothAbs(0) is 0, so the peak keeps + /// its full height. + /// + public static float SmoothAbs(float d, float epsilon) + { + float a = Mathf.Abs(d); + return a * a / Mathf.Sqrt(a * a + epsilon * epsilon); + } +} diff --git a/Tools/Scripts/MapGenerator.cs b/Tools/Scripts/MapGenerator.cs index 5f1d3ba..b463852 100644 --- a/Tools/Scripts/MapGenerator.cs +++ b/Tools/Scripts/MapGenerator.cs @@ -473,12 +473,16 @@ public partial class MapGenerator : TextureRect if (distY > 0.90f) finalFalloff += (distY - 0.90f) * 15.0f; // --- 3. THE MOUNTAIN SPINE --- + // The ridge axis is the line x = centre. `1 - |x - cx|` peaks there with + // a slope discontinuity, which put the single largest slope step on the + // whole map at exactly that column (task-11 diagnostic). SmoothAbs rounds + // the crest — same peak height, continuous slope through it. float mountainSpine = 0f; - if (temperature < 0.65f) + if (temperature < 0.65f) { float distanceToCenterX = Mathf.Abs(x - center.X) / (MapSize / 2.0f * 1.15f); - mountainSpine = 1.0f - distanceToCenterX; - float southernFade = Mathf.Clamp((0.65f - temperature) * 4.0f, 0.0f, 1.0f); + mountainSpine = 1.0f - IslandFalloff.SmoothAbs(distanceToCenterX, IslandFalloff.CREST_EPSILON); + float southernFade = Mathf.Clamp((0.65f - temperature) * 4.0f, 0.0f, 1.0f); mountainSpine = Mathf.Pow(mountainSpine, 3.0f) * southernFade * 0.6f; }