4
\$\begingroup\$

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!

\$\endgroup\$
6
  • \$\begingroup\$ Try simplex noise \$\endgroup\$
    – Savlon
    Commented 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
    Commented 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
    Commented 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
    Commented Jul 20, 2014 at 14:57
  • \$\begingroup\$ What does that have to do with z-coordinate? \$\endgroup\$
    – Neophyte
    Commented Jul 20, 2014 at 17:02

2 Answers 2

12
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\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
    Commented 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
    Commented 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
    Commented 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
    Commented Feb 19, 2017 at 23:49
-2
\$\begingroup\$

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.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .