My Second Step Procedurally Generating a Game Map (Rivers, Rivers, Rivers!!!)

Procedural Generation is a great gameplay concept, but it takes an entirely different kind of work (and mindset) than a game where every element is built by hand. In this post, I’ll be briefly expanding on the process of creating a procedurally generated river for my tile based survival, exploration, and base building game JACO.

If you haven’t read part one, it may interest you to start there as I’ll be layering on concepts as I go. You can find part one of this series here:

Quick Recap

When last we spoke, I had simply made a three dimensional grid of null values representing spaces. Eventually, these null values will eventually be filled with tiles representing land, rivers, mountains, etc, all inserted programmatically based on rules I build into my map making algorithms.

By the end of that post, I had generated a river that started at the top of the grid in a random column, and flowed straight down.

But now it’s time to knock it up a notch with our spice weasel.

About the Algorithm

When I first attempted to create a map programmatically, I stumbled big time. I attempted to begin by creating a random tile in one corner of the grid, then wrote logic that would iterate through each node and insert a new tile based on the tiles surrounding it.

Well that approach quickly became unwieldy, so I decided to do some research, and what do you know, most of the problems I was facing had already been solved by others in the procedural generation community.

I found this great wiki site and parsed their posts like Hermione in a library digging through Hogwarts a History.

Seriously, Google becomes your best friend when you begin programming.

I realized that I will need to write a series of algorithms. Each algorithm will be responsible for generating one piece of the map, layering tile types on top of each other until the map generation is complete. So it seems like I have my work cut out for me.

For generating the river, I decided to follow the concept of the Wandering Drunk. This algorithm chooses a random starting point on the edge of the map, then stumbles through the grid following a set of rules that dictate it act in a rivery sort of way (or like a drunk wandering back and forth, hence the name).

As you may have read in the last post, that meant starting with something much simpler, a river flowing straight down.

Let’s River All the Sides!

So we have the concept? Good!

Once I had the river flowing down, I took the next step and wrote code that would allow it to flow straight left or straight right. In concept, this is a little easier that going down because I am iterating through just one array (albeit inside another array). But when it came down to it, the logic was nearly identical.

The code that allows the river to go left, right, up, or down looks like this:

I just ended up writing very similar logic to the code I had written earlier. I don’t like the look of these long if, else if, else if functions, but I really hate the look of switch cases, so I gravitate to this instead.

Then, in order to enable the algorithm to begin at any side, I wrote new logic that used a random number generator to pick which side to start from (0 = top, 1 = right, 2 = bottom, 3 = left), and then an initializer to save the a random starting point on that side to the appropriate variables.

You may notice that the createRiver function is starting to get kind of big. I’ll need to break out that while loop into it’s own function next time I get to work on this code. That refactoring of code keeps it readable for other programmers who might look at the code later (it’ll also make it easier to contain bits of functionality in my own head). On top of that, I’ll probably change this into a do…while loop, I just haven’t worked with those often, and didn’t want to double check the syntax cause … lazy.

And now, our awesome grid can feature a river that starts on any side and flows perfectly straight in any direction. Next time we’ll need to make it wander a little bit more. Anyway, this last image is of the actual text map. Bear in mind that the final product will feature actual graphics, I just… need to make them.

That’s as far as I got last night. Next on the docket is writing the logic that determines the wandering pattern, and stops the river from overlapping itself. Keep an eye out.

Update: The next post is here. Find out how the river turns in the exciting next installment.

Thanks for reading. Want more? Visit the JACO development diary table of contents for more goodness: