Roguelike Adventure Generator (PART 1)

I’ve been watching a lot of shows lately that involve high fantasy adventures – most of which involve some kind of power grab. They’re the kind of shows full of shady politics, tactical dealings, huge battles, and vast ambitions. I want to try and distill this into game format.

The most recent example of such a show is Game of Thrones. It has all sorts of characters going on all sorts of grand adventures. There’s dairy queen, for example, uniting a bunch of misfit armies, freeing the slaves, and taming dragons on her quest to claim the iron throne.

The best example of an epic adventure, though, is probably the Lord of the Rings. The sheer amount of stuff that Frodo gets up to on his quest to throw the one ring into Mount Doom is honestly quite ridiculous. I’d like to make a game that enables this kind of interesting quest.

Thus, long story short, I’m going to make an adventure generator!

Currently, my plan is to create a deeply simulated fantasy world. I want to fill the world with a bunch of different factions and let god sort them out.

The result should be a ton of chaos that I can exploit for procedural quest generation by using something similar to Stalkers A-Life or Bethesda’s radiant AI systems. I don’t know how these systems work, but it doesn’t matter. I’ll figure something out when needed.

I have to make the world super interactive in order to support maximum freedom of choice while also giving it enough depth that the player can get up to all sorts of zany antics.

Anyway, let’s get down to brass tacks. I’ve been pouring ungodly amounts of in-depth design analysis into my super project so for this series I’d rather focus on getting things done. I’ll go into excessive detail when it’s necessary instead of front-loading everything like I usually do.

The first thing I need to do is build the world. The game is going to focus on player-centric activities but without a world and its inhabitants, there’s no activities to be had! Thus, I need to create a basic simulation. I need to generate terrain, factions and who knows what else.

The first step is to generate noise. Lots of noise! It’s never actually that easy, though.

Let me show you what plain old noise looks like. It’s not very useful or pretty!

Here is some plain old simplex noise. The result would be largely the same even if I used perlin, wavelet or anything else. The problem is that noise is kind of worthless by itself. It needs to be treated like a worthless lump of clay and shaped into something more useful.

The brown tiles are what I’m currently using to represent land. The entire map defaults to being filled with land because I’m not applying a threshold. This means it doesn’t matter if a particular tile of noise is 0, 1, or something in-between. It considers everything land.

This is what happens if I apply a threshold of 0.2!

There are some blobs of water showing up now! This happens because increasing the threshold basically causes gaps to appear in the noise array. I’m only accepting values that are greater than the threshold – so anything below it doesn’t get carved to the map. I turn any tiles that aren’t land into water which is why more of it appears as the threshold rises.

As you can see, the higher I raise the threshold the less land there is.

You might also notice how each of the examples has a similar pattern. That’s because I’m using a seed number for the noise generator. I’m going to do that from now on for continuity purposes. This way, even a hundred posts from now, the map will still look familiar! I think it will be neat to compare an old version of the map to a fancier one a couple posts from now.

By the way, the map is actually far larger than I’ve led you to believe. The above images are only showing a small section of the world. This section is all I can fit in my 1280×720 game window! Even if I maxed out my game resolution to 1920×1080 or greater it still wouldn’t be enough to fit the whole world. The map is 200×200 which comes out to 40,000 tiles in total while each individual tile is 12×12. I’m only able to show 75 of these tiles at a time.

Let’s switch over to pixel scale. This means I basically draw every tile as an individual pixel instead of a 12×12 tile. If you take into consideration that every tile takes up 12 pixels then you can imagine the space-saving that occurs by compressing them to 1×1!

This is the result of switching over to pixel scale. I went ahead and included the rest of the map area just so you could really comprehend how much smaller things are. If you look closely you’ll notice the previous images pattern is now visible at the pixel scales center.

Anyway, since we can now see so much more it’s time to up the map size. Let’s go from 200×200 to 700×700. That brings us up to a grand total of 490,000 tiles from 40,000!

That’s better. I’m still using the same seed and threshold so due to how noise works, the previous image can be found in this images upper left corner.

Scroll up to look and then back down and you’ll see what I mean.

