private void processBiomeChanges(NetData.NetMessage message) {
   for (NetData.BiomeChangeMessage biomeChange : message.getBiomeChangeList()) {
     logger.debug(
         "Received block change to {}", blockManager.getBlock((short) biomeChange.getNewBiome()));
     // TODO: Store changes to blocks that aren't ready to be modified (the surrounding chunks
     // aren't available)
     WorldProvider worldProvider = CoreRegistry.get(WorldProvider.class);
     Vector3i pos = NetMessageUtil.convert(biomeChange.getPos());
     if (worldProvider.isBlockRelevant(pos)) {
       Biome newBiome = biomeManager.getBiomeByShortId((short) biomeChange.getNewBiome());
       worldProvider.setBiome(pos, newBiome);
     } else {
       awaitingChunkReadyBiomeUpdates.put(ChunkMath.calcChunkPos(pos), biomeChange);
     }
   }
 }
  @Override
  public void onChunkReady(Vector3i chunkPos) {
    WorldProvider worldProvider = CoreRegistry.get(WorldProvider.class);

    List<NetData.BlockChangeMessage> updateBlockMessages =
        awaitingChunkReadyBlockUpdates.removeAll(chunkPos);
    for (NetData.BlockChangeMessage message : updateBlockMessages) {
      Vector3i pos = NetMessageUtil.convert(message.getPos());
      Block newBlock = blockManager.getBlock((short) message.getNewBlock());
      worldProvider.setBlock(pos, newBlock);
    }

    List<NetData.BiomeChangeMessage> updateBiomeMessages =
        awaitingChunkReadyBiomeUpdates.removeAll(chunkPos);
    for (NetData.BiomeChangeMessage message : updateBiomeMessages) {
      Vector3i pos = NetMessageUtil.convert(message.getPos());
      Biome newBiome = biomeManager.getBiomeByShortId((short) message.getNewBiome());
      worldProvider.setBiome(pos, newBiome);
    }
  }