params = {}
params.cs = 512
params.cliff = 4
params.offset = Vector3.new(0,-300,0)
params.thresh = 0.18
params.voxels = false
local p = params

exclude = {}

chunks = {}

function part(x,y,z,mat,s)
	local stone = Instance.new("Part")
	stone.Parent = game.Workspace.Generation
	stone.Transparency = 0
	stone.Material = Enum.Material.Slate
	stone.Position = Vector3.new(x,y,z)*params.s + p.offset
	stone.Size = Vector3.new(p.s,p.s,p.s)
	if s then stone.Size = s end
	stone.Anchored = true
	
	local grass = stone:Clone()
	grass.CanCollide = true
	grass.Transparency = 0
	grass.Material = Enum.Material.Grass
	grass.Color = Color3.fromRGB(255, 255, 255)
	grass.Parent = stone
	grass.Size = Vector3.new(stone.Size.X+1,20,stone.Size.Z+1)
	grass.Position = stone.Position + Vector3.new(0,stone.Size.Y/2 - grass.Size.Y/2 + 1,0)
	return stone
end
local mod = 1
local n = function(x,y,z,scale)
	return math.noise(x*scale,y*scale,z*scale)
end
local function mulv(a,b) return Vector3.new(a.x*b.x,a.y*b.y,a.z*b.z) end
local structures = _G.Storage.Structures:GetChildren()
local foliage = _G.Storage.Foliage:GetChildren()
function islandChunk(ox,oz) -- i had to think there lol
	local chunk = chunks[tostring(ox)..","..tostring(oz)]
	local cn = n(ox,.5,oz,0.05)
	if cn < 0.3 then return end
	local offset = math.abs(n(ox,124.5432,oz,0.015)*2)
	ox = ox + 20
	for oy = 0,3 do
		mod = math.clamp(math.pow(Vector2.new(ox,oz).Magnitude/6,2),0,1)
		local height = {}
		p.thresh = 0.5
		p.s = 10
		local lx = 1/8
		local ly = 1/8
		local lz = 1/8
		local values = {}
		local xi = 0
		for x=ox,ox+1,lx do
			xi = xi + 1
			table.insert(values,{})
			local yi = 0
			for y=oy,oy+1,ly do
				yi = yi + 1
				local hshift = math.abs((y/2)-1)/4
				table.insert(values[xi],{})
				local zi = 0
				for z=oz,oz+1,lz do
					zi = zi + 1
					local v = (n(x,y,z,0.05))*((n(x,y,z,0.1)+n(x,y,z,1)+n(x,y,z,0.5)))-0.2-hshift-math.abs(n(x,0.123,y,0.1))
					table.insert(values[xi][yi],v)
					if xi > 1 and yi > 1 and zi > 1 then
						local temp = values[xi]
						local a = temp[yi][zi-1] > 0
						local b = temp[yi-1][zi] > 0 
						local c = values[xi-1][yi][zi] > 0
						local d = v > 0
						if ((not(a and b and c) and d) or ((a or b or c) and not d)) and math.random(1,4) == 1 then 
							local part = _G.Storage.Stone:Clone()
							part.Position = Vector3.new(x,y+offset,z)*params.cs
							part.Size = Vector3.new(lx,ly,lz)*params.cs
							part.Parent = chunk.folder
							local m = Vector3.new(math.random(1,16)/4,math.random(1,16)/4,math.random(1,16)/4)+Vector3.new(1.2,1.2,1.2)
							part.Size = mulv(part.Size,m)
							
							local grass = _G.Storage.Grass:Clone()
							grass.Size = Vector3.new(part.Size.X+1,params.cs/math.random(5,30),part.Size.Z+1)
							grass.CFrame = part.CFrame + Vector3.new(0,part.Size.Y/2,0)
							grass.Parent = chunk.folder
						end
					end
				end
			end
		end
	end
