public float GetTerrainHeight(float x, float y, Island island)
    {
        //simple height  generation (only one noise pass)
        PerIslandGeneratorProperties properties = (PerIslandGeneratorProperties)island.GeneratorProperties;

        float height = IslandNoise.GetPerlin(x * TerrainNoiseScale, y * TerrainNoiseScale) + properties.noiseOffset;

        height *= TerrainAmp;

        //circular, square masks (to achieve island looking terrain)
        float distance_x = Mathf.Abs(x - island.Size * 0.5f);
        float distance_y = Mathf.Abs(y - island.Size * 0.5f);

        float distance = 0f;

        if (properties.circleShaped)
        {
            distance = Mathf.Sqrt(distance_x * distance_x + distance_y * distance_y);             // circular mask
        }
        else
        {
            distance = Mathf.Max(distance_x, distance_y);             // square mask
        }

        float max_width = island.Size * 0.5f - 10.0f;
        float delta     = distance / max_width;
        float gradient  = delta * delta;

        height *= Mathf.Max(0.0f, 1.0f - gradient);

        return(height);
    }
    public void SetupIslandForGeneration(Island island)
    {
        //always use random with static unique per island seed so engine will generate always same island in given position
        random = new Random(GetPerIslandSeed(island));

        //height generation properties
        PerIslandGeneratorProperties properties = new PerIslandGeneratorProperties();

        island.GeneratorProperties = properties;

        properties.islandSize   = (int)random.Range(300, 1000);
        properties.noiseOffset  = random.Range(.4f, 1f);
        properties.circleShaped = random.Bool();

        //mesh generation properties
        island.Size             = properties.islandSize;
        island.minPointRadius   = 6;
        island.trianglesInChunk = 1500;
    }