From ed16a7f668efd4b71fc00ba459f72673fc428dd6 Mon Sep 17 00:00:00 2001 From: beezm Date: Sat, 8 Aug 2026 20:52:08 -0400 Subject: [PATCH] tune: edge warp 5 m @12/island -> 12 m @20/island (terrain-water task 10) Sized from measurement, not taste-first. |grad raw| at the K3/K4/K5 contours on seed 1375359975 is p50 0.00088 raw/px, so the first try (5 m, 12 undulations/island) displaced the shelf boundary a MEAN of 3.7 px with a roughness ratio of 1.03 -- real, and invisible at map scale. At 12 m and 20/island the boundary moves a mean 8.4 px (bench) / 9.1 px (plateau), roughness ratio 1.09, and the outline grows the notches, coves and peninsulas the sketch asked for. Measured cost at 12 m (A off vs B, same seed): lowland and toe/red bands bit-identical in both pixel count and slope -- the K2 pin holding exactly, as designed. Foothill riser p50 0.681 -> 0.676 m/px, p90 1.445 -> 1.478, max 3.09 -> 3.81. Bench p50 0.21 -> 0.232 (micro-relief included), still buildable. Peaks max identical at 6.55. Safety bound restated from "half the margin to a fixed knot" to 2/3 of the smaller adjacent band, which is the constraint that actually matters: the squeezed band never compresses below a third of its nominal width, so its slope never more than triples. That puts the ceiling at 16.45 m for the v5 knots and leaves the 12 m default real headroom if the gate says "more". Co-Authored-By: Claude Opus 5 (1M context) --- Core/Scripts/ConfigManager.cs | 4 ++-- Tools/Scripts/TerrainDetailPass.cs | 34 ++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Core/Scripts/ConfigManager.cs b/Core/Scripts/ConfigManager.cs index 78bf933..d56e0fe 100644 --- a/Core/Scripts/ConfigManager.cs +++ b/Core/Scripts/ConfigManager.cs @@ -39,10 +39,10 @@ namespace IslaApocalypse.Core // Change this if your namespace is different // of OUTPUT height. ShelfEdgeVariation is the shelf-edge warp amplitude in // metres of INPUT height — how far the shelf/riser boundary contour is // displaced, not an elevation change; it is clamped at load time to the - // largest shift that keeps the curve's knots ordered. Defaults: v1, 3 m, 5 m. + // largest shift the curve's bands can absorb. Defaults: v1, 3 m, 12 m. public static string TerrainDetail = "v1"; public static float ShelfReliefAmp = 3.0f; - public static float ShelfEdgeVariation = 5.0f; + public static float ShelfEdgeVariation = 12.0f; public static void LoadConfig() { diff --git a/Tools/Scripts/TerrainDetailPass.cs b/Tools/Scripts/TerrainDetailPass.cs index 3b6f439..3687db3 100644 --- a/Tools/Scripts/TerrainDetailPass.cs +++ b/Tools/Scripts/TerrainDetailPass.cs @@ -34,19 +34,31 @@ public static class TerrainDetailPass // Pass B — shelf-edge variation. The amplitude is stated in metres of INPUT // height (raw × 251): it is how far, in raw-height terms, a shelf boundary - // contour is displaced — not an output elevation change. Lateral wander on - // the map is that displacement divided by the local raw gradient. - public const float EDGE_AMP_DEFAULT_M = 5f; // config dial: ShelfEdgeVariation (metres of input height) - public const float EDGE_FREQ_ISLANDS = 12f; // ~12 undulations per island width — a handful of notches - public const int EDGE_SEED_OFFSET = 7507; // per shelf perimeter, not hundreds of teeth - public const float EDGE_SAFETY_FRACTION = 0.5f; // shift ≤ half the smallest margin to a fixed knot + // contour is displaced — not an output elevation change. What the eye sees is + // the LATERAL wander, which is that displacement divided by the local raw + // gradient. Measured on seed 1375359975: |∇raw| at the K3/K4/K5 contours is + // p50 0.00088 raw/px, so 12 m of input height buys a median peak displacement + // of ~54 px and a mean of ~8 px along the boundary — coves and notches, which + // is where the developer's sketch sits. 5 m (the first try) moved the boundary + // a mean 3.7 px and was invisible at map scale. + public const float EDGE_AMP_DEFAULT_M = 12f; // config dial: ShelfEdgeVariation (metres of input height) + public const float EDGE_FREQ_ISLANDS = 20f; // ~410 px wavelength at 8K — coves and notches at the + public const int EDGE_SEED_OFFSET = 7507; // scale of the sketch, not a fringe of teeth + + // The shift squeezes whichever of the foothill riser / plateau bands it moves + // into. Bounding it at 2/3 of the smaller band means that band never compresses + // below a THIRD of its nominal width — i.e. its slope never more than triples, + // even where peak noise lands on a boundary. That is the real constraint; knot + // ordering follows from it. + public const float EDGE_SAFETY_FRACTION = 2f / 3f; /// - /// The largest per-column knot shift this preset can take while keeping the - /// knot set strictly ordered (K2 < K3+d, K5+d < K6) with margin to spare. - /// K1/K2/K6 never move, so the toe, the orange/red bands and the summit spike - /// are bit-identical whatever the warp does — which is what makes the - /// red-ceiling and peak-height guarantees exact rather than statistical. + /// The largest per-column knot shift this preset allows: bounded by the band + /// squeeze above, which also keeps the knot set strictly ordered + /// (K2 < K3+d, K5+d < K6) with a third of each band to spare. K1/K2/K6 never + /// move, so the toe, the orange/red bands and the summit spike are + /// bit-identical whatever the warp does — which is what makes the red-ceiling + /// floor and the 420 m cap exact rather than statistical. /// public static float MaxEdgeShift(CurveKnots k) {