The next step is to make the world a little more interesting. I’m sure you’ve noticed how repetitive the noise looks. It was fine when we were zoomed in but now that we’re zoomed out a very obvious pattern has emerged. It doesn’t look like any kind of terrain I’ve ever seen! It comes off as some sort of bizarre planet covered in lakes.

This is another problem with noise. It’s very repetitive looking. This happens because the noise isn’t as random as you might think. If it was, then these images would look like static.

It’s beyond the scope of this blog to explain how and why the noise generates shapes instead of useless static, but this wiki entry about noise might help you a little bit.

Either way, static isn’t very useful in regards to terrain generation. The repetitive patterns, though, aren’t exactly ideal either. They look artificial and just plain weird.

The answer is more manipulation. I’ve found the best way to reduce this sameyness is to mix your noise with more noise. That’s what we’re going to do next. I’m going to generate some big and small noise and then evenly mix them together to see what happens.

Here is an animated version of the same images to try and better show the combination.

The end result is certainly more interesting visually but it’s still pretty samey. The only thing I really accomplished was replacing the old pattern with a new one. It’s rougher, sure, as if the world has been eroded over time, but the map still looks very repetitive from top to bottom.

It’s just less squiggly and more spikey.

To further improve this, I’m going to make both sets of noise bigger.

I’m pretty happy with this result! It also helps show off the whole noise combination thing a lot better since you can more clearly see how each set of noise influenced the final result.

This worked better because each set of noise had a bigger scale.

Previously, each set of noise was like static. Theirs shapes, sure, but they’re just a bunch of small patterns. The big noise, though, due to taking up so much space can’t repeat itself as much. This makes the end result more unique when it gets combined with other noise.

This is the map I’ll be using from now on so get used to it! The next thing I want to do is some noise maintenance. I’m going to nuke a few of those small islands from orbit.

Before and after small areas of land were turned into water.

Here is the end result. I turned any landmasses that were less than 30 tiles in total into water. The next step is basically the same thing but used on different terrain. I’m going to use my godly powers to erase any blobs of water that are too small now instead of land.

Before and after tiny bodies of water were turned into land.

I settled on a minimum water count of 50 after some trial and error. It gets rid of all the dumb puddles while retaining a few lakes and other interesting bodies of water.

What’s next? It’s time to give the world some actual terrain. Forests, mountains, deserts and other stuff like that! Believe it or not, I’m going to use more noise to accomplish this.

Here is our map with the addition of forests. It looks stupid because I need to add some new carving rules. I need to restrict the forests to only being carved over land tiles.

This is what it looks like after only letting the forests overwrite land. I also cleaned up any blobs of forest that were less than 20. I’m still using a seed for everything so if you compare this image and the previous one you’ll notice its the exact same noise distribution.

I think the forests might be too big, though, but I don’t care enough to mess with them further. I’ll probably come back to them later and fiddle with the noise values a bit more.

Let’s add some freshwater next. This doesn’t take any noise generation or anything! Instead, I’ll just be converting small bodies of landlocked water into freshwater.

This is what the map looks like with freshwater. I’m turning any water that is less than 10,000 tiles in size into it. That basically means everything but the ocean itself gets converted.

This isn’t a perfect solution. It’s possible for a landlocked blob of ocean tiles to exist that is greater than 10,000 tiles in size. This method wouldn’t detect and convert such a scenario into freshwater. That’s just how procedural generation is. There are infinite possibilities due to the nature of randomization which means theres too many edge cases to handle.

The mountains are next. These are a pain in the ass to make in a satisfying way. Originally, I wanted to create fault lines and simulate volcanic activity along them to create nice looking mountain ranges. This is the kind of appearance I was going for.

Satellite image of the Himalayan mountains. Credit: NASA.

I want nice long ridges like the above image and other curvy stringy mountain range shapes.

However, after several days of tinkering, I’ve decided to give up on that approach. I was making progress but it was slow and soon began to feel ridiculous. The terrain doesn’t really matter right now so every second spent perfecting it was largely a waste of time. I fell into that design trap of working on irrelevant things or optimizing when optimization isn’t needed.

