Skip to content

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 CusomBiome block replacements.
  • When you want to show unique biome for different players in the same area.

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.

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.

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.

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();
}
}