-
Notifications
You must be signed in to change notification settings - Fork 9
Your first world generator
Software tools usage | |
---|---|
Uses Bukkit | Yes |
Uses resource packs | No |
Uses WorldGeneratorApi | No |
This tutorial assumes you have some basic knowledge in creating a Bukkit plugin. You should be able to create a Bukkit plugin that adds a command named /hi
, that simply prints "Hello!" when executed. If not, please head over to the Plugin Tutorial page at the Bukkit wiki.
- This tutorial can be edited by anyone, you just need a (free) GitHub account. So if you want to improve it, please do!
- If you have any questions or comments, or get stuck somewhere, please contact me!
rutgerkok
We will create a very basic plugin, called Pancake
. It is used to create a flat landscape.
Let's use the following code for the plugin.yml
:
name: Pancake
version: 1.0
main: your.package.here.PancakeMain
load: startup
api-version: 1.17
This plugin.yml
file creates a plugin named Pancake
, with the main class PancakeMain
placed in the package your.package.here
. Feel free to change the names. The plugin is set to load at startup
, so before the worlds are active. That is necessary: if your plugin would be loaded after the initial terrain had generated, it would be useless!
Our main class starts out empty:
// This is the PancakeMain.java file
package your.package.here;
import org.bukkit.plugin.java.JavaPlugin;
public class PancakeMain extends JavaPlugin {
// Pretty empty, isn't it?
}
If you see an error about JavaPlugin
missing, then you forgot to add the Bukkit API.
Ok, let's add some code. First, we create a new class called PancakeGenerator
:
// PancakeGenerator.java
package your.package.here;
import java.util.Random;
import org.bukkit.HeightMap;
import org.bukkit.Material;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.WorldInfo;
/**
* This the actual terrain generator.
*
*/
public class PancakeGenerator extends ChunkGenerator {
private static final int CHUNK_SIZE = 16;
private static final int TERRAIN_HEIGHT = 66;
@Override
public void generateNoise(WorldInfo world, Random random, int x, int z, ChunkData chunk) {
chunk.setRegion(0, chunk.getMinHeight(), 0, CHUNK_SIZE, TERRAIN_HEIGHT, CHUNK_SIZE, Material.STONE);
}
@Override
public int getBaseHeight(WorldInfo world, Random random, int x, int z, HeightMap type) {
return TERRAIN_HEIGHT;
}
@Override
public boolean shouldGenerateBedrock() {
return true;
}
@Override
public boolean shouldGenerateCaves() {
return true;
}
@Override
public boolean shouldGenerateDecorations() {
return true;
}
@Override
public boolean shouldGenerateMobs() {
return true;
}
@Override
public boolean shouldGenerateNoise() {
return false; // We do this ourselves
}
@Override
public boolean shouldGenerateStructures() {
return true;
}
@Override
public boolean shouldGenerateSurface() {
return true;
}
}
This is quite a lot of code, so let's go through it. The method generateNoise
will be called once for every chunk that is being generated. It must decide the general shape of the terrain. To do this, it must place only stone and water, and leave all other blocks as air. (In the Nether and End, instead of stone you must place Netherrack and End Stone, respectively.) Usually, this is done by using the results of a so-called noise function. However, here we won't be generating noisy terrain, we'll just provide superflat terrain.
The chunk starts out completely empty. This is because we have overridden the method shouldGenerateNoise
to make it return false
. In our generateNoise
method, we fill a number of layers (y = 0
to TERRAIN_HEIGHT
) of the chunk with stone. Because this method is called for every newly generated chunk, the entire world will become superflat.
We have also overridden a bunch of other methods: shouldGenerateSurface
, shouldGenerateStructures
, etc. They all return true
. This makes Bukkit automatically add "decorations" like caves, ores, trees, villages and strongholds in exactly the same way as regular Minecraft would. This can be disabled by making the appropriate methods return false
.
We're not done yet. To actually use this flat terrain generator, we first need to tell the server it exists. That is done by updating the PancakeMain
class. Update the file so that it now looks like this:
// PancakeMain.java
package your.package.here;
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 {
// The class is no longer empty, we now add this method
// It is like onEnable, but for world generators
@Override
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
getLogger().info("Activated for world \"" + worldName + "\"");
return new PancakeGenerator();
}
// End of addition to class
}
We see a new method called getDefaultWorldGenerator
. This method is part of the Bukkit API. It is very similar to onEnable
, except it is called once for every world, instead of just once for the whole server. You can still add an onEnable
method if your plugin needs to do other things besides terrain generation (like listening for events), but for now we won't need an onEnable
method.
The method consists of just two lines. The first simply logs a message, so that the server admin knows that the Pancake plugin is in use for that world. The second actually returns an instance of our chunk generator class.
You can now compile your plugin, and then place the JAR file of your plugin in the plugins
folder of your server. Once you start or restart the server (not reload!), your plugins will be active.
If you have installed Multiverse, you can type the following command to enter your world:
/mv create world_name_here normal -g Pancake
Here, Pancake
must be the name of your plugin, as supplied in the plugin.yml
file. So if you changed the name there, also change it here. You can now teleport to this world (use /mv tp world_name_here
) and see your world generator.
If you have not installed Multiverse, and/or if you want to modify one of the default worlds, you'll need to edit the bukkit.yml
file. Add the following at the end of the file:
worlds:
world:
generator: Pancake
If your default world isn't simply called world
(so if you have changed the name in the server.properties
file), you need to change world
in this file as well.
If you restart your server, any new chunks in the default world should consist of flat terrain.
Example terrain. Note that the ground is completely flat. You may of course spawn in a different biome, so the terrain may look different on your server.