private void createPlains(Region region)
    {
        BlockCounter counter  = new BlockCounter(Region.regionXZ * Region.regionXZ * Region.regionY);
        int          x_offset = region.getBlockOffsetX();
        int          y_offset = region.getBlockOffsetY();
        int          z_offset = region.getBlockOffsetZ();

        for (int x = 0; x < region.data.GetLength(0); x++)
        {
            for (int z = 0; z < region.data.GetLength(2); z++)
            {
                int xi = x_offset + x;
                int zi = z_offset + z;


                int highHills = PerlinNoise(xi, 751, zi, 50, 10f, 1.0f) + 128;
                int lowHills  = PerlinNoise(xi, 407, zi, 50, 10f, 1.0f) + 128;
                //int val = (int)Math.Max (highHills, lowHills);
                for (int y = 0; y < region.data.GetLength(1); y++)
                {
                    int yi = y_offset + y;
                    if (yi <= highHills)
                    {
                        counter.add(DirtBlock.blockId);
                        region.data [x, y, z] = DirtBlock.blockId;
                    }
                    else if (yi <= lowHills)
                    {
                        counter.add(GrassBlock.blockId);
                        region.data [x, y, z] = GrassBlock.blockId;
                    }
                    else
                    {
                        counter.add(0);
                    }
                }
            }
        }

        //process flags
        if (counter.isAirOnly())
        {
            region.flags.isEmptyAir = true;
        }
        else if (counter.isSingleSolidOnly())
        {
            region.flags.isSingleSolid = true;
        }
    }
    private void createMountains(Region region)
    {
        BlockCounter counter  = new BlockCounter(Region.regionXZ * Region.regionXZ * Region.regionY);
        int          x_offset = region.getBlockOffsetX();
        int          y_offset = region.getBlockOffsetY();
        int          z_offset = region.getBlockOffsetZ();

        for (int x = 0; x < Region.regionXZ; x++)
        {
            for (int z = 0; z < Region.regionXZ; z++)
            {
                int xi = x_offset + x;
                int zi = z_offset + z;


                int stone      = PerlinNoise(xi, 751, zi, 550, 15f, 2.2f) + 200;
                int lowHills   = PerlinNoise(xi, 400, zi, 200, 10f, 2.2f);
                int roughness1 = PerlinNoise(xi, 231, zi, 20, 2f, 1.5f);
                int roughness2 = PerlinNoise(xi, 845, zi, 50, 2f, 2.5f);
                int roughness3 = PerlinNoise(xi, 19, zi, 100, 3f, 3.5f);
                int val        = stone + lowHills + roughness1 + roughness2 + roughness3;
                for (int y = 0; y < Region.regionY; y++)
                {
                    int yi = y_offset + y;
                    if (yi <= val)
                    {
                        region.data [x, y, z] = 1;
                        counter.add(1);
                    }
                    else
                    {
                        counter.add(0);
                    }
                }
            }
        }

        //process flags
        if (counter.isAirOnly())
        {
            region.flags.isEmptyAir = true;
        }
        else if (counter.isSingleSolidOnly())
        {
            region.flags.isSingleSolid = true;
        }
    }