Why biomes aren't updating?

  • After careful consideration and due to limited usage, we’ve made the decision to discontinue the PaperMC forums. Moving forward, we recommend using Hangar for plugin uploads, and for all other community discussions and support, please join us on Discord.

maksim2498

New member
May 7, 2023
2
0
1
24
Moscow, Russia
I'm writing a PaperMC plugin that should restore all biomes in the world within a specified radius.
The issue here is that biomes aren't restoring.

Can someone please tell me what am i doing wrong?

I've tested this code on PaperMC 1.19.0-1.19.4

Here is a full plugin code:

Java:
package ru.fominmv.biome_fixer;

import org.bukkit.Chunk;
import org.bukkit.plugin.java.JavaPlugin;

public class BiomeFixer extends JavaPlugin {
    @Override
    public void onEnable() {
        final int MIN_X        = -4000;
        final int MAX_X        =  4000;

        final int MIN_Z        = -4000;
        final int MAX_Z        =  4000;

        final int TOTAL_CHUNKS =  (int) Math.ceil((float) (MAX_X - MIN_X) / 16.f)
                               *  (int) Math.ceil((float) (MAX_Z - MIN_Z) / 16.f);

        final int INIT_DELAY   =  20 * 15;
        final int DELAY        =  2;

        final var server       =  getServer();
        final var logger       =  server.getLogger();
        final var scheduler    =  server.getScheduler();
        final var world        =  server.getWorld("world");

        assert world != null;

        final var s = new Object() {
            Runnable step;

            int chunksProcessed = 0;

            int x = MIN_X;
            int z = MIN_Z;
        };

        s.step = () -> {
            if (world.isChunkGenerated(s.x, s.z)) {
                final var chunk = world.getChunkAt(s.x, s.z);
                fixChunk(chunk);
            }

            ++s.chunksProcessed;

            final var message = String.format("%d/%d chunks processed", s.chunksProcessed, TOTAL_CHUNKS);
            logger.info((message));

            s.x += 16;

            if (s.x >= MAX_X) {
                s.x  = MIN_X;
                s.z += 16;
            }

            if (s.z >= MAX_Z) {
                logger.info("Biome recovery is done");
                return;
            }

            scheduler.scheduleSyncDelayedTask(this, s.step, DELAY);
        };

        final var message = String.format("Biome recovery will be started in %d secods...", INIT_DELAY / 20);

        logger.info(message);

        scheduler.scheduleSyncDelayedTask(this, () -> {
            logger.info("Biome recovery has started");
            s.step.run();
        }, INIT_DELAY);
    }

    private void fixChunk(final Chunk chunk) {
        final var server = getServer();
        final var logger = server.getLogger();

        if (!chunk.isLoaded() && !chunk.load()) {
            logger.info("Chunk loading failed");
            return;
        }

        final var world         = chunk.getWorld();
        final var biomeProvider = world.vanillaBiomeProvider();

        assert biomeProvider != null;

        for (int x = 0; x < 16; x += 4)
            for (int z = 0; z < 16; z += 4)
                for (int y = world.getMinHeight(); y < world.getMaxHeight(); y += 4) {
                    final var block = chunk.getBlock(x, y, z);
                    final var biome = biomeProvider.getBiome(world, block.getX(), block.getY(), block.getZ());

                    block.setBiome(biome);
                }


        if (!chunk.unload(true))
            logger.info("Chunk unloading failed");
    }
}
 
Last edited:

maksim2498

New member
May 7, 2023
2
0
1
24
Moscow, Russia
The issue is solved. The problem was that in world.getBiome(x, z) x and z aren't the same as block coordinates. They are a factor of 16, i.e. a number of chunk rather than a coordinate within it