From 896a428d47f443218fd9fddd13875c55b1d21746 Mon Sep 17 00:00:00 2001 From: beezm Date: Sat, 8 Aug 2026 23:28:45 -0400 Subject: [PATCH] fix: round the mountain-spine crest, the real centre line (terrain-water task 11) The faint mid-map ridge is NOT the squircle/ellipse falloff blend that the task suspected. Measured, read-only, before touching anything: bare falloff, slope step at centre +2.05e-07 (SMALLER than the off-axis controls +2.36e-06 / +3.05e-06 -- Pow(2.5) crushes it, because the falloff is ~0 there) mountain spine, slope step at centre -7.58e-04 (170x the controls) On real terrain, with the by-design Trench walls excluded, x = 4096..4099 hold the top FOUR slope-step locations out of 5999 columns. Column-mean height runs 109.6 -> 135.5 -> 110.7 m across it: a symmetric ridge peaking exactly on the centre column. Not the noise domain either -- the noise is sampled over [0, MapSize], so coordinate zero is at the map CORNER. And not seed-dependent: present on all 10 seeds checked, 6 positive AND 4 negative (ranks 0, 18, 0, 83), so the "positive seeds only" impression does not hold. Cause: the spine is Pow(1 - |x - cx|, 3), and |.| peaks at the axis with a slope discontinuity of magnitude 2. SmoothAbs replaces |d| with d^2/sqrt(d^2+e^2) -- zero with zero slope at the axis, converging to |d| away from it -- so the crest rounds without dropping. e = 0.03 (~141 px) cuts the 1-px kink by 99.3% (-7.64e-04 -> -5.41e-06, against a natural profile curvature of ~1.1e-07), fills at most 3.9 m, and decays under 0.5 m by ~1100 px. DEFERRED, reported not fixed: the spine's AXIS is still hard-coded dead straight down x = centre for the full map height. That is what the derivative render actually shows -- everything west of centre slopes east, everything east slopes west. Rounding the crest does not make the range meander. Per the task's "fix only if trivial, else report and defer" rule, and confirmed with the developer, the axis is left alone: a wandering spine is a world-shape change that rebaselines biomes on every seed, and it deserves its own task and its own gate. Co-Authored-By: Claude Opus 5 (1M context) --- Tools/Scripts/IslandFalloff.cs | 33 +++++++++++++++++++++++++++++++++ Tools/Scripts/MapGenerator.cs | 10 +++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 Tools/Scripts/IslandFalloff.cs 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; }