Hey there!
I've been bored out of my mind with this whole "Not having a job due to quarantine thing" & have been messing around with Perlin noise in generating terrain. I've got it working pretty nicely, looking spectacular if I may say!
Now, to expand upon the question, which is not yet asked: How do I load in chunks seamlessly without causing colossal lagspikes? So far my code is using for loops per dimension size to load in the first starting chunk (I found the initial code in a YouTube video, and thus I have expanded upon it for a cleaner terrain generation). I generate the seed using math.random(0, 10000000) for... randomness. Now, I can't just simply load in a whole new chunk because this method is using thousands of blocks per chunk, which would cause immense lag. So I was thinking of despawning around 10 blocks behind the user and 10 in front per increment. But I still have no way of knowing how to do this.
If you have any question please let me know! Code is below.
game.ReplicatedStorage.RemoteEvent.OnServerEvent:Connect(function() local n = tick() for _,v in pairs(workspace.TerrainG:GetChildren()) do v:Destroy()end local mapxsize = 100 local mapysize = 40 local mapzsize = 100 local seed = math.random(0,10000000) local noisescale = 50 local amplitude = 20 local blocksize = 3 local lastBlock for x=0,mapxsize do for z = 0,mapzsize do for y=0,mapysize do if y == mapysize then local lastPart = Instance.new("Part") lastPart.Material = Enum.Material.SmoothPlastic lastPart.Anchored = true lastPart.Size = lastBlock.Size lastPart.CFrame = CFrame.new(lastBlock.Position.X, lastBlock.Position.Y + blocksize, lastBlock.Position.Z) lastPart.BrickColor = BrickColor.new("Bright green") lastPart.Parent = workspace.TerrainG local treeblock = math.random(1, 1000) if treeblock == 12 then local tree = game:GetService("ReplicatedFirst").Tree:Clone() tree:SetPrimaryPartCFrame(CFrame.new(lastPart.Position)) tree.Parent = workspace.TerrainG end local rockblock = math.random(1, 1000) if rockblock == 12 then local rock = game:GetService("ReplicatedFirst").Rock:Clone() rock:SetPrimaryPartCFrame(CFrame.new(lastPart.Position.X, lastPart.Position.Y + 1, lastPart.Position.Z)) rock.Parent = workspace.TerrainG end local grassblock = math.random(1, 50) if grassblock == 12 then local grass = game:GetService("ReplicatedFirst").Grass:Clone() grass:SetPrimaryPartCFrame(CFrame.new(lastPart.Position.X, lastPart.Position.Y + 2, lastPart.Position.Z)) grass.Parent = workspace.TerrainG end else local xnoise = math.noise(y/noisescale,z/noisescale,seed) * amplitude local ynoise = math.noise(x/noisescale,z/noisescale,seed) * amplitude local znoise = math.noise(x/noisescale,y/noisescale,seed) * amplitude local density = xnoise + ynoise + znoise + y if density < 20 and density > 10 then if density <= 19 and density > 10 then local rand = math.random(1, density) if rand == 3 then local part = Instance.new("Part") part.Material = Enum.Material.SmoothPlastic part.Anchored = true part.Size = Vector3.new(blocksize,blocksize,blocksize) part.CFrame = CFrame.new(x*blocksize,y*blocksize,z*blocksize) part.BrickColor = BrickColor.new("Dark stone grey") part.Parent = workspace.TerrainG lastBlock = part end end local part = Instance.new("Part") part.Material = Enum.Material.SmoothPlastic part.Anchored = true part.Size = Vector3.new(blocksize,blocksize,blocksize) part.CFrame = CFrame.new(x*blocksize,y*blocksize,z*blocksize) part.BrickColor = BrickColor.new("Brown") part.Parent = workspace.TerrainG lastBlock = part elseif density < 10 then local part = Instance.new("Part") part.Material = Enum.Material.SmoothPlastic part.Anchored = true part.Size = Vector3.new(blocksize,blocksize,blocksize) part.CFrame = CFrame.new(x*blocksize,y*blocksize,z*blocksize) part.BrickColor = BrickColor.new("Dark stone grey") part.Parent = workspace.TerrainG lastBlock = part end end end end end local m = tick()-n print(m) end)
This page could help: https://developer.roblox.com/en-us/articles/content-streaming