Diagnostic first (SouthernStretchTool, ISLA_DIAG_ONLY; scratch/southern_diagnosis.md). Along the central south profile the mask blend climbs 0.018 per 0.01 N, edge noise adds 0.03-0.06, and the southern sinker is zero until 0.75 N then adds 0.024 per 0.01 N before the 2.5 power; the coast sits at 0.76-0.82 N, ~0.06 N north of where the blend alone would end. The stretch compresses the southward distance the mask sees inside a fixed feathered latitude band, y' = yB + (y - yB)/(1 + s*ramp), texture (base noise, edge noise, latitude) untouched, so the extended mass keeps the elevation of the rows it came from. With the sinker reading the REAL y it cancels the stretch outright: median coast saturates at 0.83-0.84 from s = 1 to 16 and the south stays 1-10 tiny nubs on both seeds. The lever is therefore two things - extend reach AND hold the sinker back - and this pass couples them 1:1 (StretchSinker = true; the real-y mode is kept as the config's other setting). Ladder chosen from the sweep, non-linear: 0.5, 1, 2, 3, 5 (peninsula / onset / few big pieces / big pieces consolidating / over-stretched sheet); 8 and 16 are indistinguishable from 5. Topography: cells above the band take the untouched code path (fy == y), so the classify field north of the band is bit-identical by construction. SouthernStretch.cs holds the band constants (start 0.70 N, feather 0.05 N - fixed for the batch) and the ramp. TerrainGenConfig: SouthStretch (the swept axis, 0 = off), SouthBandStartFrac, SouthBandFeatherFrac, StretchSinker. Oracle, all passing: a1/a3 stretch OFF bit-identical; a3b stretch 5 north of the band bit-identical to the task-03 dump (2.93 M cells), a4b the same at 8192 against the terrain-curve-v1 gallery dump (46.97 M cells north of the band, 20.1 M differ below - the relaxation); per field north bit-locked classify and render vs stretch 0 (p, p2), northern island set invariant (q), centre is land, tag/coastline, classify == raw; ids and heights deterministic. Batch: BatchRoot(8, "southern_stretch_explore") - 5 levels x 2 seeds (1063685222, 999999937 - the two 07 seeds with the most mainland south of the band), lean render (regions overlay + relief + .f32), the hemisphere-split count/size table. Region labeling on, offshore / shelf / speck revert off: the pure fragmentation signal. The read at 4096: s 0.5 peninsula (coast +0.04 N); s 1 onset (999999937 6 -> 12 southern islands, 11 substantial); s 2 few big pieces (35k / 86k-cell fragments); s 3-5 a solid sheet to the trench whose southern edge is the trench wall - a ruler-straight coast - and whose island count falls as pieces re-merge. Gravel never dominates. Graduation held, per the task. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013EY3ZTF6NwzF8ukBHQXSK7 |
||
|---|---|---|
| Client | ||
| Core | ||
| Server | ||
| Tools | ||
| .gitattributes | ||
| .gitignore | ||
| islaApocalypse-v2.csproj | ||
| islaApocalypse-v2.sln | ||
| project.godot | ||
| README.md | ||
Isla Apocalypse — v2
The rewrite (D-049). A post-apocalyptic survival voxel game: one island, generated once offline, loaded by everyone.
Status: Phase 2 — shaping. Phase 0 laid the contracts and the tooling rails; Phase 1 ported the crown-jewel noise and pass 1 (the island's raw shape); chat2/01 added pass 2a — the height redistribution curve and shelf detail, re-calibrated against this repo's own output, with the two-height-field split and an automatic oracle.
Still no erosion, rivers, water bodies, crater carve, coast shelf, offshore islets, biomes, roads or mesher.
⚠ Two repos. Never one.
| Repo | Role |
|---|---|
~/celerNexus/islaApocalypse-v2/ (this) |
The rewrite. Every line of new code is written here. |
~/celerNexus/islaApocalypse/ |
⛔ READ-ONLY. The pre-rewrite prototype, archived at ab78883, tag pre-rewrite-reference. Ported FROM; never written to. |
~/celerNexus/islaApocalypse-vault-v0.1/ |
The design vault — the source of truth for WHAT and WHY. The vault leads. |
The old codebase is a spent quarry (D-050): mined, never tracked, never synced, never canon'd. Writing rewrite code into it would corrupt the very thing being ported from.
⚠ Runtime data isolation — do not weaken
This project pins its user:// directory away from the old prototype's, which holds the
preserved reference seeds, blueprints and batches:
user:// → ~/.local/share/islaApocalypse-v2/ ← this project
~/.local/share/godot/app_userdata/islaApocalypse/ ← ⛔ the OLD prototype. Never touch.
Pinned two ways in project.godot — a distinct application/config/name and
use_custom_user_dir + custom_user_dir_name. Both must stay.
⚠ Do not document this with a comment in
project.godot— it will not survive.Godot rewrites
project.godoton import and STRIPS ALL COMMENTS, replacing the header with its own boilerplate. (Measured: a warning block written there was gone after the next--import. The settings survived; only the explanation was deleted.) So the warning lives here, and the guarantee is enforced by the probe below — which exits non-zero on a clash and therefore works in a pre-flight check, not just by eye.
After any change to the [application] block, re-run the probe:
Godot_v4.7.2-stable_mono_linux.x86_64 --headless \
--path ~/celerNexus/islaApocalypse-v2 res://Tools/Scenes/UserDirProbe.tscn
Layout
Core/ math + data only, ENGINE-FREE — depends on nothing above it
Server/ authoritative logic — may use Core (empty: not yet its phase)
Client/ rendering — may use Core (empty: not yet its phase)
Tools/ the offline generator — ⚠ may NOT use Client
Each layer has a README.md stating its role and its boundary. Read the one for the layer you are
about to write in — they carry the reasons, not just the rules.
The contracts this phase establishes
- ★★ The column model (D-053) — the world as a 2D grid of columns, each a stack of
(material, thickness)runs. Air is the top run; there is no air-vs-solid height branch. →Core/Scripts/Column.cs - The material schemas (D-054) — terrain and building, two schemas bridged by a transformation
seam that is deliberately empty. Identity is a registry key, never an ordinal. Mesh style is
per-origin, never a material property. →
Core/Scripts/MaterialRegistry.cs - The scaling discipline — nothing uses a raw pixel number.
→
Core/Scripts/GenerationScale.cs - The vertical yardstick — ONE metres-per-raw-unit number, not three constants and twenty
literals as the prototype had. →
Core/Scripts/WorldScale.cs - The elevation profile — the 7-band redistribution curve, identity at and below sea, its
knots measured rather than chosen. →
Core/Scripts/HeightCurve.cs - The two-height-field split (D-046) —
heightClassifyis raw and is the oracle;heightis curved and is what gets drawn. →Tools/Scripts/Pass2Result.cs - Tooling safety — every path env-overridable, deletion refused by code.
→
Core/Scripts/ToolingPaths.cs,Core/Scripts/FileSafety.cs
Build
dotnet build
Godot_v4.7.2-stable_mono_linux.x86_64 --headless --import --path .
Godot 4.7.2 (mono) · .NET 8 (net8.0) · Godot.NET.Sdk/4.7.2
The reference repo is Godot 4.7.1. This repo deliberately targets 4.7.2 — clean rewrite, current tooling. 4.7.1 is the port source, not a constraint on new code.
⚠
<RollForward>Major</RollForward>in the.csprojis load-bearing.The target is
net8.0but this machine carries only a .NET 10 runtime. Without that property the generatedruntimeconfig.jsonrolls forward by MINOR only and every run fails with "You must install .NET 8". This bites at run time, not build time — the build succeeds either way — so re-check the emittedruntimeconfig.jsonafter any.csprojchange.
What this phase is NOT
No mesher, no stratigraphy, no biomes, no water, no rivers, no erosion. The pipeline is 2D-maps-first (D-056): stages 1–5 are flat maps, gotten completely right before a single 3D vertex exists. Building the mesher before the data is right is the specific trap this rewrite exists to undo.
And the curve is a BASELINE, not a verdict. It is ported faithfully and calibrated honestly so that later reshaping has a control to be judged against. Whether this elevation profile — 60 % of land in the bottom 14 m, 4 % above the plateau — is the one the world wants is an open question the histograms exist to inform, not one this port has answered.