I decided to take a less advanced approach. No geological modeling, unfortunately! Instead, I’m basically just generating a bunch of circles and then corrupting them with noise. There are too many steps involved to screenshot so I’m going to create a gif and then explain it.

Editing on wordpress is like stepping on legos.

I made the gif by just recording my screen. I built an in-game noise visualizer for debugging purposes. It’s a lot easier to figure out what you’re doing when you can see the results!

First, I create two arrays full of randomly positioned and sized circles. That’s Hills1 and Hills2 in the animation. Then, I feed these two circle arrays to a zany math function. It compares the two circle arrays and spits out a weird combination of the two. The combination seems to detect overlapping values and blends them into football-like shapes. The result is that Hills3 is now full of crescents and other vague mountain shapes instead of perfect circles. The first two hill arrays are purposely similar to one another to take advantage of this side effect.

Then I create two sets of small noise. That’s Small1 and Small 2. This noise is evenly mixed together to create Small3. The mixture is then eroded to rough it up even further. Finally, I mix Hills3 with Small3 and apply a gaussian filter to smooth things. The mountains are done!

Here is our familiar world with mountains.

Also, since this is the last dose of terrain generation for the time being, here are some other worlds. They’re made using the exact same noise settings. I just randomized the seed value.

The result isn’t perfect but it’s close enough. There’s some stringy mountain range shapes and other decently peaky looking things so I’m going to call it a wrap and move on.

Here is what the current world would look like if converted into an island if you’re curious.

This is accomplished by creating a map sized centered gradient circle and blending the landmass with it. It basically causes the land to taper off the further it gets from the center.

If you remember, I started adding terrain as a stepping stone towards supporting a basic simulation. I need a world to populate, of course, before I can do anything interesting. I’ve met that goal, so let’s move onto the next step! I’m going to start adding resources now.

I generated terrain first because resources are often tied to it. It’s possible to find ore in the middle of nowhere, for example, but it’s more likely to show up in the mountains. The same goes for wildlife resources like sheep. I guess they could be found in a swampy wasteland but they probably prefer grassy areas near fresh-water sources like natural springs or lakes.

There’s not enough biome variety to accurately simulate resource distribution yet but that’s alright. I’m not aiming for realism right now. I just wanted to build some kind of foundation to work off of instead of just throwing everything around randomly.

Why don’t I just throw it around randomly, though? I don’t literally need terrain. I could just as easily generate resources without it. The answer is that I want resources tied to terrain in preparation for faction generation. Towns, industries and entire civilizations have sprung up around useful resources. The best example I can think of is Egypt and the Nile river or the middle east and its oil. I want to say Rome and its bronze, too, but I’m not entirely sure.

Either way, I think an easy way to make factions more interesting is to give them unique access to certain resources. If one faction has access to lots of iron, for example, then they’ll be able to make some great equipment while everyone else is stuck with copper or stone. It then stands to reason that they’ll develop high-end blacksmithing as a result and potentially claim a good portion of the world due to their access to strong metals and talented smiths.

I could just randomly generate factions and give them access to random resources but then the world would have no weight to it. They would just be an intangible background element that can’t be interacted with. They’d be more like perks or upgrades than resources in this state. If iron is a real resource, though, then factions can trade, steal or even fight over it.

It has implications for the player, too, since resources are now a legitimate in-world thing.

The first iteration of this will be quite simple but should nevertheless help make the world a little more diverse at almost no cost to me complexity wise. I like the way the total war series of games handle resources. They’re just single tile objects on the map. I was originally going to generate fields of resources using noise, but have decided to go this way instead.

Medieval total war is the best total war.

I’m going to generate some resources, and then, if a faction is near said resources they’ll claim it. They’ll build a mine on diamonds, a farm on wheat or ranch on cows. This will be a real place the player can visit and people will staff. Traders will transport goods back and forth between them and whatever town the resource belongs to.

I think we’ll stop here, though. I’d like to put more thought into resources and factions before committing to anything. Come back next year when I add resources, factions and more!