16
\$\begingroup\$

I'm currently working on a tile-based 2D platformer similar to Terraria in some ways, although I'm having difficulty with the terrain generation. I have some basics done, although they do not come out as anything useful.

I have tried a few different techniques like Perlin Noise and read about some others such as Midpoint Displacement, although I'm not sure what one would be best, or a combination of different techniques to generate different areas. (Such as Midpoint Displacement for the general shape of the terrain and Perlin Noise for the caves.)

I have found an excellent explanation of how I could layer it up with the Accidental Noise Library, although it is in C++, and I do not know enough C++ to compile it into a DLL that I can use from C#. I have tried to copy this in C#, although, I do not know how I can merge two effects together (the gradient for the general base, and then the fractal for detail).

Currently I am using a Plasma Fractal and the results are extremely varied. For example it can generate terrain where there is hardly any surface, or it can generate terrain where there is no surface at all.

An example of an okay map, would be better with some more improvements, though. (Black is solid, white is air):

Good map

And an example of a terrible map. (Black is solid, white is air):

Terrible map

Basically, what I'm asking is, what would be a better way of generating the terrain, or forcing it to make sure that there is a reasonable amount of surface area, with the generation time as quick as possible. Or, alternatively, how I would be able to achieve the same result as the Accidental Noise Library, but in C#.

Any examples would be very much appreciated.

\$\endgroup\$
1
  • \$\begingroup\$ Hi, I was wondering how you made this. I am trying to get an understanding on how to generate worlds such as this and I like the results you are getting. What algorithm are you using because it doesn't look like perlin noise 2D and it's definetely not perlin noise 1D. \$\endgroup\$ Jul 9 '14 at 19:01
9
\$\begingroup\$

I would try sticking with Perlin noise, but adding a weight to it based on height, to ensure a certain average density at certain altitudes. To quote part of Notch's post on Minecraft terrain generation:

So I switched the system over into a similar system based off 3D Perlin noise. Instead of sampling the “ground height”, I treated the noise value as the “density”, where anything lower than 0 would be air, and anything higher than or equal to 0 would be ground. To make sure the bottom layer is solid and the top isn’t, I just add the height (offset by the water level) to the sampled result.

Essentially, you're taking a little slice of a Minecraft terrain. So generate 2D Perlin noise, but weight it so that anything above a certain point is likely to be air, and anything below a certain point is likely to be earth.

This will give you a good ground terrain, with some overhangs and interesting features, as well as some caves and floating islands. (If you don't want floating islands, you can test for them and remove them manually.) This method won't give you things like tunnels, so you'll want a method for adding those in after terrain generation, such as a random-walk.

\$\endgroup\$
5
  • \$\begingroup\$ Not entirely sure that I'm using Perlin Noise to it's full potential. After doing exactly as you described it's just made a lot of caves, with a lot of floating islands. No actual terrain-type definitions. Using a gradient to weigh the results, I get this result. \$\endgroup\$ Aug 12 '11 at 20:53
  • \$\begingroup\$ @Shaded Dimensions - Your Perlin Noise parameters need tweaking. You have very highly variable noise, when what you want is a much smoother, broader pattern. Check out freespace.virgin.net/hugo.elias/models/m_perlin.htm and try messing around with your parameters some. Try lower persistence and fewer octaves. (These terms may vary, so read that article.) \$\endgroup\$
    – dlras2
    Aug 12 '11 at 21:11
  • \$\begingroup\$ Okay, thanks for the link. I also found out that the weight wasn't working as intended after changing a few parameters. \$\endgroup\$ Aug 12 '11 at 21:16
  • \$\begingroup\$ Okay, modified the parameters quite a bit and I have got something that is fairly acceptable, for now, at least. I also removed generating caves just for this test, as I wanted to get the actual terrain done first. This is the final result. Just need to add checks to remove those floating islands. Thanks again. \$\endgroup\$ Aug 12 '11 at 22:09
  • \$\begingroup\$ @Shaded Dimensions - Nice! A lot of time, good terrains come from just tweaking parameters and overlaying noise. It'll take a while before you get something you're very happy with, but you can always use what you have now and come back to add finishing tweaks. Good luck! \$\endgroup\$
    – dlras2
    Aug 12 '11 at 23:58
1
\$\begingroup\$

You need some kind of coherent noise function, I would recommend go with Perlin or OpenSimplex noise, it is well known algorithm and there many implementation of same functions for different languages: C/C++, C#, Python, Java, JS etc...

Basically you just need to use noise function to generate value for x/y coordinate and apply math function on top of that to get desired effect.

Than you can can generate many map for different type of tiles, and mix them. For example every type of minerals can have separate map.

For example let's say you have mineral A and mineral B.

  • Noise function with seed A for Mineral A, will give you certain value in point (x,y), and same way another noise value for Mineral B, and then you just choosing which mineral's have higher value.
  • If all mineral bellow some threshold, than just using some common mineral like dirt.
  • You can use it as binary so mineral is there or not, or you can use noise value, to generate mineral yield for that block.
  • Another approach, you can take use noise function to map to different minerals. For example 0 - 0.5 is dirt, 0.5-0.7 dirt with stone, 0.7-0.85 stone with iron, 0.85-0.95 iron with gold, 0.95 - 1.0 pure gold.
  • You may want to introduce some probability factor based on depth noise, so some mineral will be more often on certain height than other. I would recommend some kind of https://en.wikipedia.org/wiki/Binomial_distribution, or any other function which plot looks like that.

I was searching similar thing for 3D terrain height generation recently, it is not exactly what you asking, but here is good xample how same noise function can be used for different variation. https://www.youtube.com/watch?v=lctXaT9pxA0

  • He used same perlin for different things like: flat land, mountain range, biomes, geographical zones.

Also putted some analysis about noise functions: Enumerate list of noise algorithm for 3D terrain heighmap generation

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.