islaApocalypse-v2/Core/README.md
beezm 89e0f85c9f chat2/12: drainage analysis (minimal-first) — the reference river plan ported, analysis only, on the eroded terrain
Core/Scripts/DrainageAnalysis.cs is the reference's DrainageAnalysis ported verbatim: the
Barnes priority-flood routing fill (8-connected, seeded from the four borders, index
tiebreak, pit fills ONE ULP above the parent so every filled cell keeps a strictly
descending path to its spill; the terrain heightmap itself is never written - the fill lives
in its own array), terminal-basin qualification (depth >= 2 m AND area >= 10,000 px; the rest
are pits filled through), D8 flow directions on the routing surface - FOR ANALYSIS ONLY, the
reverted-as-carving landmine stated in the file - Kahn accumulation, the memoised destination
walk crediting a terminal basin with TOTAL inflow, sea-reaching outlets ranked by drainage
area with the outlet separation, main stems by max accumulation, mountain exits from the
along-stem grade, lean tributaries, lean endorheic terminals, and the promoted giants
(provisional routes computed as the reference did, not drawn - routing is a later task).
WorldScale-denominated; Dir / Acc / Filled / FullFilled / BasinId / BasinInflow exposed so the
caller can prove the invariants.

"The sea" is the OCEAN body from the region layer: RegionLabeling.OceanMask - the 4-connected
water component touching the border, on the CLASSIFY field (the water-side complement of the
land contract). Enclosed lagoons, lake beds and island-fringe pockets are ordinary terrain to
the router.

DrainageTool (4 task-11 seeds at 8192, the eroded fields bit-identical to the 11 dumps)
renders the log-scaled accumulation map and the promoted-candidates overlay (trunks cyan,
endorheic giants orange, lean terminals red; nothing carved) and writes the accumulation
.f32. Oracle, all passing: render AND classify fields bit-identical before/after the analysis
(zero terrain cells written), no water added, full fill >= original everywhere with a
non-ascending path to the border from every cell, ocean mask all below sea and on the border,
dir/acc/candidates identical across two runs.

Endorheic basins are the expected first-class output: on every seed the top giants out-drain
the top trunks - the biggest drainages pool inland because erosion delivers the upland network
only and cannot cross the flats.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EY3ZTF6NwzF8ukBHQXSK7
2026-08-22 20:51:51 -04:00

6 KiB

Core — math and data only

Holds: the column model, the material schemas, the scaling discipline, tooling path resolution and the file-safety rails. Constants and contracts.

Boundary: Core depends on nothing above it. Not on Server/, not on Client/, not on Tools/. The dependency arrow points one way into this folder and never out of it.

⚠ Additional boundary, tighter than the layer rule: Core is engine-free.

No using Godot; anywhere in this folder. Core is plain C# — no Node, no GD.Print, no ProjectSettings, no engine types in any signature.

Two reasons, both load-bearing. (1) D-049 commits to "C# for fast iteration, with C++-ready seams… port path-by-path when settled and hot" — the hot paths that get ported first are exactly the ones in here, and a type that names Godot.Vector2 cannot cross that seam. (2) It keeps the column model testable and reviewable without standing up an engine.

Where Core genuinely needs something the engine knows — the resolved user:// directory — the engine layer hands it in (ToolingPaths.Configure), rather than Core reaching for it. If you find yourself wanting an engine type here, the type belongs one layer up.

What is in here

