Chunk Generation and Biomes

Discussion in 'Plugin Development' started by tustin2121, Jul 21, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    tustin2121

    There doesn't seem to be a way in the ChunkGenerator and BlockPopulator methods to set a chunk or block's biome. Does anyone know how I can go about setting the biomes for generated chunks?

    I've looked at some other people's code for their plugins and found them to be using some WorldChunkManager class that is not part of bukkit, and it uses an (obfuscated) "a" function. Can anyone shed some light upon this and if this is the sole way to set biomes? All I want to do is make the entire world a winter biome...
     
    Sayshal likes this.
  2. Offline

    bleachisback

    I've tried looking for it before, and even though I could have sworn i saw it before, there doesn't seem to be a way to set humidity, period. I think bukkit just hasn't thought of that yet.
     
  3. Offline

    tustin2121

    So, for those finding this thread later when asking the same question as me, here are my results:

    Biomes are a strange thing that the server has little control over, believe it or not. Biomes have sole control over a half-dozen things, including rainfall, grass color, ice formation, and mob spawning. Ice formation and mob spawning are controllable at the server level, because the server simply uses the Biome data to see if block updates or spawning should happen.

    Rainfall and grass color, on the other hand, are entirely client side. The client uses the world seed to do its own biome calculation for the grass and rainfall, thereby freeing up network traffic about those things and taking away a server's ability to dictate those things. So even if there was a way to set the biome in Bukkit, it would only manifest in block change and mob spawn events, and not the REAL reason we want to control biomes - the weather conditions. It would still snow where there was originally snowy biomes, rain where it originally rained, and do nothing where there were originally vast deserts, despite the changes on the server and the snow drift blocks appearing over the sand dunes.

    Furthermore, in order to dictate anything about Biomes, you must by-pass Bukkit and go straight to Craftbukkit and subsequently Minecraft itself. In order to control biomes, you must subclass the net.minecraft.server.WorldChunkManager class* and override all of its "a()" functions (which is obviously an obfuscated function name). There are three overloads of this function:
    • public BiomeBase[] a(BiomeBase[] buffer, int x, int z, int rx, int rz)
    • public double[] a(double[] buffer, int x, int z, int rx, int rz)
    • public BiomeBase a(ChunkCoordIntPair coords)
    From what others have determined (I can't take credit for these discoveries), the first function returns an array of type BiomeBase (which is similar to Bukkit's Biome class). The array is [rx * rz] long. BiomeBase is one of the constants listed in the class (FOREST, TUNDRA, etc). BiomeBase.a(double, double) is a convenience method where you can pass a normalized** double or float for temperature and rainfall (respectively) to get the corresponding Biome.

    The second function returns an array of doubles which is again [rx * rz] long. It is likely that this function returns snowfall percentages, but I can't be sure of that.

    The third function returns a single BiomeBase class for the chunk coordinates x and z (which are stored in the ChunkCoordIntPair class, just to be verbose). The others usually (indirectly) call the first function inside this method, returning the first value in the array.

    Finally, you should also override getBiome(x, z) and getBiomeData(x, z, rx, rz). The others who have done the research I'm reporting usually have the first function call the second, and the second call the first a() function (and the last a() function call getBiome()).

    Once you create the WorldChunkManager subclass, you must assign it to the world you want it to take effect on. You do that like this (likely from your onEnable() method, or even from an onWorldInit() event method):
    Code:
    CraftWorld cw = (CraftWorld) getServer().getWorld("worldname");
    cw.getHandle().worldProvider.b = new CustomChunkManager();
    
    Note that this line makes your plugin only compatible with Craftbukkit servers and not any other (theoretical) server software that uses the Bukkit architecture.

    For working examples, see some other people's github source code (like from Nightgunner5's lovely Biome Changing plugin: BiomeChunkManager). Hope this helps others.

    * You must compile against the Craftbukkit.jar in addition to the Bukkit.jar in order to get to the net.minecraft classes
    ** Normalized = between 0.0 and 1.0
     
  4. unfortunatly, the biome change plugin doesn't work anymore.
     
  5. Offline

    xpansive

    Great post, I was wondering about this too.
     
  6. Offline

    tustin2121

    UPDATE: Recent tweet by Jeb:
    This means that the Server will soon be able to dictate the biome of the place WITHOUT hacky solutions! :)
     
Thread Status:
Not open for further replies.

Share This Page