void GenerateFreshMap()
    {
        vertexHeightmap = HeightmapGenerator.GenerateHeightmap(mapSize);
        GenerateTerrain();

        // saving the map
        MapEncoder.instance.SetHeightMap(vertexHeightmap);
        MapEncoder.instance.SaveMapToFile();
    }
        public TerrainData Generate()
        {
            CreateMeshComponents();

            var numTilesPerLine = Mathf.CeilToInt(worldSize);
            var min             = centralize ? -numTilesPerLine / 2f : 0;
            var map             = HeightmapGenerator.GenerateHeightmap(terrainNoise, numTilesPerLine);

            var vertices  = biomes.Select(_ => new List <Vector3>()).ToArray();
            var triangles = biomes.Select(_ => new List <int>()).ToArray();

            var terrainData = new TerrainData(numTilesPerLine);
            var colors      = biomes.Select(_ => new List <Color>()).ToArray();

            for (var y = 0; y < numTilesPerLine; y++)
            {
                for (var x = 0; x < numTilesPerLine; x++)
                {
                    var biomeAndStep = GetBiomeInfo(map[x, y]);
                    var biomeIndex   = (int)biomeAndStep.x;
                    var biome        = biomes[biomeIndex];
                    terrainData.BiomeIndices[x, y] = biomeIndex;
                    terrainData.BiomesStep[x, y]   = biomeAndStep.y;
                    terrainData.Depths[x, y]       = biomeIndex > 0 ? Mathf.Lerp(biomes[biomeIndex - 1].maxTerrainHeight, biome.maxTerrainHeight, biomeAndStep.y) : 0f;
                }
            }

            // Bridge gaps between water and land tiles, and also fill in sides of map
            for (var y = 0; y < numTilesPerLine; y++)
            {
                for (var x = 0; x < numTilesPerLine; x++)
                {
                    var biomeIndex = terrainData.BiomeIndices[x, y];
                    var biome      = biomes[biomeIndex];
                    var step       = terrainData.BiomesStep[x, y];
                    var color      = Color.Lerp(biome.startColor, biome.endColor, step);
                    var height     = terrainData.Depths[x, y];

                    var vertexCount = vertices[biomeIndex].Count;

                    var topRight    = new Vector3(min + x - 0.5f, GetCornerHeight(terrainData, x, y, -1, -1), min + y - 0.5f);
                    var topLeft     = new Vector3(min + x + 0.5f, GetCornerHeight(terrainData, x, y, 1, -1), min + y - 0.5f);
                    var bottomRight = new Vector3(min + x - 0.5f, GetCornerHeight(terrainData, x, y, -1, 1), min + y + 0.5f);
                    var bottomLeft  = new Vector3(min + x + 0.5f, GetCornerHeight(terrainData, x, y, 1, 1), min + y + 0.5f);

                    vertices[biomeIndex].AddRange(new[]
                    {
                        topLeft,
                        topRight,
                        bottomRight,
                        bottomLeft
                    });
                    colors[biomeIndex].AddRange(new[]
                    {
                        color,
                        color,
                        color,
                        color
                    });
                    triangles[biomeIndex].AddRange(new[]
                    {
                        vertexCount + 0, vertexCount + 1, vertexCount + 2,
                        vertexCount + 0, vertexCount + 2, vertexCount + 3,
                    });
                }
            }


            for (var biomeIndex = 0; biomeIndex < biomes.Length; biomeIndex++)
            {
                var mesh = _meshes[biomeIndex];
                mesh.SetVertices(vertices[biomeIndex]);
                mesh.SetTriangles(triangles[biomeIndex], 0, true);
                mesh.SetColors(colors[biomeIndex]);
                mesh.Optimize();
                mesh.RecalculateNormals();
                mesh.RecalculateTangents();
                mesh.RecalculateBounds();

                _meshRenderers[biomeIndex].sharedMaterial = biomes[biomeIndex].material;
            }

            return(terrainData);
        }