Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Minecraft terrain generation help

Discussion in 'Scripting' started by suctioncup, Dec 5, 2012.

  1. suctioncup

    suctioncup

    Joined:
    May 19, 2012
    Posts:
    273
    Ok, I have written a script that generates perlin noise. What I would like to know, is how do I transfer that texture (generated from the perlin noise) into a blocky world, like a heightmap. Like minecraft.

    How would I go about doing this, coding-wise?
     
    Last edited: Dec 5, 2012
  2. suctioncup

    suctioncup

    Joined:
    May 19, 2012
    Posts:
    273
    Fixed! If anyone wants to know how this is done, PM me.
     
  3. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    How do you generate a minecraft terrain?
     
  4. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,606
    You use a 3D perlin noise function and sample it using coordinates as input. That way you get a float value between 0 and 1 per coordinate, based on which you can decide to place a block or not. For example, place a block if the value is below 0.5. To generate more reasonable terrain, you then want to mix different noise functions, with different scales and offsets. Then you probably want to scale the output based on the y-coordinate to get, on average, higher values the higher up you are and lower values the lower you are, resulting in a surface with air above and denser terrain below.

    This is the general approach, but it gets a lot more complicated when you consider performance. Filling a 16x16x256 chunk, like in minecraft, roughly half with single block objects causes the creation of 8*16*256 = 32768 individual block objects, each having its own drawcall. This gets very slow very fast. What i'm getting at is this: Block worlds are actually not made up of blocks. What you want to do instead, in order to reduce drawcalls, is create as few single mesh objects as possible. In practice this means that you will want to create a mesh, using squares, that puts a square only where a side of a block is exposed to air - and then combine all those squares into a single mesh. This makes a single chunk a single object - large enough such that you are not bottlenecked by thousands of drawcalls, but small enough to allow for redrawing the mesh in a reasonable amount of time, if it was changed by the player.
    However, this approach causes another problem. You cant have more than 1 texture per mesh. There are two sollutions for this problem. You either create one mesh per "block type" in the chunk, which again increases drawcalls by a lot when many materials are used (especially considering self-build structures like houses), or you use a texture atlas, combining all the textures you are going to use into one large one, and then using only part of it based on which block-type the square you are texturing belongs to.

    Talking about performance, you will also want to multithread the whole process so that the game does not freeze whenever a chunk is being generated or updates, and to generally speed up world generation (which is an ongoing process, unlike in most games), as well as update times for editing chunks.

    Procedural / voxel based worlds are probably the single most hardest way to create gameworlds, so i wouldnt recommend it to beginners. What looks very simplistic, is actually a very complex topic.
    That said, if you have some background in programming or are absolutely certain you have enough (weeks to months of) dedication to go from zero to hero on this topic, then you can always try. It was actually one of the first things i worked on in gamedevelopment as well, but i already had a background in computer science and it was still far from easy and i'm still working on it.
     
  5. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    And caves?
     
  6. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    But so much cubes, it must be very very laggy!
     
  7. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    Sorry that I don't know much, but I'm just 11 years old...
     
  8. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,606
    Caves are also produced by subtracting noise from noise, but given that we used noise to create the terrain, there will already be some caves present. And i already wrote that having lots of individual objects is very imperformant, and what to do about it ;)

    Also, asking questions and being curious is absolutely fine, but please refrain from double- or triple posting. Unless somebody already replied, you can just edit your post if you need to add something.
     
  9. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    Can you give a sample,please?
     
  10. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    Minecraft terrain is not easy...
     
  11. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,606
    If you want to understand how it works, you can pretty much follow my above post as a step by step guide by googling a bit for each topic. If you just want a working code example to play around with, then there are plenty of tutorials around that posted their code.

    The first step would look something like this in pseudo code:
    Code (CSharp):
    1. float noiseScale = 0.05f;
    2.  
    3. for (all x < xChunkSize)
    4.     for (all y < yChunkSize)
    5.         for (all z < z ChunkSize)
    6.             if(noise(x * noiseScale, y * noiseScale, z * noiseScale) < 0.5f)
    7.                 Instantiate(block)
    Dont use too large chunk sized for your example, since it will be slow as previously mentioned. If you want to go further you'll need to work on the performance by not using blocks, but instead creating one big mesh that looks as if it was many blocks. The easiest, but least performant, way to do this is just combine the meshes of all instantiated blocks into one mesh. After that it gets more complicated, with the approach described above.
    Cant really post a code example from by project, since i only experimented with blocks and then went with procedurally generating isosurfaces instead (which is even more complicated).

    And no, as i wrote myself: voxel terrain is as far from easy as it gets. Literally.
     
    MadeFromPolygons and Nanior like this.
  12. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    Yes, but if you have hundreds of cubes, it will be very very laggy!
     
  13. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,606
    Yes, i already said that and how to solve the problem twice now..
     
    MadeFromPolygons likes this.
  14. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101
    Yes...
     
  15. Nanior

    Nanior

    Joined:
    May 4, 2019
    Posts:
    101