File What it is
Scripts/Column.cs ★★ The load-bearing contract (D-053). A column as run-length bands; MaterialRun; RunOrigin. Read its header before touching anything that stores world data.
Scripts/ColumnGrid.cs The 2D grid of columns. Shape only — chunking and streaming are later phases.
Scripts/MaterialKey.cs Material identity — a registry key, never an ordinal.
Scripts/TerrainMaterial.cs A row in the terrain schema (D-054).
Scripts/BuildingMaterial.cs A row in the building schema (D-054).
Scripts/MaterialRegistry.cs Both registries, append-only, seed rows only.
Scripts/RecipeRegistry.cs The transformation seam — deliberately empty.
Scripts/GenerationScale.cs The scaling discipline. MapSize, ScaleFactor, normalized offsets, the two frequency conventions.
Scripts/WorldScale.cs The vertical yardstick. The ONE metres↔raw conversion (251 m/unit). No literal 251f anywhere else.
Scripts/HeightCurve.cs The height-redistribution curve (v5), 7 bands. Identity at and below sea.
Scripts/CurveKnots.cs The six INPUT knots — percentiles of the measured land CDF, plus the reference's for comparison.
Scripts/CurveAnchors.cs The OUTPUT anchors — the storm-ladder elevations each band lands at.
Scripts/TerrainDetailPass.cs Shelf micro-relief + the shelf-edge knot warp. Output-height only.
Scripts/HydraulicErosion.cs Droplet (hydraulic) erosion (chat2/11) — the reference's pass ported VERBATIM: four governors (count, lifetime, carve cap, deposit cap) on a net-displacement ledger proven on exit, the sea clamp (below-sea read-only both ways), the cone brush shared by erode and deposit, the crater exclusion (inert until the carve exists). Engine-free, own PCG32, WorldScale-denominated (no literal 251). Render-map only — the caller (Tools/ErosionPass) owns the split and the flood guard.
Scripts/DrainageAnalysis.cs Drainage analysis (chat2/12) — the reference's river-PLAN pass ported verbatim: priority-flood routing fill (one ulp above the parent, terrain never written), D8 flow directions FOR ANALYSIS ONLY (D8 was reverted as a carving technique), Kahn accumulation, outlets ranked by drainage area, endorheic terminals credited TOTAL inflow, promoted giants. Engine-free, WorldScale-denominated. "The sea" = the ocean body from RegionLabeling.OceanMask.
Scripts/RegionLabeling.cs The region-labeling layer (chat2/07) — shared infrastructure. 8-connected land components on the CLASSIFY field; mainland = the centre component; per component id / size / centroid / hemisphere (by centroid) / isMainland. Pure, engine-free, C++-candidate; a contract downstream phases consume (islands first; biomes, placement, rivers, the crater later). The hemisphere convention lives here.
Scripts/ToolingPaths.cs Every tooling path, env-overridable, resolved in one place.
Scripts/FileSafety.cs The permanent file-safety rules, as throws rather than sentences.

The three rules this layer exists to make unbreakable

  1. Air is the top run. There is no "air vs solid" height branch, anywhere, ever. → Scripts/Column.cs.
  2. Properties come from the registry, never from storage. A run stores an identity. → Scripts/MaterialRegistry.cs.
  3. Nothing uses a raw pixel number. Every distance is a fraction of MapSize. → Scripts/GenerationScale.cs.
  4. There is one metres-per-raw-unit number. The prototype scattered 251 across three duplicate constants and ~20 literals, and the generator never used the derived one at all. → Scripts/WorldScale.cs.

Not here, and not by accident

  • No water. Water is an overlay over the columns (levels-not-cells), never a band.
  • No biomes. Biomes are a later classification of finished shape, not an input to it (D-049).
  • No algorithms beyond the height curve and the region layer. Phase 2 added HeightCurve and TerrainDetailPass here because they are pure, engine-free, C++-candidate math that defines the world's elevation profile — a contract, not a tool's dial. chat2/07 added RegionLabeling on the same grounds: region identity is a contract every later phase reads, and the flood fill is a hot path. (The speck REVERT that uses it is a pass, and lives in Tools/RegionPass.) Stratigraphy, feature passes, meshing and run-splitting on dig are still later phases.
  • No erosion, rivers, water bodies, crater carve, coast shelf or offshore islets. Later chat2 tasks; the curve is deliberately the only pass-2 element present.

Design - Data - Column Model.md, Design - Data - Material Schema.md, Design - Tooling - Scaling Discipline.md