I wanted to create a program that generates a random 2d world map. Like one you would find in old rpg video games. This got me to investigate the wonderful world of procedural content generation.

The word random is used here to mean that the map will be created using a certain amount of randomness so as to get a different map every time we generate one.

Using totally random data would just create a bunch of noise. I generated a map using totally random data to show you what I mean.

Random world generated using pure random numbers

I looked into how to create random 2d worlds. My research on Google led me to pseudo-random number generation and Perlin noise. I quickly realized this wasn’t the path I wanted to investigate.

I wanted to share with you the solution I adopted. It’s easy to code and powerful. I ended up generating a heightmap. These are primarily used to create 3d worlds, but when you think about it, it’s even easier to use them for a 2d world by applying some sort of filter on the height values of the map to convert them to 2d tiles. Here is some code that uses an already generated heightmap, of exactly the same kind you would use for 3d graphics, and turns it in a 2d world map.

require '../map'
require '../tile'
require './height_map'

class WorldMap < Map	
	def initialize(width, height, height_map)
		super(width, height)		
				
		(0...width).each do |x|
			(0...height).each do |y|
                # If the tile is on the edge of the map I select a water tile whatever the results. This is because I absolutely wanted to create an island. If this is not your goal you can forgo this.
				if edge_of_map?(x, y)
					terrain = :water
				elsif height_map[x + y * width] == 0
					terrain = :water
				elsif height_map[x + y * width] >= 70
					terrain = :mountain
				elsif height_map[x + y * width] >= 1 && height_map[x + y * width] <= 2
					terrain = :sand
				elsif height_map[x + y * width] >= 30 && height_map[x + y * width] <= 60
					terrain = :forest
				else
					terrain = :grass
				end
				
				@tiles[x + y * width] = Tile.new(terrain, x, y)
			end
		end
	end			
end

This will allow us to generate something like this:

World created using a heightmap

Bear in mind that these are preliminary results. I still have much work to do on the height map generator to get the kind of results I am looking for.

Generating a heightmap is actually pretty simple. You can look up my two previous posts on the subject for more information.

Generating heightmaps using particle deposition
Using Gaussian blurring on heightmaps

UPDATE: I published a part 2 to this article: Generating Lake and Rivers.
UPDATE: I published a part 3 to this article: Cities, caves and snow.

9 thoughts on “Creating a random 2d game world map

  1. Hello, I have been looking for a great way to randomly generate a world and you really helped me! I have learned a lot but I still don’t know how you made a height map. If you could make some code or just explain it for me to understand would really help, Thanks!

    1. Hi,

      Since I originaly wrote this post, I have open sourced all of this project’s code on GitHub under the very permissive MIT license. You can find it here: https://github.com/gilles-leblanc/gameproject.

      The code specific to world generation is in this folder: https://github.com/gilles-leblanc/gameproject/tree/master/MapGenerator.

      You can even make it run for yourself (provided you have all the necessary dependencies (sorry no bundler yet)).

      To run it, run map_output.rb and be prepared to wait a bit for the world to generate itself. You can configure everything with height_map_configurator.

      To learn more about the technique I used to generate the heightmaps (all the source code is there, just in case you want additional explanations) you can read the following posts from my blog:

      https://gillesleblanc.wordpress.com/2012/08/22/generating-heightmaps-using-particle-deposition/

      https://gillesleblanc.wordpress.com/2012/08/24/using-gaussian-blurring-on-heightmap/

      In addition be sure to check part II and part III from this series which you can find links to at the end of this blog post just above. These parts talk about how I generated rivers and lakes and how I choose where to place caves and cities.

      In the code on GitHub, roads are also generated if certain conditions are met (not discussed in a blog post). Basically the conditions relate to the distance and position of the different cities that have been placed on the map.

      Hope this helps !

        1. I don’t recall the Ruby version for sure as this was years ago but I think it was 2.1.
          I remember there was a problem with getting texplay working. It wasn’t working because of a compatibility issue, I had forked the repo (https://github.com/gilles-leblanc/texplay/tree/ruby21compat) and created a fix that I had submitted as a pull request to the main texplay project (https://github.com/banister/texplay/pull/25).

          This had fixed it, but I haven’t followed anything Ruby related for years so it may have gotten broken again?

      1. Can the result of the generated map be created as a text file using only the basic library of Ruby? I’d like to make a kind of command line utility. (If possible, could you please make command line version of this map generator?)

  2. Apart from this blog post you can also find my other explanations on the two linked post at the bottom of my post.

    Also, in my reply to the comment by Matthew Schmidt, I linked the github repo with all the source code.

Leave a comment