end
function chunk(ox,oz)
	math.randomseed(ox+oz)
	local chunk = {}
	chunk.folder = Instance.new("Folder")
	chunk.folder.Name = tostring(ox)..", "..tostring(oz)
	chunk.folder.Parent = game.Workspace.Generation
	chunk.position = Vector3.new(ox,0,oz) -- ? my hands are cold again
	chunk.needed = true
	if ox%2==0 and oz%2==0 then 
		for i=18,2,-4 do
			local water = _G.Storage.Water:Clone()
			water.Size = Vector3.new(params.cs,2,params.cs)*2
			water.Position = Vector3.new(ox,0,oz)*params.cs + Vector3.new(0,i+-41.5,0)
			water.Parent = chunk.folder
		end
	end
	chunks[tostring(ox)..","..tostring(oz)] = chunk -- again abusing Lua's hashtables
	--[[islandChunk(ox,oz) -- oh lord have mercy on my clockspeed
	local cn = n(ox,.5,oz,0.05)
	if cn < 0.4 then return end
	mod = math.clamp(math.pow(Vector2.new(ox,oz).Magnitude/6,2),0,1)
	local height = {}
	local lx = 1/8
	local ly = 1/8
	local lz = 1/8
	local values = {}
	local xi = 0
	for x=ox-lx,ox+1,lx do
		xi = xi + 1
		table.insert(values,{})
		local yi = 1
		local y=-0.05
		local hshift = y/2
		table.insert(values[xi],{})
		local zi = 0
		for z=oz-lz,oz+1,lz do
			zi = zi + 1
			local v = (n(x,y,z,1)+n(x,y,z,1))*n(x,y,z,0.05)-0.5-hshift
			table.insert(values[xi][yi],v)
			if xi > 1 and zi > 1 then
				if v > 0 then
					local r = CFrame.new()--CFrame.Angles(0,math.random(-10,10)/300,0)
					local part = _G.Storage.Sand:Clone()
					part.CFrame = CFrame.new(Vector3.new(x,y,z)*params.cs)*r
					part.Size = Vector3.new(lx,ly*0.2,lz)*params.cs
					part.Parent = chunk.folder
					
					local grass = _G.Storage.Grass:Clone()
					grass.CFrame = CFrame.new(Vector3.new(x,y,z)*params.cs)*r
					grass.Size = Vector3.new(lx,ly*0.2,lz)*params.cs
					grass.Parent = chunk.folder
					
					local m = Vector3.new(math.random(1,10),math.random(1,10)/10,math.random(1,10))/5+Vector3.new(1,1,1)
					part.Size = mulv(part.Size,m)
					grass.Size = mulv(grass.Size,(m+Vector3.new(0,0.3,0))*0.9)
					m = Vector3.new(math.random(1,4)/4+1,1,math.random(1,4)/4+1)
					part.Size = mulv(part.Size,m)
					local random = Random.new(60391)
					for sx=x,x+lx,0.125 do
						for sz=z,z+lz,0.125 do
							local fv = n(x+1/sx,0,z+1/sz,4.123)
							if fv > 0.3 then
								local sub = foliage[random:NextInteger(1,#foliage)]:Clone()
								sub:SetPrimaryPartCFrame(CFrame.new(Vector3.new(sx,y,sz)*params.cs)*CFrame.Angles(0,math.random(0,3)*math.pi*0.5,0))
								sub.Parent = chunk.folder
								sub:ScaleTo(math.random(1,10)/10 + 1)
							end
							if fv < -0.4 then
								local sub = structures[random:NextInteger(1,#structures)]:Clone()
								sub:SetPrimaryPartCFrame(CFrame.new(Vector3.new(sx-0.125,y+0.015+0.00390625,sz)*params.cs)*CFrame.Angles(0,math.random(0,3)*math.pi*0.5,0))
								sub.Parent = chunk.folder
							end
						end
					end
				end
			end
		end
	end]]
end

-- ok now more!

return getfenv()