using System;
namespace IslaApocalypse.Tools
{
///
/// ⭐ COASTAL FRAGMENTATION (chat2/09, EXPLORATION) — a perimeter-wide, band-limited, zero-mean noise
/// on the PRE-power falloff, applied only inside the coastal window.
///
/// ═══ WHY A DEDICATED TERM AND NOT THE EDGE NOISE SCALED ═══
///
/// Pass 1's edge noise is (noise+1)/2 · 0.15 · squircle: positive-only (it only ever PUSHES
/// the falloff up), modulated by the squircle (strongest at the rim, zero at the centre), sampled at
/// 2.5× the base frequency. Scaling it would roughen the whole rim and bias the coast inward; it is
/// the coastline's jitter, not a margin-targeted cutter. This term is separate: its own deterministic
/// field (seed offset + a coordinate offset in map widths), its own frequency (the neck/lobe scale),
/// zero-mean (it bites AND builds, so the coast is redrawn rather than eroded), and weighted by a
/// smooth WINDOW on the falloff value itself:
///
/// w(f) = 1 − smoothstep(|f − centre| / halfWidth) (exactly 0 beyond ± halfWidth)
/// falloff += amp · w(f) · noise(x + off, y + off) noise ∈ [−1, 1]
///
/// The coast sits where rawBase − falloff^2.5 crosses sea, i.e. near f ≈ 0.66 for a median rawBase
/// (chat2/08 diagnosis), so a window centred there covers the barely-land / barely-sea margin
/// around the whole perimeter, north and south. Cells whose falloff is clear of the window — the
/// interior, the massif, the deep sea — get w = 0 and are bit-identical by construction (asserted).
///
/// SELF-TARGETING: every lobe hangs off a neck of barely-land, cells whose height sits a hair above
/// sea. A bite of the same Δfalloff flips those first; solid land inside the window (a coastal hill)
/// moves in height but does not flip. No neck is detected; the margin selects itself. Amplitude is
/// the ladder; frequency is fixed and exposed as the secondary dial.
///
public static class CoastalFragment
{
/// Periods per map width. The base noise is ≈ 4/map, the edge noise ≈ 10/map; lobes in the 08 plates are 2–7 % of the map. Chosen by the chat2/09 probe.
public const float DefaultFreqPerMapWidth = 12f;
/// The coastal window's centre in pre-power falloff units (the coast's falloff for a median base noise).
public const float DefaultBandCentre = 0.66f;
/// Half-width of the window. 0.18 spans f ∈ [0.48, 0.84] — the whole fringe, nothing of the interior.
public const float DefaultBandHalfWidth = 0.18f;
/// Bites only by default? Set by the chat2/09 probe (see the report): zero-mean redraws the margin and can bridge islands back; bites-only only cuts.
public const bool DefaultBitesOnly = false;
/// The field's seed offset (a SEED offset, like the islet layer's 7607).
public const int SeedOffset = 9109;
/// The field's coordinate offset, IN MAP WIDTHS (D-059) — decorrelates it from the base field's realization at every size.
public const float OffsetMapWidths = 0.37f;
/// The window weight for a pre-power falloff value.
public static float Window(float falloff, float centre, float halfWidth)
{
float t = MathF.Abs(falloff - centre) / halfWidth;
if (t >= 1f) return 0f;
return 1f - t * t * (3f - 2f * t);
}
}
}