islaApocalypse/Tools/README.md
beezm 1f957b3430 docs: water sections (WBID/WBTB/WSRF), no-BSIN rationale, SkipRoads + water stage in READMEs (terrain-water task 03)
Byte-accurate entries for the three water sections (transitional
per-body level rule, provisional salinity, WSRF sentinel/quantization),
updated size math (~576 MiB at 8K with water), the on-the-record
rationale for NOT serializing basins, and README updates for the new
pipeline stage, the 0_water snapshot, and the SkipRoads toggle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 01:40:48 -04:00

57 lines
3.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# /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`'s `MapProfile`: `4K`/`6K`/`8K`/`10K` →
4096 / 6144 / 8192 / 10240. **Shipped default is 8K.** 1 pixel = 1 in-game metre = 1 voxel
footprint. (The `MapSize` field 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`/`WSRF` sections), plus priority-flood
basin diagnostics. The `SkipRoads` config toggle turns a full ~26-min generation into a ~80 s
road-less iteration cycle.
- **Logistics:** `AStarGrid2D` pathfinding producing a looping continental highway, a branch to the
mountain hub, and county roads daisy-chained outward with Prim's algorithm. Paths are decimated
(RamerDouglasPeucker) 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
1. **No client dependencies.** Nothing here may reference UI, player controllers or shaders in
`/Client`.
2. **Data out, nothing in.** Tools emit `.dat`/`.png`/`.json`; they never write to a live server save.
3. **No magic numbers.** Distances and radii scale off `MapSize` or the derived `scaleFactor`, so the
generator behaves the same at every profile.