feat: submarine coast shelf + elongation dials (terrain-water task 11)
COAST. The task's premise -- "the island edge is the steepest part" -- is
right, and the diagnostic locates it precisely: it is the SEABED, not the
land. HeightCurve.Apply returns early at and below sea level, so tasks
05-09 reshaped the land and never touched the water. Measured on the same
seed, distance-from-shore vs height:
land reaches 10 m seabed reaches 10 m gradient
curve OFF 31 px 31 px 0.254/0.258
curve ON (ships) 186 px 31 px 0.038/0.258
So the landward side is ALREADY the broad shallow shelf terrain_design.md
asks for -- 54% of the island sits under 14 m -- and flattening it further
would only make it mushy. What is left is a shoreline that shelves gently
on land and then drops 6.7x steeper the moment it goes under.
CoastShelf fixes that side: depth' = depth * (1 - 0.775*exp(-depth/100 m)).
The seabed leaves the waterline at 22.5% of its former gradient and
recovers smoothly, so deep water and the Trench keep their shape. Measured
after: 5 m depth at 43 px (was 15), 10 m at 75 (was 31), 30 m at 150 (was
94) -- a 2.4-2.9x wider shallows.
It is strictly positive for positive depth, so it CANNOT move the waterline
by one pixel. Biomes and water bodies come out bit-identical, which is why
the coast is separable from elongation in the batch rather than tangled
with it -- contrary to the task's expectation that all coast work moves
biomes.
ELONGATION. IslandAxisX/Y replace the 1.15/0.90 literals (the spine shares
AxisX, as it always shared the literal). Sized by replaying candidate
falloffs against real terrain rather than guessing -- the replay reproduces
the shipped extents exactly, bbox and land count.
That replay says the task's suggested 1.30/0.85 buys +2.0% aspect, because
THE ISLAND IS ALREADY TRENCH-CLAMPED IN X: it spans 90.5% of the map width,
and 1.15 -> 1.40 moves the west coast only 393 -> ~360 px. Aspect responds
almost entirely to AxisY, which costs land:
1.30/0.85 +2.0% aspect +2.9% land 1.30/0.80 +4.9% -2.2%
1.30/0.82 +3.7% aspect -0.1% land 1.30/0.75 +11.5% -7.3%
Default 1.30/0.78 -- a visible step (+~8% aspect, measured 1.137 -> 1.200)
at ~4% land. The developer's eye tunes it from the batch; the table above
is the price list.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
896a428d47
commit
566abe9784
3 changed files with 105 additions and 9 deletions
|
|
@ -44,6 +44,27 @@ namespace IslaApocalypse.Core // Change this if your namespace is different
|
|||
public static float ShelfReliefAmp = 3.0f;
|
||||
public static float ShelfEdgeVariation = 12.0f;
|
||||
|
||||
// Island falloff shaping (task 11).
|
||||
//
|
||||
// CoastProfile: "wide" adds the submarine shelf. The height curve is identity
|
||||
// at and below sea, so it never reached the seabed — measured, land rises from
|
||||
// the shoreline at 0.038 m/px while the seabed drops at 0.258 m/px. "steep" is
|
||||
// the pre-task-11 seabed, kept for A/B. The shelf cannot move the waterline, so
|
||||
// biomes and water are bit-identical either way. Default: wide.
|
||||
//
|
||||
// IslandAxisX/Y: the falloff axis ratios (pre-task-11: 1.15 / 0.90). NOTE,
|
||||
// measured: the island is already Trench-clamped in x at ~90% of the map width,
|
||||
// so AxisX is a weak lever — aspect responds almost entirely to AxisY, which
|
||||
// trades against land area. These MOVE THE COASTLINE, so they move biomes by
|
||||
// design; elongated seeds have a new biome baseline.
|
||||
public static string CoastProfile = "wide";
|
||||
public static float IslandAxisX = 1.30f;
|
||||
public static float IslandAxisY = 0.78f;
|
||||
|
||||
// The pre-task-11 axis ratios, so legacy/steep runs can restore them exactly.
|
||||
public const float LEGACY_AXIS_X = 1.15f;
|
||||
public const float LEGACY_AXIS_Y = 0.90f;
|
||||
|
||||
public static void LoadConfig()
|
||||
{
|
||||
string path = "res://ServerConfig.json";
|
||||
|
|
@ -147,6 +168,27 @@ namespace IslaApocalypse.Core // Change this if your namespace is different
|
|||
ShelfEdgeVariation = (float)data["ShelfEdgeVariation"];
|
||||
}
|
||||
|
||||
// Extract the island-falloff dials (task 11)
|
||||
if (data.ContainsKey("CoastProfile"))
|
||||
{
|
||||
string coast = (string)data["CoastProfile"];
|
||||
if (coast == "steep" || coast == "wide")
|
||||
CoastProfile = coast;
|
||||
else
|
||||
GD.PrintErr($"[ConfigManager] Unknown CoastProfile '{coast}'. Keeping '{CoastProfile}'.");
|
||||
}
|
||||
if (data.ContainsKey("IslandAxisX")) IslandAxisX = (float)data["IslandAxisX"];
|
||||
if (data.ContainsKey("IslandAxisY")) IslandAxisY = (float)data["IslandAxisY"];
|
||||
|
||||
// The axis ratios divide map extents; a zero or negative one is a divide-by-
|
||||
// zero that would silently produce an all-ocean map. Refuse it loudly.
|
||||
if (IslandAxisX <= 0.01f || IslandAxisY <= 0.01f)
|
||||
{
|
||||
GD.PrintErr($"[ConfigManager] IslandAxisX/Y must be > 0.01 (got {IslandAxisX}/{IslandAxisY}). Restoring legacy {LEGACY_AXIS_X}/{LEGACY_AXIS_Y}.");
|
||||
IslandAxisX = LEGACY_AXIS_X;
|
||||
IslandAxisY = LEGACY_AXIS_Y;
|
||||
}
|
||||
|
||||
switch (profile)
|
||||
{
|
||||
case "4K":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue