The gate's two river notes. FILL THE TRIBUTARIES. RiverTribWaterMinFlow defaults to 0, so every promoted tributary carries water its whole length (800 of 1574 reaches are now on tributaries, 65,364 of 268,863 wet px). The graceful tip survives: the fade zone is now always TaperPx long starting wherever water begins, so with a threshold it spans (WetFrom-Taper -> WetFrom) and with full watering it spans the first TaperPx from the HEAD. Fill is about LENGTH, taper is about the END. FILL THE CHANNEL, NOT THE FLOOR. The water surface is now RiverFillFraction (80%) of the LOCAL bed depth rather than a fixed height, floored by RiverWaterDepthM as an absolute minimum. A fixed height is wrong at both ends — a trickle in a 13 m mouth and over the rim at a 1.5 m head — where a fraction is right at every scale and cannot spill onto the plain. BANKS AS SHORES. The shoulder flares RiverBankFlare (3.2, was a hard 2x) half-widths with a smootherstep instead of smoothstep, so the rim leaves nearly tangent to the water plane. That alone cut too much where a course crosses a ridge (cells deeper than 20 m went 339 -> 1917, max 26 -> 37 m), so the SHOULDER may not lower a cell more than RiverBankMaxCutM (3 m) — measured against the PRE-PASS surface, because a per-write cap let overlapping stamps each take another 3 m and changed the carved volume by 1 m3 out of 1.29 M. Gentle ground still flares into a shore; a ridge crossing keeps steep walls, which is what a gorge looks like. Net result is better than BOTH predecessors: max cut 16.8 m (task 24: 26.0), zero cells past 20 m (task 24: 339), carve p95 5.26 m. Guards unchanged: BIOME oracle md5-identical to the task-22 baseline, 0 newly-below-sea, 0 below-sea cells modified, lowest carved cell exactly sea+margin, island top 457.65 m exact, crater core excluded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| Scenes | ||
| Scripts | ||
| README.md | ||
/Tools
Offline developer utilities. Nothing here ships. These generate the source data that /Server
and /Client later consume, which keeps world-generation logic out of the shipped client.
The 2D world generator
Script: Tools/Scripts/MapGenerator.cs · Scenes: Tools/Scenes/MapPreview.tscn and
Scenes/MapCaptureTool.tscn
Builds the topographical and logistical foundation of the island before any 3D exists.
- Resolution is config-driven, from
ServerConfig.json'sMapProfile:4K/6K/8K/10K→ 4096 / 6144 / 8192 / 10240. Shipped default is 8K. 1 pixel = 1 in-game metre = 1 voxel footprint. (TheMapSizefield initialiser in the script says 4096, but it is overwritten from config before use.) - Topography: FastNoiseLite plus distance-falloff maths for a guaranteed mainland island, a mountain spine, dynamic temperature-driven sea level, and an impact crater pushed into the northern coast (carved at 80 % of its radius so a landbridge always survives).
- Water bodies: the classified water promoted into explicit blueprint data (ocean + labeled
lakes with transitional per-body levels —
WBID/WBTB/WSRFsections), plus priority-flood basin diagnostics. TheSkipRoadsconfig toggle turns a full ~26-min generation into a ~80 s road-less iteration cycle. - Logistics:
AStarGrid2Dpathfinding producing a looping continental highway, a branch to the mountain hub, and county roads daisy-chained outward with Prim's algorithm. Paths are decimated (Ramer–Douglas–Peucker) then smoothed (4 Chaikin passes). - Zoning: biome mapping and tiered town/POI placement by slope, temperature and proximity.
⚠️ A* is the known bottleneck
The grid is one node per pixel — 67 million nodes at 8K — and the weight-setup pass walks every
one of them. A full generation can stall long enough that runs get abandoned. await yields are
sprinkled through the road stage, but they cannot interrupt a single engine-side GetPointPath call,
so they only help between paths. Expect a regeneration to take minutes, or to need abandoning.
Outputs — written to user://, not into the project
| File | What it is |
|---|---|
MapData_Seed_<seed>.dat |
The binary blueprint the server reads — v2 tagged container (~336 MB at 8K; contract in Core/Scripts/BLUEPRINT_FORMAT.md) |
MapData_Seed_<seed>_v1.dat |
The same content in the legacy v1 format (~512 MB), dual-written as a safety net until a future removal task |
Map_Seed_<seed>.png |
Visual snapshot of the map, for reviewing and picking seeds |
On Linux: ~/.local/share/godot/app_userdata/islaApocolypse/.
Running it
Open Tools/Scenes/MapPreview.tscn and press F6. It is also the project's main scene, so
pressing F5 anywhere runs this — which is why F5 regenerates your world instead of starting the
game. Use Scenes/MapCaptureTool.tscn when you specifically want the full-resolution PNG.
Rules
- No client dependencies. Nothing here may reference UI, player controllers or shaders in
/Client. - Data out, nothing in. Tools emit
.dat/.png/.json; they never write to a live server save. - No magic numbers. Distances and radii scale off
MapSizeor the derivedscaleFactor, so the generator behaves the same at every profile.