I’m now over a month into the basic RPG I mentioned in the last post, so a bunch of systems are in place. In my last post I talked a lot about the narrative system Ink, but this time I want to get back to what is a frequent topic on my devlog: procedural generation of maps. Here is what I came up with for the map of city regions:
(The weird batches of horizontal lines are actually lines of text. That’s just to test applying textures to quads strewn about the map, and will eventually be replaced with images of buildings and trees.)
The core of this is a good ol’ Voronoi diagram, just like I’ve mentioned for maps before. The voronoi cells are seeded using Poisson Disk sampling; so far, so standard. Now the problem I’ve run into before with maps generated from Voronoi diagrams is the straight line edges between map sections. Hm, but I want irregular borders on the map…
The tricky thing I did at this point to get those irregular map sections was assigning clumps of voronoi cells to regions, rather than directly using voronoi cells as regions. This involved a second, sparser, set of poisson points. These new points were the origins for each region of the map, and I looped through every cell of the voronoi diagram to assign them to the region of closest origin. Boom, regions with irregular borders!
I got the idea for this approach after reading an article about giving an organic look to voronoi cells. In that article the cells are calculated against every pixel in the image, but it occurred to me that you could do the same thing using the cells of a denser voronoi diagram. That way the entire thing could still be a mesh of vertices and edges, rather than a raster image. The borders are perturbed using perlin noise in that article, but I found I didn’t need to do anything special to perturb the borders of my regions since the voronoi cells in the regions were inconsistent sizes and shapes.
I did find that very rarely I’d end up with a cell in a region that isn’t really connected to any other cells in that region (they were assigned based on distance from the cell’s site to the region’s origin, which could cause an issue if the cell has a funky shape) but that was easy enough to fix. I simply did a pass through the map after assigning cells to regions to detect these orphans, and then randomly assign them to to a different adjacent region.
A final little trick: I actually generate more regions than needed, and then discard a bunch of regions on the outside. Otherwise the map would be square, whereas this gives the overall map an irregular shape.
Incidentally, I also recently saw a thread on the gamedev Reddit that helps explain why I’m so keen on developing this game in partnership with a writer like Michael Coorlim. In short, that thread was started by someone who loves programming systems for games, but loses steam when filling those systems with content. I’m the same way, but for other people the content is the fun part.