Procedural Map Generation

What and why?

The past week or so I've been messing about with procedural map generation in an attempt to make creating content for my current game easier. In the past I've really struggled when it comes to making levels. I struggled with Ninjah and that was just a single screen single layer map and I really, really struggled with Pogo Fred.

My struggle with Ninjah purely related to coming up with 50 or so maps that were all different and fun. While I managed to make the 50 levels in the end, I admit that some of them were below par.

With Pogo Fred I struggled with basically every part of level design. I struggled with unique ideas, I struggled with adding all the features I had developed (I think I must have used less than a third of the features I had developed). Most of all I struggled with making the levels feel organic. By this I mean, I struggled to make the "filler" parts.

By filler I mean the parts between key moments and areas within the game. I could try packing everything on top of each other but the pace of the game would be ridiculous. If I wanted a really remote castle or something, I would need to have a certain amount of distance between said castle and any other key areas in the game. It is the bit in between that I struggle with, I clearly lack something in my head that will let me just organically build for example a forest. Should I put two trees here? Or four? Wait that looks stupid, I'll try three... no four... no three! Whatever gets made I always seem to feel unahppy or uneasy with it. If I could just get levels handed to me that would be great.

So... if I can generate the areas without having to think at all about trees, flowers and all the other "filler" content, I'd be happy. This has been my attempt so far; it's not in any particular order, just go with whatever I think about at the time.

The process

All the screenshots below are not of the actual game graphics, just a simple map of what type of graphics will go where.

First off I wanted to create barrier around the outside of the area. I didn't want to include an invisible wall but at the same time I wanted to guarantee that the player couldn't run off in to the void. The above is created by allowing the border to be between 1 and 5 tiles away from the actual edge of the map.

The border goes round the map in a clockwise manner, so to start I draw the upper border, then the right, bottom and finally the left one. There is a 10% chance that the distance from the edge will change with each tile. It can either go further away or closer.

You will notice in future images that the border doesn't always join in the top left hand corner, this will need work! Next up forests.

Each dark green square is a forest tile. A random point is selected in the map and this becomes the basis for the start of the creation of a forest. The logic behind the placement of the forest tile is as follows...

Above you can kind of see the origin of 3 forests, but quite clearly the spread is too much.

I tweaked the spread code to prevent the forests spreading so far. This appears to have done the trick, but the forests now look quite square (and stupid).

I want to avoid single tile forests (i.e. one forest tile on its own), so to do this I perform two steps.

These steps will remove the orphan trees as well as plugging the gaps. This is beginning to create something that's more realistic.

I expanded on the previous logic as well as increasing the amount of tiles a forest could potentially have. At this point I am now happy with forests, but will go back and tweak them if need be.

My first attempt at adding rivers! It's looking good right? Yeah I know... The logic...

In my head, I had thought 8 directions would be fine, but clearly it isn't. I did decide that a river can flow through (and replace) forest tiles.

I use the same logic as above but instead of 8 directions I make it 360 degrees. I am happy with the results!

I add a very slim chance of the river forking in to two. From the trials I have done, this is very hit and miss, but I will keep it for now.

I increase the width of the river tiles. I do this by scanning every tile on the map to see if it's water. If it is I randomly expand it by 0 tiles, 1 tile or 2 tiles with 1 tile being the most likely outcome.

  o           0 tile expansion
  
  x
 xox          1 tile expansion 
  x
  
  x
 xxx
xxoxx         2 tile expansion
 xxx
  x
		

Above, the o is the original tile and the x's are the added padding cells. I am not entirely sure how happy I am with it at this stage.

I add river banks. Basically, if a grass tile is next to at least 3 water tiles, turn it in to a sand tile. I expand the map size at this point as well, just to check it works ok (and it does!).

Just another example of a river.

My first attempt at creating random settlements. The logic...

On the most part I am actaully quite pleasantly surprised how well it turned it. There is a slight issue with overlapping the water as well as buildings overlapping (not sure if it's actually a problem though, I could just use it for irregular shaped buildings). I didn't take a screen shot, but an early attempt showed that the buildings were too keen to spread from the origin, so I changed that.

Very minor changes here. I make it so the building don't overlap but make more of an effort to remain together. I also make it so there is always a blank area around the edge of the settlement. You can kind of see this in the left most town, where the buildings are cutting in to the trees slightly.

Just another example!

What next?

I want to add streets to the towns, as well as paths between notable areas in a map (whatever they might be). For the streets, I assume I will be using some kind of grid and for paths I will be using a more organic route finder (like A* I suppose!). I want to add lakes and other more individual items like flowers, bushes and what not.

It's probably worth noting that, while I intend to use the generator to make the basis of the maps, it will not be the finaly thing. I will import the generated map in to the editor and make tweaks as I see fit!

-Chris