private HeightMap CreateHeightMap(GameStartupSettings settings)
        {
            HeightMap heightmap = new HeightMap(256, HeightMap.Overlap / 2, HeightMap.Overlap / 2);

            heightmap.MakeFlat(0.1f);
            heightmap.SetNoise(0.22f); // 0.3 makes smaller structure, 0.1 makes blobs
            heightmap.Erode(10);
            heightmap.Smoothen();
            //heightmap.Smoothen();

            return heightmap;
        }
        public void Create(GameStartupSettings settings)
        {
            Random rnd = new Random();

            log.DebugFormat("Create( {0} )", settings);
            HeightMap heightmap = CreateHeightMap(settings);

            float seaLevel = heightmap.FindHeightLevel(settings.OceanRatio * 1.5f, 0.05f); // <-- Values from settings
            float shoreLevel = heightmap.FindHeightLevel(settings.OceanRatio, 0.05f); // <-- Values from settings
            float hillLevel = heightmap.FindHeightLevel(0.1f, 0.01f); // <-- Values from settings
            float mountainLevel = heightmap.FindHeightLevel(settings.PeakRatio, 0.01f); // <-- Values from settings

            OnProgress(new ProgressNotificationEventArgs(string.Format("Min: {0}, Sea: {1}, shoreLevel: {2}, mountain: {3}, max: {4}", heightmap.Minimum, seaLevel, shoreLevel, mountainLevel, heightmap.Maximum), 1f, 0.1f));

            Init(settings.Width, settings.Height);

            // assign coords
            for (int i = 0; i < settings.Width; ++i)
            {
                for (int j = 0; j < settings.Height; ++j)
                {
                    this[i, j].Height = heightmap[i, j];
                }
            }

            Terrain ocean = Provider.Instance.Terrains["Ocean"];
            Terrain shore = Provider.Instance.Terrains["Shore"]; // Shore
            Terrain coast = Provider.Instance.Terrains["Coast"];
            Terrain grassland = Provider.Instance.Terrains["Grassland"];

            Feature hills = Provider.Instance.Features["Hills"];
            Feature mountains = Provider.Instance.Features["Mountains"];

            // settle ground plains (ocean, grassland, mountain)
            RangeConversion<float, Terrain> conv = new RangeConversion<float, Terrain>(grassland);

            conv.AddMapping(heightmap.Minimum, seaLevel, ocean);
            conv.AddMapping(seaLevel, shoreLevel, shore);
            conv.AddMapping(shoreLevel, hillLevel, grassland);
            //conv.AddMapping(hillLevel, mountainLevel, hill);
            //conv.AddMapping(mountainLevel, heightmap.Maximum, mountain);

            for (int i = 0; i < settings.Width; ++i)
            {
                for (int j = 0; j < settings.Height; ++j)
                {
                    this[i, j].Terrain = conv.Find(heightmap[i, j]);

                    if(hillLevel <= heightmap[i,j] && heightmap[i,j] < mountainLevel)
                        this[i, j].Features.Add(hills);
                    else if(mountainLevel <= heightmap[i,j])
                        this[i, j].Features.Add(mountains);
                }
            }

            OnProgress(new ProgressNotificationEventArgs("Basic Terrain Assignment", 1f, 0.2f));

            // find coasts
            for (int i = 0; i < settings.Width; ++i)
            {
                for (int j = 0; j < settings.Height; ++j)
                {
                    if (this[i, j].IsOcean)
                    {
                        if (ShouldBeCoast(i, j))
                            this[i, j].Terrain = coast;
                    }
                }
            }

            OnProgress(new ProgressNotificationEventArgs("Find Coasts: " + GetArea(a => a.IsOcean).Count + " ocean tiles, " + GetArea(a => a.IsLand).Count + " land tiles", 1f, 0.3f));

            // find river tiles
            List<MapCell> hillsOrMountains = GetArea(a => a.IsSpring);

            int currentRiverId = 0;

            int numOfRivers = Math.Min(hillsOrMountains.Count, settings.NumOfRivers);
            Array corners = Enum.GetValues(typeof(HexCorner));
            while( currentRiverId < numOfRivers)
            {
                MapCell spring = hillsOrMountains.PickRandom();

                HexCorner randomCorner = (HexCorner)corners.GetValue(rnd.Next(corners.Length));

                HexPointCorner hxc = new HexPointCorner { Corner = randomCorner, Point = spring.Point };
                HexPointFlow[] flows = GetFlowByCorner(hxc);

                River currentriver = new River(string.Format("River{0}", currentRiverId));
                Rivers.Add(currentriver);
                DoRiver(flows[rnd.Next(3)], hxc, currentriver, 0);

                currentRiverId++;
            }

            OnProgress(new ProgressNotificationEventArgs("Add Rivers: " + GetArea(a => a.IsRiver).Count + " tiles", 1f, 0.3f));
        }