I need to generate tile data for an island based rpg, my goal is have something that looks like this (mountains not required):
enter image description here
For the past few days I have been trying to figure out a satisfactory way to generate tile data that will give me varied and natural islands, such as in the example above.
I've tried using Unity's Mathf.PerlinNoise but the results are far too random, and I can't see a way to get it to generate a single island.
Using LibNoise I was able to get slightly better results, although the generation seems to be significantly slower and perhaps better suited to 3d terrain. Similarly however, I can't see a way to set the Octaves/Frequency/etc, so that I get a nice single island each time.
While there are a fair amount of resources online for perlin/noise in general, it mostly seems to be aimed at 3d terrain and height, where I simply have a 2d array of int for my tile data, that maps to either water, sand or grass and needs to be generated in such a way that sand/grass are grouped together logically to form an island.
Any help would be greatly appreciated!
-
\$\begingroup\$ Try simplex noise \$\endgroup\$Savlon– Savlon2014年07月20日 14:03:48 +00:00Commented Jul 20, 2014 at 14:03
-
1\$\begingroup\$ Your 2d map is in fact a 3d map: The z-coordinate maps to the terrain type. \$\endgroup\$Philipp– Philipp2014年07月20日 14:53:07 +00:00Commented Jul 20, 2014 at 14:53
-
\$\begingroup\$ Could you explain that a bit more? Surely the result of PerlinNoise for a given x/y maps to my tile type? Ie: 0.4+ is sand, 0.6+ is grass, etc. \$\endgroup\$Neophyte– Neophyte2014年07月20日 14:55:56 +00:00Commented Jul 20, 2014 at 14:55
-
\$\begingroup\$ @Neophyte Where you set the thresholds for each terrain type is something you need to experiment with yourself. \$\endgroup\$Philipp– Philipp2014年07月20日 14:57:10 +00:00Commented Jul 20, 2014 at 14:57
-
\$\begingroup\$ What does that have to do with z-coordinate? \$\endgroup\$Neophyte– Neophyte2014年07月20日 17:02:11 +00:00Commented Jul 20, 2014 at 17:02
2 Answers 2
One thing I've done in the past for island shapes is to use perlin noise minus a circular shape. It usually produces one big island and some little things off on the side. You can use flood fill or smoothing to remove any small noise.
Here's a demo (flash) that I wrote for this question.
For each location (x, y)
in the noise bitmap, compute the distance from the center, normalized so that the bitmap is 2x2:
function distance_squared(x, y):
dx = 2 * x / width - 1
dy = 2 * y / height - 1
# at this point 0 <= dx <= 1 and 0 <= dy <= 1
return dx*dx + dy*dy
Location (x, y)
is part of the island if perlin_noise(x, y) > 0.3 + 0.4 * distance_squared(x,y)
. In the demo you can vary the two constants to see the effects you can get.
I don't think these islands look quite the way you want but this technique might be useful for you in combination with other techniques you're using.
-
\$\begingroup\$ This is exactly the kinda thing I needed, thank you so much! Using your distance_squared method with my existing perlin code has yielded nice big islands with the occasional smaller one to the side, as you said. Is there anything I can do further, such as turbulence or any specific perlin settings, to deform the shape more towards my example? \$\endgroup\$Neophyte– Neophyte2014年07月20日 21:48:21 +00:00Commented Jul 20, 2014 at 21:48
-
\$\begingroup\$ You might be able to use fewer octaves. The lower octaves are smoother than the higher ones. Or you might post-process in some way, to smooth out the corners with some sort of blur algorithm. For example, set a block to water if its eight neighbors include at least 3 water (you might need to try different numbers). This might remove some of the rough borders. \$\endgroup\$amitp– amitp2014年07月21日 01:42:39 +00:00Commented Jul 21, 2014 at 1:42
-
\$\begingroup\$ I added a better demo that lets you adjust more parameters. You can either subtract a circular shape or multiply by a cone. \$\endgroup\$amitp– amitp2016年01月30日 18:57:49 +00:00Commented Jan 30, 2016 at 18:57
-
\$\begingroup\$ btw if you want an island longer than it is tall to fit a wide screen, try an ellipse instead of a circle skillsyouneed.com/num/curved-shapes.html \$\endgroup\$jhocking– jhocking2017年02月19日 23:49:05 +00:00Commented Feb 19, 2017 at 23:49
I don't do a lot of 2d in Unity, but I can still make this pretty easily. So, first you start with a minimum and maximum (x,y) then generate a random. From here you need a basic island tileset (full islands) then you will find a random island in code and instantiate it. Henceforth, you now have a island. TRUELY random generation is much harder.
You must log in to answer this question.
Explore related questions
See similar questions with these tags.