Adjusting the vanilla biome generator - rutgerkok/WorldGeneratorApi GitHub Wiki

In this tutorial, we built a very simple biome generator. You can expand it however you like, and make it as complex as you like. However, sometimes you just want to make some tweaks to the vanilla biome generator. Maybe you want to replace all deserts with forests, or maybe you want a large taiga at the world origin.

This is not possible with the Bukkit API, at least not unless you code an exact copy of the vanilla biome generator. However, with WorldGeneratorApi, it is actually quite straightforward.

Software tools usage
Uses Bukkit Yes
Uses resource packs No
Uses WorldGeneratorApi Yes

First, add WorldGeneratorApi to your project. Next, add WorldGeneratorApi to your plugin.yml file:

depend: [WorldGeneratorApi] 

If your plugin already depends on other plugins, you can write that as depend: [OtherPlugin, AnotherPlugin, WorldGeneratorApi].

Next, we're not going to use the Bukkit API to provide a biome generator. So remove your getDefaultBiomeGenerator method, if you were using that.

Instead, we're going to listen to the WorldInitEvent. In that event, we will get the current biome generator of the world and replace it by our own extended version. As a first step, we will code our extended biome generator. It will call into the original biome generator. If it finds a desert biome, it replaces it by a forest. Otherwise, the original biome is passed through.

import java.util.Objects;

import org.bukkit.block.Biome;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.WorldInfo;

class YourModifiedBiomeGenerator extends BiomeProvider {

    private final BiomeProvider originalBiomeGenerator;

    WiderRiverGenerator(BiomeProvider originalBiomeGenerator) {
        this.originalBiomeGenerator = Objects.requireNonNull(originalBiomeGenerator, "originalBiomeGenerator");
    }

    @Override
    public Biome getBiome(WorldInfo worldInfo, int x, int y, int z) {
        Biome originalBiome = this.originalBiomeGenerator.getBiome(worldInfo, x, y, z);
        if (originalBiome == Biome.DESERT) {
            return Biome.FOREST;
        }
        return originalBiome;
    }

    @Override
    public List<Biome> getBiomes(WorldInfo worldInfo) {
        return originalBiomeGenerator.getBiomes(worldInfo);
    }
}

Next, we need to inject this class in the world. We first register for events, and next we listen to the WorldInitEvent, in which we install our biome generator. For simplicity, we place all code in the main class of the plugin:

import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.plugin.java.JavaPlugin;

import nl.rutgerkok.worldgeneratorapi.WorldGeneratorApi;

public class TheMainClassOfYourPlugin extends JavaPlugin implements Listener {

    @Override
    public void onEnable() {
        // Necessary fo the WorldInitEvent
        getServer().getPluginManager().registerEvents(this, this);
    }

    @EventHandler(priority = EventPriority.HIGH)
    public void onWorldInitEvent(WorldInitEvent event) {
        World world = event.getWorld();
        getLogger().info("Setting biome provider for " + world.getName());

        // Replace the version here (1.3) with the actual version of WorldGeneratorApi that built against
        WorldGeneratorApi worldGeneratorApi = WorldGeneratorApi.getInstance(this, 1, 3); 

        // Here we construct the new biome generator
        BiomeProvider original = worldGeneratorApi.getBiomeProvider(world);
        worldGeneratorApi.setBiomeProvider(world, new YourModifiedBiomeGenerator(original));
    }
}

That's it!

Using this method, the biome generator will be injected into all worlds. If you don't want that, implement some filtering in the WorldInitEvent. For example, the following code checks whether the world name is included in the world-names setting of the config file of your plugin.

    if (!getConfig().getStringList("world-names").contains(world.getName()) {
        return; // Don't inject the biome generator
    }
⚠️ **GitHub.com Fallback** ⚠️