The always up-to-date definitive guide to terrain generation: part one - prerequisites and setup

Discussion in 'Resources' started by jtjj222, Aug 16, 2012.

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

    jtjj222

    From personal experience, I know how hard it is to make terrain generators. Hell, I've been going at it for about 6 months and I don't have anything decent out there! This is to help everyone who wishes to learn how to make world generators. I plan to make a series about the topic, covering everything I know, from porting to single player, to biomes, to other forms of noise generation, but I still consider myself a beginer on the subject. I would like the help of the bukkit community, and all of the expert terrain guru's out there, to help make this sereis the definitive guide to minecraft terrain generation. :D I will write a new part to this series whenever I can, but this is the first in a long line. Pm me if there is anything you want to add.

    Part 0: Prerequisites
    Let me start by explaining a few things:

    A chunk is a 16 by 16 by 256 piece of the world. A chunk(or block) section is a 16x16x16 part of a chunk.

    A chunk generator is a piece of code that defines the "big" terrain features like hills, valleys...
    A block populator is a piece of code that defines the "little" terrain features, like npc villages, dungeons...

    This tutorial assumes that you have made bukkit plugins before, but just in case, there is a brief setup guide below.

    Part 1: setup:
    Ok, so first we will start by setting up everything we will need during this tutorial series. Start by creating a new java project in your IDE:
    [​IMG]
    Link the latest RB of bukkit to your project, so that you can use bukkit's methods.
    At the root of your project, create a file called plugin.yml, and add the following to it:
    Code:
    name: BasicTerrain
    version: 1.0
    main: me.<your name>.BasicTerrain.BasicTerrain
    load: startup
    [​IMG]

    Create a new package called me.<your name>.BasicTerrain and make a new java class in it called BasicTerrain.java.
    [​IMG]
    Add extends JavaPlugin to your class definition as usual, and add your onEnable and onDisable methods. Add the following code to your class like so:

    Code:java
    1.  
    2. /**
    3. *
    4. * @param worldName
    5. * The name of the world the generator is being applied to
    6. * @param GenId
    7. * The id (if any) specified by the user. It can be used if the plugin
    8. * wants to have multiple generators in one plugin. More on this later.
    9. * @return
    10. * The ChunkGenerator that this plugin provides
    11. */
    12. public ChunkGenerator getDefaultWorldGenerator(String worldName, String GenId) {
    13. return new me.<your name>.BasicTerrain.BasicChunkGenerator();
    14. }
    15.  

    [​IMG]
    Create a class called BasicChunkGenerator in the same place as your main class file, and add extends ChunkGenerator to it's class definition.
    Add the following methods:
    Code:java
    1.  
    2. /**
    3. *
    4. * @param x
    5. * X co-ordinate of the block to be set in the array
    6. * @param y
    7. * Y co-ordinate of the block to be set in the array
    8. * @param z
    9. * Z co-ordinate of the block to be set in the array
    10. * @param chunk
    11. * An array containing the Block id's of all the blocks in the chunk. The first offset
    12. * is the block section number. There are 16 block sections, stacked vertically, each of which
    13. * 16 by 16 by 16 blocks.
    14. * @param material
    15. * The material to set the block to.
    16. */
    17. void setBlock(int x, int y, int z, short[][] chunk, Material material) {
    18. if (y < 256 && y >= 0 && x <= 16 && x >= 0 && z <= 16 && z >= 0) {
    19. if (chunk[y >> 4] == null)
    20. chunk[y >> 4] = new short[16 * 16 * 16];
    21. chunk[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = (short) material.getId();
    22. }
    23. }
    24. @Override
    25. /**
    26. * @param world
    27. * The world the chunk belongs to
    28. * @param rand
    29. * Don't use this, make a new random object using the world seed (world.getSeed())
    30. * @param biome
    31. * Use this to set/get the current biome
    32. * @param ChunkX and ChunkZ
    33. * The x and z co-ordinates of the current chunk.
    34. */
    35. public byte[][] generateBlockSections(World world, Random rand, int ChunkX,
    36. int ChunkZ, BiomeGrid biome) {
    37. return null;
    38. }
    39.  


    Now, this might take some explanation, so stay tuned for the next part instalment in this series, and please please please leave feedback! The next tutorial should be done by tomorrow, and it will cover the cool part of this.

    Error#1: Change getDefaultChunkGenerator to getDefaultWorldGenerator

    Part 2: http://forums.bukkit.org/threads/th...ation-part-two-making-a-flat-landscape.94063/
    Part 3: http://forums.bukkit.org/threads/th...eneration-part-three-populators-galore.94083/
    Part 4: http://forums.bukkit.org/threads/th...-to-terrain-generation-part-four-hills.94164/
    Part 5: http://forums.bukkit.org/threads/th...-to-terrain-generation-part-5-3d-noise.94312/

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
  2. Offline

    Tux2

    Awesome start! I'm looking forward to seeing the rest of the series.
     
  3. Offline

    NSArray

    Great tutorial! I'm currently working on a generator, but no matter what seed I use I always get the exact same world. I've spent a little over 2 hours trying to figure out why I wasn't getting the "randomness", but after ready this I think it may be caused by me using the given Random object. Is that a common side effect of using the given one?
     
  4. Offline

    evilmidget38 Retired Staff

    You should put all three tutorial parts in the same thread, it'd be easier to keep track of them all.
     
  5. Offline

    jtjj222

    yes, but then whenever I update one of them, I would have to re-do the indentation in the code tags for the entire series.

    Yes, instead create a random object using the world seed:
    Code:java
    1. Random rand = new Random(world.getSeed());


    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
    mactso likes this.
  6. Offline

    NSArray

    Thanks for the help :)

    Would I do the same for block populator?
     
  7. Offline

    jtjj222

    No. If you did, each chunk populated would look the same. Use the provided random object for populators.
     
  8. Offline

    Uniclaw

    Just awesome!!
     
  9. Offline

    ZachBora

  10. Offline

    evilmidget38 Retired Staff

    They're working for me.
     
    jtjj222 likes this.
  11. Offline

    ZachBora

    Then it must be the company proxy :'(
     
  12. Offline

    DevRosemberg

    jtjj222 Hey, i've got a problem. Bukkit dosent want to generate my world:

    Code:java
    1. Bukkit.createWorld(new WorldCreator(player.getName() + "_BuildSession").generateStructures(false));
     
  13. Offline

    jtjj222

    Does it crash, or give you any errors? How long are you waiting for it to finish? Are you calling that from the main thread? What method is that in, and when does it get called?
     
  14. Offline

    DevRosemberg

    jtjj222 Never mind i was being stupid and though i had setup maven to compile directly to the Test Server. Was compiling to the normal /target. Thanks for trying to help though!
     
    jtjj222 likes this.
Thread Status:
Not open for further replies.

Share This Page