Solved Generating Chunk Data

Discussion in 'Spigot Plugin Development' started by Spedwards, Jun 17, 2016.

  1. Creating a chunk generator in my plugin that's relatively simple, though it's not working. There aren't too many guides on chunk generators and those that exist appear to be outdated, so it's difficult to tell where I'm going wrong.

    I have my Chunk Generator class and the errors below.

    Code (Text):
    public class DeathGamesGenerator extends ChunkGenerator {
     
        List<BlockPopulator> populators = new ArrayList<BlockPopulator>();
     
        public DeathGamesGenerator() {
            populators.add(new MushroomPopulator());
        }
     
        @Override
        public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) {
            List<Biome> blacklist = Arrays.asList(Biome.BEACHES, Biome.COLD_BEACH, Biome.FROZEN_OCEAN, Biome.HELL, Biome.MUSHROOM_ISLAND, Biome.MUSHROOM_ISLAND_SHORE, Biome.OCEAN, Biome.SKY, Biome.STONE_BEACH, Biome.VOID);
         
            if (blacklist.contains(biome.getBiome(x, z))) { // <- line 25
                biome.setBiome(x, z, Biome.PLAINS);
            }
         
            return createChunkData(world);
        }
     
        public List<BlockPopulator> getDefaultPopulators(World world) {
            return populators;
        }
     
    }
     
    Code (Text):
    [17:22:10 ERROR]: Encountered an unexpected exception
    net.minecraft.server.v1_9_R2.ReportedException: Exception generating new chunk
            at net.minecraft.server.v1_9_R2.WorldServer.a(WorldServer.java:904) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.MinecraftServer.a(MinecraftServer.java:276) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.DedicatedServer.init(DedicatedServer.java:268) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.MinecraftServer.run(MinecraftServer.java:532) [spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_77]
    Caused by: java.lang.ArrayIndexOutOfBoundsException: 265
            at org.bukkit.craftbukkit.v1_9_R2.generator.CustomChunkGenerator$CustomBiomeGrid.getBiome(CustomChunkGenerator.java:24) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at me.spedwards.deathgames.terrain.DeathGamesGenerator.generateChunkData(DeathGamesGenerator.java:25) ~[?:?]
            at org.bukkit.craftbukkit.v1_9_R2.generator.CustomChunkGenerator.getOrCreateChunk(CustomChunkGenerator.java:52) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.originalGetChunkAt(ChunkProviderServer.java:152) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:131) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:111) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:107) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.CraftWorld.loadChunk(CraftWorld.java:278) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.CraftWorld.loadChunk(CraftWorld.java:153) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.CraftWorld.getHighestBlockYAt(CraftWorld.java:102) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.generator.ChunkGenerator.canSpawn(ChunkGenerator.java:270) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.WorldServer.canSpawn(WorldServer.java:199) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.WorldServer.b(WorldServer.java:967) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.WorldServer.a(WorldServer.java:889) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            ... 4 more
    [17:22:10 ERROR]:       Cause of unexpected exception was
    java.lang.ArrayIndexOutOfBoundsException: 265
            at org.bukkit.craftbukkit.v1_9_R2.generator.CustomChunkGenerator$CustomBiomeGrid.getBiome(CustomChunkGenerator.java:24) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at me.spedwards.deathgames.terrain.DeathGamesGenerator.generateChunkData(DeathGamesGenerator.java:25) ~[?:?]
            at org.bukkit.craftbukkit.v1_9_R2.generator.CustomChunkGenerator.getOrCreateChunk(CustomChunkGenerator.java:52) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.originalGetChunkAt(ChunkProviderServer.java:152) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:131) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:111) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:107) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.CraftWorld.loadChunk(CraftWorld.java:278) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.CraftWorld.loadChunk(CraftWorld.java:153) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.CraftWorld.getHighestBlockYAt(CraftWorld.java:102) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.generator.ChunkGenerator.canSpawn(ChunkGenerator.java:270) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.WorldServer.canSpawn(WorldServer.java:199) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.WorldServer.b(WorldServer.java:967) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.WorldServer.a(WorldServer.java:889) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.MinecraftServer.a(MinecraftServer.java:276) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.DedicatedServer.init(DedicatedServer.java:268) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.MinecraftServer.run(MinecraftServer.java:532) [spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_77]
     
     
  2. I guess what I'm confused at, is that in the docs, it says the x and y ints passed through to generateChunkData are the X/Y-coordinate of the chunk. How can this be greater than 15, or does it mean the chunk coordinates?
     
  3. https://hub.spigotmc.org/javadocs/spigot/org/bukkit/generator/ChunkGenerator.html#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)

    Parameters:
    world - The world this chunk will be used for
    random - The random generator to use
    x - The X-coordinate of the chunk. This is the X coordinate of the chunk in the world
    z - The Z-coordinate of the chunk. This is the Z coordinate of the chunk in the world
    biome - Proposed biome values for chunk - can be updated by generator. This is a BiomeGrid which is essentially a 16x16 Map containing a biome type for each X/Z coordinate in this single chunk (the chunk is specified by the X/Z parameters just before it).

    You are mixing the X/Z coordinates from the world to be the X/Z entry of the BiomeGrid.

    Take this imagery for example. Here are some chunks in a world:

    [​IMG]

    They are colored for biome types. This represents an entire chunk as a one biome.

    [​IMG]

    See the lines? Those lines represent the actual wanted level of the biome borders. Notice how the chunks are very coarse and make rough sharp edges for the biomes. This would be ugly in game, so you get better control over biome on a block level inside each chunk. Thats the the BiomeGrid is. The 16x16 area inside the chunk each entry is its own biome.

    BiomeGrids give much smoother biome border results:

    [​IMG]
     
    #4 BillyGalbreath, Jun 17, 2016
    Last edited: Jun 17, 2016
    • Informative Informative x 1
  4. Thanks, this was helpful. One thing though, would I have to divide the x and z values by 16 (or rather 15), or is there a better method? I was looking through as much of the source code for Bukkit and I couldn't find anything that would suggest an easier method.
     
  5. If you're talking about trying to convert from World Block coordinates (3214, 67, 1345) to World Chunk coordinates (200, 84) then you can just use bit shifting ( << and >> ).

    Since integers are 16 bits and chunks are 16 blocks, you can easily do math on them with bit shifting.

    Code (Text):

    int chunkX = 3214 >> 4; // new value is 200
    int chunkZ = 1345 >> 4; // new value is 84
     
    Code (Text):

    int blockX = 200 << 4; // new value is 3200
    int blockZ = 84 << 4; // new value is 1344
     
     
    • Like Like x 1
  6. So this was helpful, right up until now. It just randomly stopped working, and I didn't touch anything. Any ideas?

    Method:
    Code (Text):
    @Override
        public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) {
            List<Biome> blacklist = Arrays.asList(Biome.BEACHES, Biome.COLD_BEACH, Biome.FROZEN_OCEAN, Biome.HELL, Biome.MUSHROOM_ISLAND, Biome.MUSHROOM_ISLAND_SHORE, Biome.OCEAN, Biome.SKY, Biome.STONE_BEACH, Biome.VOID);
           
            Util.log("X: " + x);
            Util.log("Z: " + z);
           
            x = Math.abs(x >> 4);
            z = Math.abs(z >> 4);
           
            Util.log("X: " + x);
            Util.log("Z: " + z);
           
            if (blacklist.contains(biome.getBiome(x, z))) {
                biome.setBiome(x, z, Biome.PLAINS);
            }
           
            return createChunkData(world);
        }
    Error:
    Code (Text):
    [04:32:51 INFO]: X: -400
    [04:32:51 INFO]: Z: -400
    [04:32:51 INFO]: X: 25
    [04:32:51 INFO]: Z: 25
    [04:32:51 WARN]: [DeathGames] Task #25 for DeathGames v1.0.0 generated an exception
    net.minecraft.server.v1_9_R2.ReportedException: Exception generating new chunk
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.originalGetChunkAt(ChunkProviderServer.java:160) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:131) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:111) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.getChunkAt(ChunkProviderServer.java:107) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.CraftWorld.loadChunk(CraftWorld.java:278) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at me.spedwards.deathgames.GameUtil.loadChunks(GameUtil.java:65) ~[?:?]
            at me.spedwards.deathgames.GameManager$1.run(GameManager.java:50) ~[?:?]
            at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftTask.run(CraftTask.java:71) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at org.bukkit.craftbukkit.v1_9_R2.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:350) [spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.MinecraftServer.D(MinecraftServer.java:734) [spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.DedicatedServer.D(DedicatedServer.java:399) [spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.MinecraftServer.C(MinecraftServer.java:665) [spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.MinecraftServer.run(MinecraftServer.java:564) [spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_77]
    Caused by: java.lang.ArrayIndexOutOfBoundsException: 409
            at org.bukkit.craftbukkit.v1_9_R2.generator.CustomChunkGenerator$CustomBiomeGrid.getBiome(CustomChunkGenerator.java:24) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at me.spedwards.deathgames.terrain.DeathGamesGenerator.generateChunkData(DeathGamesGenerator.java:36) ~[?:?]
            at org.bukkit.craftbukkit.v1_9_R2.generator.CustomChunkGenerator.getOrCreateChunk(CustomChunkGenerator.java:52) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            at net.minecraft.server.v1_9_R2.ChunkProviderServer.originalGetChunkAt(ChunkProviderServer.java:152) ~[spigot-1.9.4-R0.1-SNAPSHOT.jar:git-Spigot-8a048fe-106ced0]
            ... 13 more
     
  7. Think I figured it out... I believe I was doing it wrong to begin with. I've included the method below for anyone curious.

    Code (Text):
    @Override
    public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) {
        List<Biome> blacklist = Arrays.asList(Biome.BEACHES, Biome.COLD_BEACH, Biome.FROZEN_OCEAN, Biome.HELL, Biome.MUSHROOM_ISLAND, Biome.MUSHROOM_ISLAND_SHORE, Biome.OCEAN, Biome.SKY, Biome.STONE_BEACH, Biome.VOID);
     
        for (int X = 0; X < 16; X++) {
            for (int Z = 0; Z < 16; Z++) {
                if (blacklist.contains(biome.getBiome(X, Z))) {
                    biome.setBiome(X, Z, Biome.PLAINS);
                }
            }
        }
     
        return createChunkData(world);
    }
    Now I just have to solve this problem.
     
    • Like Like x 1