rutgerkok / WorldGeneratorApi

Minecraft Spigot plugin that enables other plugins to customize world generation
MIT License
95 stars 9 forks source link

Getting a chunk #30

Closed tastybento closed 3 years ago

tastybento commented 3 years ago

Hi,

I would like to get a chunk from the generator. I have this code to define the generator:

cg = WorldGeneratorApi
                .getInstance(getPlugin(), 0, 5)
                .createCustomGenerator(wordRef, generator -> {
                    // Set the noise generator
                    generator.setBaseNoiseGenerator(new BasicWorldGenerator(this, wordRef));
                    generator.getWorldDecorator().withoutDefaultDecorations(DecorationType.SURFACE_STRUCTURES);
                    generator.getWorldDecorator().withoutDefaultDecorations(DecorationType.STRONGHOLDS);
                });

I then try to obtain a chunk using:

ChunkData cd = cg.generateChunkData(chunk.getWorld(), new Random(), chunk.getX(), chunk.getZ(), grid);

but I then get this error in the console:

java.lang.UnsupportedOperationException: This is a dummy class, used because a custom world generator was registered, but no base chunk generator has been set. Please use WorldGenerator.setBaseChunkGenerator(...).
    at nl.rutgerkok.worldgeneratorapi.internal.bukkitoverrides.DummyBukkitChunkGenerator.generateChunkData(DummyBukkitChunkGenerator.java:43) ~[?:?]

In looking at the JavaDoc for createCustomGenerator it says:

Registers a custom world generator for the given world. Once the world is loaded, the code passed as the second argument of this method will be run. This code must first set the base chunk generator using WorldGenerator.setBaseChunkGenerator(BaseChunkGenerator), and can then (optionally) make other modifications.

This method is intended to be called from within the Plugin.getDefaultWorldGenerator(String, String) method. It returns a dummy ChunkGenerator that can be passed back to Bukkit. This returned ChunkGenerator is not actually capable of generating terrain: this is why it must be replaced using WorldGenerator.setBaseChunkGenerator(BaseChunkGenerator).

If you don't want to modify the base terrain, then you must not use this method. You must also not override Bukkit's Plugin.getDefaultWorldGenerator(String, String) method. Instead, you must listen for the WorldGeneratorInitEvent and modify the world generator inside that event.

However, setBaseChunkGenerator is deprecated and it's JavaDoc says it is replaced by setBaseTerrainGenerator(BaseTerrainGenerator), which says:

Sets the basic terrain generator. This method (unlike setBaseNoiseGenerator(BaseNoiseGenerator)) provides you total block-by-block control over the shape of your terrain. However, structures might be placed on unsuitable locations, as unlike setBaseNoiseGenerator(BaseNoiseGenerator) the terrain shape is not modified to accommodate for structures like villages.

So, it seems that setBaseNoiseGenerator(BaseNoiseGenerator) should be acceptable and the exception shouldn't be thrown. Do you agree? Is there any way to get the chunk from the chunk generator? The reason I need it is because I need to regenerate the chunk, i.e., put it back to what it was before.

rutgerkok commented 3 years ago

Indeed, this won't work as you have found out. Plugins are not allowed to direclty call this method; and neither is Minecraft. (But Minecraft is automatically rewired by WorldGeneratorApi so that it doesn't do that.) I've created a wiki page with more information: https://github.com/rutgerkok/WorldGeneratorApi/wiki/Dummy-class-error

tastybento commented 3 years ago

Thank you! Really good info!