public void Serialize(DataOutputStream stream) throws IOException {
    stream.writeInt(TCDefaultValues.ProtocolVersion.intValue());

    WriteStringToStream(stream, this.WorldName);

    stream.writeInt(this.GenerationDepth);
    stream.writeInt(this.BiomeRarityScale);
    stream.writeInt(this.LandRarity);
    stream.writeInt(this.LandSize);
    stream.writeInt(this.LandFuzzy);
    stream.writeInt(this.IceRarity);
    stream.writeInt(this.IceSize);
    stream.writeBoolean(this.FrozenOcean);
    stream.writeBoolean(this.FrozenRivers);
    stream.writeInt(this.RiverRarity);
    stream.writeInt(this.RiverSize);
    stream.writeBoolean(this.RiversEnabled);

    stream.writeDouble(this.oldBiomeSize);

    stream.writeFloat(this.minTemperature);
    stream.writeFloat(this.maxTemperature);
    stream.writeFloat(this.minMoisture);
    stream.writeFloat(this.maxMoisture);

    stream.writeInt(this.WorldFog);
    stream.writeInt(this.WorldNightFog);

    stream.writeInt(this.CustomBiomes.size());
    for (String name : this.CustomBiomes) {
      WriteStringToStream(stream, name);
      stream.writeInt(this.CustomBiomeIds.get(name));
    }

    stream.writeInt(this.biomes.size());
    for (BiomeConfig config : this.biomes) {
      stream.writeInt(config.Biome.getId());
      config.Serialize(stream);
    }

    stream.writeInt(this.NormalBiomes.size());
    for (String biome : this.NormalBiomes) WriteStringToStream(stream, biome);

    stream.writeInt(this.IceBiomes.size());
    for (String biome : this.IceBiomes) WriteStringToStream(stream, biome);

    stream.writeInt(this.IsleBiomes.size());
    for (String biome : this.IsleBiomes) WriteStringToStream(stream, biome);

    stream.writeInt(this.BorderBiomes.size());
    for (String biome : this.BorderBiomes) WriteStringToStream(stream, biome);
  }
  public void Serialize(DataOutputStream stream) throws IOException {
    // General information
    writeStringToStream(stream, this.WorldName);

    stream.writeInt(this.WorldFog);
    stream.writeInt(this.WorldNightFog);

    // Custom biomes + ids
    stream.writeInt(this.CustomBiomes.size());
    for (String name : this.CustomBiomes) {
      writeStringToStream(stream, name);
      stream.writeInt(this.CustomBiomeIds.get(name));
    }

    // BiomeConfigs
    stream.writeInt(this.biomesCount);
    for (BiomeConfig config : biomeConfigs) {
      if (config == null) continue;
      stream.writeInt(config.Biome.getId());
      config.Serialize(stream);
    }
  }
  public WorldConfig(File settingsDir, LocalWorld world, boolean checkOnly) {
    this.SettingsDir = settingsDir;
    this.WorldName = world.getName();

    File settingsFile = new File(this.SettingsDir, TCDefaultValues.WorldSettingsName.stringValue());

    this.ReadSettingsFile(settingsFile);
    this.RenameOldSettings();
    this.ReadConfigSettings();

    this.CorrectSettings();

    ReadWorldCustomObjects();

    // Check biome ids

    for (String biomeName : CustomBiomes)
      if (CustomBiomeIds.get(biomeName) == -1)
        CustomBiomeIds.put(biomeName, world.getFreeBiomeId());

    // Need add check to clashes
    if (this.SettingsMode != ConfigMode.WriteDisable)
      this.WriteSettingsFile(settingsFile, (this.SettingsMode == ConfigMode.WriteAll));

    world.setHeightBits(this.worldHeightBits);

    File BiomeFolder =
        new File(SettingsDir, TCDefaultValues.WorldBiomeConfigDirectoryName.stringValue());
    if (!BiomeFolder.exists()) {
      if (!BiomeFolder.mkdir()) {
        System.out.println(
            "TerrainControl: error create biome configs directory, working with defaults");
        return;
      }
    }

    ArrayList<LocalBiome> localBiomes = new ArrayList<LocalBiome>(world.getDefaultBiomes());

    // Add custom biomes to world
    for (String biomeName : this.CustomBiomes) {
      if (checkOnly) localBiomes.add(world.getNullBiome(biomeName));
      else localBiomes.add(world.AddBiome(biomeName, this.CustomBiomeIds.get(biomeName)));
    }

    // Build biome replace matrix
    for (int i = 0; i < this.ReplaceMatrixBiomes.length; i++)
      this.ReplaceMatrixBiomes[i] = (byte) i;

    this.biomeConfigs = new BiomeConfig[world.getMaxBiomesCount()];

    String LoadedBiomeNames = "";

    for (LocalBiome localBiome : localBiomes) {
      BiomeConfig config = new BiomeConfig(BiomeFolder, localBiome, this);
      if (checkOnly) continue;

      if (!config.ReplaceBiomeName.equals("")) {
        this.HaveBiomeReplace = true;
        this.ReplaceMatrixBiomes[config.Biome.getId()] =
            (byte) world.getBiomeIdByName(config.ReplaceBiomeName);
      }

      if (this.NormalBiomes.contains(config.Name)) this.normalBiomesRarity += config.BiomeRarity;
      if (this.IceBiomes.contains(config.Name)) this.iceBiomesRarity += config.BiomeRarity;

      this.biomeConfigs[localBiome.getId()] = config;
      if (!this.BiomeConfigsHaveReplacement)
        this.BiomeConfigsHaveReplacement = config.ReplaceCount > 0;
      if (this.biomes.size() != 0) LoadedBiomeNames += ", ";
      LoadedBiomeNames += localBiome.getName();
      this.biomes.add(config);

      if (this.ModeBiome == BiomeMode.FromImage) {
        if (this.biomeColorMap == null) this.biomeColorMap = new HashMap<Integer, Integer>();

        try {
          int color = Integer.decode(config.BiomeColor);
          if (color <= 0xFFFFFF) this.biomeColorMap.put(color, config.Biome.getId());
        } catch (NumberFormatException ex) {
          System.out.println("TerrainControl: wrong color in " + config.Biome.getName());
        }
      }
    }

    System.out.println("TerrainControl: Loaded biomes - " + LoadedBiomeNames);
  }