islaApocalypse/Tools
beezm 1f7613439a perf: weight-aware A* heuristic + tamed road repulsion (route-preserving speed fix)
A* was searching almost the whole island for every road. Godot's stock
estimate-to-goal is plain straight-line distance, which assumes every step
costs 1 — but a step through mountains costs up to 401 and a step near an
existing road cost 10,001. With the estimate that far below reality, A* cannot
rule anything out, so it degenerates toward Dijkstra.

Two changes, both aimed at that:

1. RoadPathGrid overrides the estimate to scale it by HEURISTIC_WEIGHT (3.0),
   i.e. weighted A*. Paths may be up to 3x costlier than the theoretical best
   in exchange for exploring far less. This does NOT push roads over mountains:
   a ridge costs hundreds of times more than going around, which a 3x bias
   nowhere near pays for.

2. ROAD_REPULSION_PENALTY replaces the hardcoded +10000 with 250. The old value
   made ground near a road effectively infinite, and it compounded — each road
   drawn made the next search slower. 250 still strongly discourages roads from
   running alongside each other.

Terrain weights are untouched: the mountain curve (1 + elevation^3 * 400),
beach and wasteland costs are exactly as before, so mountains remain expensive
and roads still avoid them. Routing, tiers, smoothing and grid resolution are
also unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-05 21:32:51 -04:00
..
Scenes docs: bring all READMEs current with actual code (post-sweep-10 truth pass) 2026-08-05 05:23:58 -04:00
Scripts perf: weight-aware A* heuristic + tamed road repulsion (route-preserving speed fix) 2026-08-05 21:32:51 -04:00
README.md docs: bring all READMEs current with actual code (post-sweep-10 truth pass) 2026-08-05 05:23:58 -04:00

/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).
  • 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 (~512 MB at 8K)
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.