Skip to content

Sending Biomes via Packets

A PhonyCustomBiome is a wrapper for CustomBiomes that is required for using the PacketHandler interface.

  • setConditional: Set a condition for when this biome should be shown to a player. This is useful for showing different biomes to different players in the same area.
  • setBiomeCondition: Superset of setConditional, this condition also takes in the biome that is being rendered, allowing you to show different biomes based on the original biome of the chunk.
  • setPriority: Set the priority of this phony biome. This is useful for when you have multiple phony biomes that could be shown in the same area and want to control which one is shown. Biomes with higher priority will be chosen over biomes with lower priority. The default priority is NORMAL.
ExamplePlugin.java Java
import me.outspending.biomesapi.biome.CustomBiome;
import me.outspending.biomesapi.registry.ResourceKey;
import me.outspending.biomesapi.renderer.packet.PacketHandler;
import me.outspending.biomesapi.renderer.packet.data.PhonyCustomBiome;
import me.outspending.biomesapi.wrapper.BiomeSettings;
import org.bukkit.Material;
import org.bukkit.plugin.java.JavaPlugin;

public class ExamplePlugin extends JavaPlugin {
  @Override
  public void onEnable() {
      CustomBiome customBiome = CustomBiome.builder()
          .resourceKey(ResourceKey.of("test", "custombiome"))
          .settings(BiomeSettings.defaultSettings())
          .fogColor("#FFFFFF")
          .foliageColor("#F5F2EB")
          .skyColor("#B99DFC")
          .waterColor("#F5F2EB")
          .waterFogColor("#000000")
          // Render all grass blocks as diamond blocks
          .replace(Material.GRASS_BLOCK, Material.DIAMOND_BLOCK)
          .register();

          PhonyCustomBiome phonyCustomBiome = customBiome.asPhony()
              .setConditional(((player, chunkLocation) -> {
                  // Only show this biome to Jsinco
                  return player.getName().equals("Jsinco");
              }))
              // Set the priority of this phony biome, defaults to NORMAL
              .setPriority(PacketHandler.Priority.NORMAL)
              .build();
  }
}

The PacketHandler is a biome renderer that injects biome data directly into packets sent to players. This means that the biome change is purely visual and does not affect gameplay elements such as mob spawns and is purely visual.

  • You want to show different biomes to different players in the same area.
  • You want to use block replacements in your custom biomes.

PacketHandlers require and injector in order to inject biome data into packets. BiomesAPI supports three different injectors:

  • Netty: BiomesAPI’s built-in standalone injector that does not require any external dependencies. Works similarly to ProtocolLib.
  • ProtocolLib: Injects block replacements and custom biomes into packets using ProtocolLib injectors.
  • PacketEvents: Injects block replacements and custom biomes into packets using PacketEvents wrappers and injectors.
ExamplePlugin.java Java
import me.outspending.biomesapi.biome.CustomBiome;
import me.outspending.biomesapi.renderer.packet.PacketHandler;
import me.outspending.biomesapi.renderer.packet.data.PhonyCustomBiome;
import net.kyori.adventure.key.Key;
import org.bukkit.plugin.java.JavaPlugin;

public class ExamplePlugin extends JavaPlugin {

  private PacketHandler packetHandler;

  @Override
  public void onEnable() {
      CustomBiome customBiome = ...;
      Key plains = Key.key("minecraft:plains");

      PhonyCustomBiome phonyCustomBiome = customBiome.asPhony()
          .setBiomeCondition(((player, snapshot) -> {
              // Replace all 'plains' biomes with this custom biome
              return snapshot.centerBiome().key().equals(plains);
          }))
          .build();

      this.packetHandler = PacketHandler.of(this) // Defaults to NETTY injector
          .appendBiome(phonyCustomBiome)
          .register();
  }

  @Override
  public void onDisable() {
      this.packetHandler.unregister();
  }
}