Perlin Noise Island Generator source code by Chris Breinholt.
One of the big things with the new game I'm making is I want it to have replayability. I want people to keep coming back to the game, playing it over and over again, having a unique experience every time they play it. It just makes the game that much better. This is a hard thing to do with 2D rogue-like RPG's though, so one of the ways I thought would help with replayability, would be implementing random world generation. Meaning, every faeture in the world (forrests, mountains, beaches, dungeons, caves, etc), would be completely randomly generated. That way the player is pretty much in a whole new world each time he plays the game. So after many hours of research on the topic, one algorithm really stood out to me, and could help generate the exact kind of terrain I was wanting. It's called Perlin Noise.
I'm not going to explain the algorithm a whole lot, but if you want more information on Perlin Noise, I strongly suggest reading this article. After writing my own python implementation, I had a program that would generate terrain like these:
And if I color the map, like these (Tan=Beach, Light Green=Plain, Dark Green=Forrest, Blue=Water, and Grey=Mountains/Caves):
This produced some pretty good looking random terrains. But the were a little too jagged for what I'm looking for. So I wrote another function that helped to smooth everything out. Here are the results:
The results are pretty amazing, but if this was going to be the world for my game, what is going to stop the player from walking off the edge? The terrain is great, but still isn't quite what I'm looking for. So then the thought of a large island popped into my head. If I could tell the program to generate an island surrounded with water instead of a plain with bodies of water, there would be reasonable limit as to where the player could actually travel. After some reading on theories of how to do this, I basically just used the same program I wrote for my dungeon generator for finding the rooms furthest away from the path from the staircases. The program generates map the same size as our noise map filled with 0's, then it picks a random spot, adds 1 to the value of that spot, then travels across the map in random directions adding 1 to each new spot IF the new spot has a value that is less than or equal to the current spot, then repeat those steps a bunch of times. This created maps that higher areas in the center part, and lower areas in the outer parts, just like an island! The next step would be to normalize this new map so it had values from -1 to 1 instead of 0 and up. Then we multiply the Perlin Noise map that makes up our current plain map (before my smoothing and coloring functions), by the corresponding values of our new island style map. This gave me the results that look something like this:
Then once we add the coloring function...
Then finally use the smoothing function to make the map a little cleaner.
Perfect! That's exactly what I wanted for the game. The steps for the whole program are something like this:
1. Generate Perlin Noise map.
2. Generate a "Island" mask map.
3. Multiply each value of the Perlin map by the corresponding value in the Island map.
4. Color the map, then smooth it to clean up the picture a little bit.
I can write a MUCH more in depth guide on how Perlin Noise works and how to implement it, as well as more explanation on the Island mask algorithm and how to combine the two, but it would take quite some time. So if anyone is actually interested in that let me know and I will do it. :)
***UPDATE***
I uploaded the Python source code for this program, here is the link to the google code project page.
You can download the source under the downloads tab:













Hey how you going!? :)
ReplyDeleteI loved the article, the idea of a random generated rpg is amazing even in the planning stages :)
I'd be very interested in how perlin noise works and a tutorial of sort... do you think you could adapt it to platformers like terraria for example?
Cheers, Luke.
Hey Luke, thanks for the comment, my RPG IS going to be amazing! ;) In answer to your question, yes. Actually, Terraria DOES use a form of noise generation for it's maps. I'm not 100% sure if it uses Perlin Noise, but it's some sort of noise algorithm that must be somewhat similar to this one. Terraria is a great game and a definite inspiration since it is also an Indie game! A lot of the features in my game where taken from Terraria.
DeleteStunning, something like this is exactly what I want. A more in depth tutorial would be great :)
ReplyDeletekeeping the richer display (not posterized) would make the game look more modern, even if is has a retro touch, it is nice to give hints of technology usages that were not possible back in the days. so you could keep the flattened color image internally to determine zones but keep the rich image for display.
ReplyDeleteI've been looking around for a ages for a easy explanation of perlin noise in python. Is this for anyone's use? I am trying to make an top down zombie game and have been experimenting with terrain generation but have made nothing near as realistic as this :( It's fun to keep pressing spacebar and see a completely random island every time.
ReplyDeleteThanks for your comment, you're about the 6th person that has mentioned wanting an easy explanation of Perlin Noise, so I will probably write a guide on it soon. In answer to your question concerning the generator being for anyone's use, it sure is! If you would like to use it you may, I only ask that I receive credit for my hard work. I'm glad you're interested enough in it though! Good luck with your top-down zombie game. ;)
DeleteThanks so much :) You'll definitely get credit in my game :D It is a huge milestone to have terrain generation out of the way. The islands it creates are amazingly unique and I still love running the program a few times to see what it does. A guide on this would be awesome and I'm sure many people trying to make games would be thankful for it. If my game does get completed, how would you like your name credited? (I'm pretty new to games in general :/ ) Should I put something like: "Terrain generation - Christopher" and a link to this site? Thanks again for the program, it made my day :)
DeleteThe new background looks awesome :)
ReplyDeleteThis might be outside your scope of "a simple explanation", but I was wondering if you could elaborate on how to do this for a spherical surface (not just a flat plane). A programmer tried to explain it to me once, and I lost track of what was going on after he tried to describe selecting great circles on the surface. Now that I'm well past junior high, if you have knowledge of the matter, would you be willing to give it a go?
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteFYI regarding the Perlin noise, what you are generating is not actually Perlin noise, but Value Noise. I know, I know, the Hugo Elias article, I read the same thing at first. But Ken Perlin's version uses a different algorithm based on what is sometimes called "Gradient Noise":
ReplyDeletehttp://en.wikipedia.org/wiki/Gradient_noise
The results tend to look nicer than Value Noise as you don't get the nasty blocky artifacts when you add the octaves together.
Hey I was wondering if someone could peek at my code. I tried converting this into javacript but it makes a mash of semi random ... stuff ...
ReplyDeleteTell me if anyone is willing and ill post a link
hey dude, great work, could you make a more in-depth tutorial on the Island mask algorithm ? that technique sounds really nice !
ReplyDelete