public LayeredBiomeGenerator(LocalWorld world) {
    super(world);

    Layer[] layers = initLayers();

    if (world.getConfigs().getWorldConfig().improvedRivers)
      defaultOutputType = OutputType.WITHOUT_RIVERS;

    this.unZoomedLayer = layers[0];
    this.biomeLayer = layers[1];
  }
  @SubscribeEvent
  public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
    // Server-side - called whenever a player logs in
    // I couldn't find a way to detect if the client has TerrainControl,
    // so for now the configs are sent anyway.

    // Get the config
    if (!(event.player instanceof EntityPlayerMP)) {
      return;
    }

    EntityPlayerMP player = (EntityPlayerMP) event.player;

    LocalWorld worldTC = worldLoader.getWorld(player.getEntityWorld());
    if (worldTC == null) {
      // World not loaded
      return;
    }
    ConfigProvider configs = worldTC.getConfigs();

    // Serialize it
    ByteBuf nettyBuffer = Unpooled.buffer();
    PacketBuffer mojangBuffer = new PacketBuffer(nettyBuffer);

    DataOutput stream = new ByteBufOutputStream(nettyBuffer);
    try {
      stream.writeInt(PluginStandardValues.ProtocolVersion);
      ConfigToNetworkSender.send(configs, stream);
    } catch (IOException e) {
      TerrainControl.printStackTrace(LogMarker.FATAL, e);
    }

    // Make the packet
    SPacketCustomPayload packet =
        new SPacketCustomPayload(PluginStandardValues.ChannelName, mojangBuffer);

    // Send the packet
    player.connection.sendPacket(packet);
  }
  @Override
  protected void spawnInChunk(
      LocalWorld world, Random random, boolean villageInChunk, ChunkCoordinate chunkCoord) {
    // Find all structures that reach this chunk, and spawn them
    int searchRadius = world.getConfigs().getWorldConfig().maximumCustomStructureRadius;

    int currentChunkX = chunkCoord.getChunkX();
    int currentChunkZ = chunkCoord.getChunkZ();
    for (int searchChunkX = currentChunkX - searchRadius;
        searchChunkX < currentChunkX + searchRadius;
        searchChunkX++) {
      for (int searchChunkZ = currentChunkZ - searchRadius;
          searchChunkZ < currentChunkZ + searchRadius;
          searchChunkZ++) {
        CustomObjectStructure structureStart =
            world.getStructureCache().getStructureStart(searchChunkX, searchChunkZ);
        if (structureStart != null) {
          structureStart.spawnForChunk(chunkCoord);
        }
      }
    }
  }