The always up-to-date definitive guide to terrain generation: Part 7 - Biomes

Discussion in 'Resources' started by jtjj222, Aug 1, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    jtjj222

    Part one
    Part Two
    Part Three
    Part Four
    Part Five
    Part Six

    2013-08-01_12.02.25.png 2013-08-01_12.05.44.png 2013-08-01_17.53.46.png 2013-08-01_17.54.20.png 2013-08-01_21.47.04.png

    I used different block types per biome, and a small scale on the biome generator so that you can see how smooth the edges between biomes are. Note in the last picture, the mycelium biome is supposed to be entirely flat, but instead of a sharp line, the edge gradually transitions into the surrounding biomes.

    The code for the above example, in the new github repository.
    There is a lot to cover in this tutorial, so instead of walking you through the code, I'll just show you the interesting parts, and explain how it works, along with some code snippets.

    How to read the suggested biomes, and set your own:

    Bukkit provides every chunk generator with a BiomeGrid object. It allows you to read the suggested biome of a region, and also set it. If you set a biome using this object, future calls to block.getBiome() and world.getBiomeAt() will return your biome, and this is the biome that is sent to the client.

    Code:java
    1.  
    2. //get a biome (note that x and z are in chunk co-ordinates)
    3. biomeGrid.getBiome(x,z);
    4. //set a biome (note that x and z are in chunk co-ordinates)
    5. biomeGrid.setBiome(x, z, Biome.SWAMPLAND);
    6.  


    Of course, the question in your mind must be, "Well, that's cool, but how do I handle transitions?"

    Transitions using combinations of biomes:

    The main reason this tutorial is over a year late is because I honestly had no idea how to handle transitions. I tried looking through the minecraft source code, tutorials and everything, and I couldn't figure out how to handle them. Perhaps I just didn't look hard enough, but I will share with you the only method I can think of to handle transitions. Hopefully, in the comments below, you can propose other ways of handling biome transitions, and also improvements to this method.

    In order to handle the biome transitions, we generate the biomes ourselves (so that we can quickly get the surrounding biome data). We generate a map of temperature and precipitation values using a noise function (perlin noise in this example), and then look them up in a Whittaker diagram to see how similar the conditions of our block are to the biomes we've defined.

    This, by the way, is a Whittaker diagram:
    [​IMG]
    We can then use the similarity to the most similar biomes to control how much those biome's noise features influence the features of the current block. For example, a block that has a temperature of 20 degrees (using the diagram above) and rainfall of 120cm would be mostly temperate deciduous forest, but also part temperate grassland and part tropical seasonal forest. By treating the biome of a location as a combination of nearby biomes, we can smoothly transition from one to the other.

    In the code, I have taken some liberties in how I defined the whittaker diagram (defined in Biomes.java), just to make it easier to write. I pretty much guessed the values, but it still serves as a useful example.

    Transitions using transition biomes:

    There is another aspect to smooth transitions, noticeably used by the default generator. By using smaller transition biomes, such as island shores and frozen rivers, you can help smooth the transition further. You could, if you desired, only use transition biomes, and then smooth out the edges of the biome with a smoothing function, but I personally think that using a combination of transition biomes and combinations of biomes creates a better look, and is cleaner in code.

    What's with the bands of biomes, and large artefacts in the example?

    The "bands" of biomes are caused because we are using a perlin noise generator to generate the temperature and rainfall maps. Perlin noise is not the best choise, and in part 7.5, I plan to show you a more biome-like alternitave, voronoi noise. Here is a map of the biomes generated with Voronoi, then simplex, then perlin noise, followed by a map of the default generator's biomes (thanks mncat77 and Courier for the images):

    [​IMG][​IMG][​IMG]
    [​IMG]
    If you look closely in the last one, you can see that it does in fact use fractal voronoi noise.

    The other artefacts are caused by how close together the biomes in the example are.

    What does generateExtBlockSections have to do with anything?

    I included that in the example because of the name of this series; Always up-to-date. In order to place newer blocks (with a block id higher than 127, such as a beacon) you need to use this method instead of generateBlockSections. In Java, bytes can hold values between -128 and 127, but shorts can hold -32,768 to 32,767! The generateExtBlockSections method is called the same way as generateBlockSections, the only difference is it stores shorts instead of bytes.

    Performance issues:

    Generating biomes like this triples the number of noise values you have to take. If you are using a lot of 3d noise, that can cause you to have to take up to 16*16*256*3 3d noise values per chunk! To solve this, we can interpolate (guess) the noise values for some of the blocks, without many noticeable differences. That is the subject of one of the next tutorials (Hint hint, I'd love some help).

    Where do I go from here?

    The parts I didn't cover include fine-tuning the whittaker diagram, and implementing all of the possible biomes (including oceans). I hope I can eventually cover those, but first I need to implement them! If you end up doing that, I beg of you to post your findings below. If there is another topic you want covered, a bug fix, or a suggestion to one of the existing tutorials, pm me or post below. If you would love to suggest improvements to any of the methods I discuss, I urge you to tell me! I would always love some help! Please don't be afraid to ask me anything either. No question is too small!

    Reserved.

    I would like to thank Icyene (for the state machine idea, and other help), mncat77 (for the pics, helping me think through my method above, many ideas, his voronoi noise tutorial, and his work deobfuscating the minecraft biomes for the next tutorial), and Courier for their many contributions.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 3, 2016
    mariosunny, mactso, Chlorek and 8 others like this.
  2. For anyone curious about that here is a slideshow (kinda) in that zip with the diffrent layers. You should see connections between most of the pictures ( zooms/ density/smoothing ), if you think they really don't fit together just look closely and look how it was zoomed in (sometimes really far):
    https://www.dropbox.com/s/7uv1n7sw9aiwo8w/vanillagen.zip
    Also hawkfalcon :D .
     
  3. Offline

    hawkfalcon

    This was a long time ago ;-p
     
  4. Offline

    TigerHix

    Nice thread nice thread. *Click Like*
     
  5. Offline

    chasechocolate

    I love all your world generation tutorials. Ever thought of making a video? :) can't wait until next one comes out :D
     
    jtjj222 likes this.
  6. Offline

    epicfacecreeper

    How would I generate multi-chunk structures like mineshafts?

    Also, I have black spots in my terrain that are only fixed by restarting the server. Any ideas?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 3, 2016
  7. Structures are generated by BlockPopulators (see part 3 of the tutorial series).

    Those are lighting errors probably. They go away with time and this will be fixed in 1.7 (@jeb_ worked on that).

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 3, 2016
  8. Offline

    epicfacecreeper

    I know how to use BlockPopulators, but there are no guarantees of chunks on either side being generated, so I can't make larger structures.
     
  9. You can check if they are generated, you can make them generate or you can just simply check if a part in that chunk would be generated by adding a per chunk random system (or accessing the one the bukkit api uses), so you can generate structures that are larger than 1 chunk.
     
  10. Offline

    epicfacecreeper

    They're not lighting errors. [​IMG]
     
  11. Those are chunks that aren't loaded for your client. There is a F3 shortcut to reload them for the client.
     
  12. Offline

    epicfacecreeper

    Tried that, F3+A, doesn't do anything. Only thing that works is to relog.
     
  13. Offline

    valon750

    I am so lost by this...

    I already have the general terrain generation sorted, as you're aware from my message. *hint hint*

    So it seems like I'd have to make quite a lot of changes, any chance you or someone could have a look at my project?
     
  14. Offline

    Schuwi

    Can you maybe make a tutorial about generating caves?

    Thanks in advance :)
     
  15. Offline

    UnluckyNinja

    Nice work, jtjj222 . Learnt a lot. I'm awaiting your Part 8.;) Keep going.
     
  16. Offline

    Rael

    Did 7.5 ever get written? I can't find it via search.
     
Thread Status:
Not open for further replies.

Share This Page