/// <summary>
    /// Generates block types with hp and hp level.
    /// Chunks and their objects (if first run = true).
    /// And calculates faces.
    /// </summary>
    public IEnumerator GenerateWorld(bool firstRun)
    {
        _stopwatch.Restart();
        ResetProgressBarVariables();

        Status = WorldGeneratorStatus.GeneratingTerrain;

        yield return(null);

        ProgressDescription = "Initialization...";
        Blocks            = new Block[Settings.WorldSizeX * ChunkSize, WorldSizeY *ChunkSize, Settings.WorldSizeZ *ChunkSize];
        AlreadyGenerated += _progressStep;

        yield return(null);

        ProgressDescription = "Calculating heights...";
        var heights = _terrainGenerator.CalculateHeights();

        AlreadyGenerated += _progressStep;

        yield return(null);

        ProgressDescription = "Generating terrain...";
        var types = _terrainGenerator.CalculateBlockTypes(heights);

        AlreadyGenerated += _progressStep;

        yield return(null);

        ProgressDescription = "Output deflattenization...";
        DeflattenizeOutput(ref types);
        AlreadyGenerated += _progressStep;

        yield return(null);

        UnityEngine.Debug.Log("WaterLevel " + Settings.WaterLevel);
        if (Settings.IsWater)
        {
            ProgressDescription = "Generating water...";
            _terrainGenerator.AddWater(ref Blocks);
        }
        AlreadyGenerated += _progressStep;

        yield return(null);

        ProgressDescription = "Generating trees...";
        _terrainGenerator.AddTrees(ref Blocks);
        AlreadyGenerated += _progressStep;

        yield return(null);

        ProgressDescription = "Creating game objects...";
        if (firstRun)
        {
            _worldScene = SceneManager.CreateScene(name);
        }

        Chunks = new Chunk[Settings.WorldSizeX, WorldSizeY, Settings.WorldSizeZ];
        CreateGameObjects(firstRun);
        AlreadyGenerated += _progressStep;

        yield return(null);

        ProgressDescription = "Calculating faces...";
        _meshGenerator.CalculateFaces(ref Blocks);
        AlreadyGenerated += _progressStep;

        yield return(null);

        ProgressDescription = "World boundaries check...";
        _meshGenerator.WorldBoundariesCheck(ref Blocks);
        AlreadyGenerated += _progressStep;

        Status = WorldGeneratorStatus.TerrainReady;

        _stopwatch.Stop();
        UnityEngine.Debug.Log($"It took {_stopwatch.ElapsedTicks / TimeSpan.TicksPerMillisecond} ms to generate all terrain.");
    }