local CHUNK_SIZE = 256
local RADIUS = 3
local LEEWAY = 20
local POOL_SIZE = 64
local BASE_RADIUS = 1

script:WaitForChild("GenerateChunk").Disabled = true
local pool = 0
local chunks = {}
local schunks = {}
local function chunk(x,z)
	if not schunks[x] then schunks[x] = {} end
	local i = {x=x,z=z}
	local first,second
	local c = {delete=function()
		if first then
			game.Workspace.Terrain:FillRegion(Region3.new(first.Value,second.Value),4,Enum.Material.Air)
		end
	end,viable = true}
	chunks[i]=c
	schunks[x][z]=c

	task.defer(function()
		repeat wait() until pool < POOL_SIZE
		if not c.viable and not c.permanent then return end 
		local actor = Instance.new("Actor")
		actor.Parent = game.Workspace
		local new_script = script.GenerateChunk:Clone()
		local location = new_script.Location
		location.Value = Vector3.new(x,CHUNK_SIZE,z)
		first = new_script.First
		second = new_script.Second
		new_script.Parent = actor
		new_script.Disabled = false
		pool = pool + 1
		new_script.Destroying:Connect(function()
			pool = pool - 1
		end)
	end)
	
	return c
end

for x = -BASE_RADIUS,BASE_RADIUS do
	for z = -BASE_RADIUS,BASE_RADIUS do
		if Vector2.new(x,z).Magnitude < BASE_RADIUS then		
			chunk(x,z).permanent = true
		end
	end
end

while wait(0.5) do
	for index,chunk in pairs(chunks) do
		chunk.viable = false
	end
	local perPlayer = function(p)
		for index,chunk in pairs(chunks) do
			if Vector2.new(p.x-index.x*CHUNK_SIZE,p.z-index.z*CHUNK_SIZE).Magnitude < CHUNK_SIZE*(RADIUS+LEEWAY) then
				chunk.viable = true
			end
		end
		for x=math.ceil(p.x/CHUNK_SIZE)-RADIUS,math.ceil(p.x/CHUNK_SIZE)+RADIUS do
			for z=math.ceil(p.z/CHUNK_SIZE)-RADIUS,math.ceil(p.z/CHUNK_SIZE)+RADIUS do
				if not schunks[x] then schunks[x] = {} end
				if not schunks[x][z] then
					chunk(x,z)
				end
			end
		end
	end
	
	for _,player in pairs(game.Players:GetPlayers()) do
		if player.Character then
			if player.Character.PrimaryPart then
				perPlayer(player.Character.PrimaryPart.Position)
			end
		end
	end
	
	perPlayer(game.Workspace.CurrentCamera.CFrame.Position)
	
	for index,chunk in pairs(chunks) do
		if not chunk.viable and not chunk.permanent then
			schunks[index.x][index.z] = nil
			--if #schunks[index.x] == 0 then schunks[index.x] = nil end
			chunk.delete()
			chunks[index] = nil
		end
	end
end