Skip to content

Decorations

Rutger Kok edited this page Apr 26, 2020 · 4 revisions

Generating the blocks of the terrain is divided into two steps by WorldGeneratorApi. In the first step, the base terrain is generated. In default Minecraft, the terrain consists solely of water, stone and air. In the second step, the so-called decorations are added. Decorations can be anything from caves and villages to flowers and trees. This page explains how to add and remove decorations from your world.

Setup

If you have followed this tutorial, then you'll have a class similar to the one below: (you can also download the complete source code here, and find setup instructions here).

package nl.rutgerkok.pancakeworldgenerator;

import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin;

import nl.rutgerkok.worldgeneratorapi.WorldGeneratorApi;
import nl.rutgerkok.worldgeneratorapi.WorldRef;

public class PancakeMain extends JavaPlugin {

    @Override
    public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
        return WorldGeneratorApi
                .getInstance(this, 0, 5)
                .createCustomGenerator(WorldRef.ofName(worldName), generator -> {
                    // Code changing the world generator goes here
                    generator.setBaseChunkGenerator(new PancakeGenerator());
                    this.getLogger().info("Enabled the Pancake world generator for world \"" + worldName + "\"");
                });
    }

}

Removing default Minecraft decorations

That tutorial produced terrain similar to the image below: (of course, you may be in a different biome)

Example terrain

As you can see, all of Minecraft's default decorations are present. If you want to design your world generator from scratch, then you'll want to get rid of them. You can do this by adding a new line after the generator.setBaseChunkGenerator(new PancakeGenerator()); line:

                .createCustomGenerator(WorldRef.ofName(worldName), generator -> {
                    // Code changing the world generator goes here
                    generator.setBaseChunkGenerator(new PancakeGenerator());
                    generator.getWorldDecorator().withoutAllDefaultDecorations();
                    this.getLogger().info("Enabled the Pancake world generator for world \"" + worldName + "\"");
                });

It's also possible to selectively disable vanilla decorations. For example, if you only want to disable the caves and ravines, you can instead use this line:

generator.getWorldDecorator().withoutDefaultDecorations(DecorationType.CARVING_AIR);

Adding custom decorations

You can also add custom decorations:

generator.getWorldDecorator().withCustomDecoration(DecorationType.UNDERGROUND_ORES, new MyOreGenerator());

Here, MyOreGenerator must be a class that implements the Decoration interface. The exact decoration type you specify is not that important; WorldGeneratorApi won't for example check if your decoration actually looks like an ore. What type you choose only influences the moment your decoration is spawned. Ores are always spawned after caves, for example.

In the following example, 1 to 5 emerald ores are generated in each chunk, from y = 20 to y = 39.

public class MyOreGenerator implements Decoration {

    @Override
    public void decorate(DecorationArea area, Random random) {
        int oreCount = random.nextInt(5) + 1;
        for (int i = 0; i < oreCount; i++) {
            int x = area.getCenterX() - DECORATION_RADIUS + random.nextInt(16);
            // DECORATION_RADIUS is a constant provided by the Decoration interface - it is equal to 8
            int y = 20 + random.nextInt(20);
            int z = area.getCenterZ() - DECORATION_RADIUS + random.nextInt(16);
            area.setBlock(x, y, z, Material.EMERALD_ORE);
        }
    }
}

Decorations may only place blocks inside the given decoration area. This is a 2 x 2 chunk area, or 32 x 32 blocks. You are only supposed to decorate a 16 x 16 blocks square at the center. So there is 8 blocks of padding in all directions, which you can use to generate a bit larger structes. See this image:

Explanation of decorations
Here, trees are only spawned inside the center area. Leaves can extend a bit into the padding area.

Base decorations

There are also the so-called "base decorations". They operate on a single chunk only. They are spawned before all other decorators, and are used to place things like grass, dirt and sand. To add a custom base decorator, you must create a class that implements BaseChunkGenerator instead of Decoration.