The PacketHandler
The PacketHandler is the second of two biome renderer BiomesAPI provides for developers.
Unlike the BiomeSetter, the PacketHandler does not support gameplay changes because it simply modifies biome data directly through packets.
When you should use the PacketHandler:
- You don’t want to modify the world in any way and only want to modify visual elements of biomes.
- When you want to use
CusomBiomeblock replacements. - When you want to show unique biome for different players in the same area.
Packet Manipulator Required!
Section titled “Packet Manipulator Required!”To use the PacketHandler, your plugin must depend on ProtocolLib or PacketEvents (or softdepend both).
Picking which manipulator to use entirely depends on your setup.
If you plan on dynamically adding, removing, or changing biomes, you should probably use ProtocolLib because PacketEvents caches the biome registry by default.
This can be changed with the force-per-user-registries JVM flag.
PacketEvents Caching Registries
Section titled “PacketEvents Caching Registries”By default, PacketEvents will cache player registries.
This means that when the Minecraft Registry is modified AFTER the server finishes starting up, PacketEvents will stop syncing up with the built-in Minecraft registries.
This behavior can only be changed by adding the -Dpacketevents.force-per-user-registries=true in your JVM arguments.
This is not ideal for public plugins that want as little setup as possible, so if you are registering biomes OUTSIDE of your onLoad() or onEnable() (or modifying them later in the lifecycle!), you should use ProtocolLib.
PhonyCustomBiome
Section titled “PhonyCustomBiome”PhoneyCustomBiomes are a component of BiomesAPI and required for using the PacketHandler interface. You must convert your CustomBiome to a PhonyCustomBiome before appending it to the PacketHandler.
Examples
Section titled “Examples”The PacketHandler is incredibly flexible and straightforward to use.
public final class ExamplePlugin extends JavaPlugin {
private PacketHandler packetHandler;
@Override public void onLoad() { // PROTOCOLLIB, or PACKETEVENTS packetHandler = PacketHandler.of(this, PacketHandler.Manipulator.PROTOCOLLIB); packetHandler.register(); // Register listeners }
@Override public void onEnable() { // Create a basic biome. Your namespace and key should be unique. CustomBiome biome = CustomBiome.builder() .resourceKey(BiomeResourceKey.of("test", "custombiome")) .settings(BiomeSettings.defaultSettings()) .fogColor("#FFFFFF") .foliageColor("#F5F2EB") .skyColor("#000000") .waterColor("#F5F2EB") .waterFogColor("#000000") .grassColor("#9D00FF") .particleRenderer(ParticleRenderer.of(AmbientParticle.WITCH, 0.01f)) .blockReplacements( BlockReplacement.of(Material.BIRCH_LEAVES, Material.ACACIA_LEAVES), ) .build();
// Register your biome to finalize it and send it to Minecraft's internal registry. biome.register();
// Create a PhonyCustomBiome PhonyCustomBiome phonyBiome = PhoneyCustomBiome.builder() .setCustomBiome(biome) .setConditional((player, chunkLocation) -> { // In the conditional, you can define what situations you want your biome to be shown. // For this example, let's make our biome only show in a specific world: return player.getWorld().getName().equals("world"); }) .build();
// Add to the PacketHandler packetHandler.appendBiome(phonyBiome); }
@Override public void onDisable() { // This isn't necessary, but it's good practice to remove your listeners! packetHandler.unregister(); }
}class ExamplePlugin : JavaPlugin() {
private lateinit var packetHandler: PacketHandler
override fun onLoad() { // PROTOCOLLIB, or PACKETEVENTS packetHandler = PacketHandler.of(this, PacketHandler.Manipulator.PROTOCOLLIB) packetHandler.register() // Register listeners }
override fun onEnable() { // Create a basic biome. Your namespace and key should be unique. val biome = CustomBiome.builder() .resourceKey(BiomeResourceKey.of("test", "custombiome")) .settings(BiomeSettings.defaultSettings()) .fogColor("#FFFFFF") .foliageColor("#F5F2EB") .skyColor("#000000") .waterColor("#F5F2EB") .waterFogColor("#000000") .grassColor("#9D00FF") .particleRenderer(ParticleRenderer.of(AmbientParticle.WITCH, 0.01f)) .blockReplacements( BlockReplacement.of(Material.BIRCH_LEAVES, Material.ACACIA_LEAVES), ) .build()
// Register your biome to finalize it and send it to Minecraft's internal registry. biome.register()
// Create a PhonyCustomBiome val phonyBiome = PhoneyCustomBiome.builder() .setCustomBiome(biome) .setConditional { player, chunkLocation -> // In the conditional, you can define what situations you want your biome to be shown. // For this example, let's make our biome only show in a specific world: player.world.name == "world" } .build()
// Add to the PacketHandler packetHandler.appendBiome(phonyBiome) }
override fun onDisable() { // This isn't necessary, but it's good practice to remove your listeners! packetHandler.unregister() }}