A four-phase pipeline orchestrated by MapGenerator. Phases 1 and 2 are implemented.
Map generation runs at startup and on regeneration (R key in debug builds). Each phase builds on the output of the previous one. The pipeline is designed so phases 3 and 4 could have been implement, but due to time constraints only the first two were completed.
Bridson's Poisson disk sampling algorithm (2007) places seed sites with a minimum separation distance derived from map area ÷ site count. This prevents site clustering while allowing the Poisson algorithm to fill the space properly. A spatial hash grid then assigns every tile to its nearest site in O(k) per tile rather than O(n). Each region gets a unique ID used for terrain assignment and POI placement.
Perlin's improved noise (2002) is sampled at every 2nd tile with configurable
frequency, octave count, and persistence. Tiles above the placement threshold get
a world object, tree stump, root, tree canopy. POI exclusion zones and terrain type
filtering prevent objects overlapping structures.
Frequency, octaves, and threshold are all tunable in MapGenerator::GenerationSettings.
A terrain smoothing pass to remove isolated tiles and create more organic region edges.
Stubbed in MapGenerator::generate(), the phase is called but
does nothing. Would run after Perlin phase.
Dijkstra flood fill from the player hideout to verify all POIs are reachable. Stubbed in the same place.
The original site placement used rejection sampling, generate a random position,
check it against all existing sites, discard if too close, try again.
It works, but it degrades badly as the map fills up.
The replacement: Bridson's Poisson disk sampling with a spatial grid, is still in the
codebase as generateSitesRejection() for comparison. It's not called in production.
Generates random positions and discards those that violate minimum distance. Each new attempt checks against all existing sites. Gets slower the more sites are placed.
Bridson (2007) uses an active list and background grid to guarantee minimum separation in expected O(n) time. Implementing it correctly required careful study of the paper and a fair bit of debugging.
The player hideout is placed at map centre before generation starts. Voronoi sites and Perlin noise placement both respect POI exclusion zones. The site placement step explicitly avoids generating sites within 400px of the hideout.
Farm and village POIs are placed at the Voronoi sites furthest from the hideout, this is done by sorting sites by distance before placement, so the nearest sites are never picked for POIs.
Always at map centre. Collision polygons loaded from a .tmx Tiled template file. Exclusion radius keeps Voronoi sites away from it so the player spawn area is clear.
Up to 2 per map, configurable. Placed at the furthest available Voronoi sites. Large sprite, 1948x2016px, with collision from a Tiled template.
Config registered, sprite and template paths empty. The POIConfigRegistry entry is there, it just has no art yet. Adding content means filling in those fields, the generation logic doesn't need changing.