Quickening world generation

I am generating a blocky world with math.noise(), and right now it takes very long to generate worlds. It does it layer by layer, here is it doing it:

But it has to do that for a 100x100 block world (not studs, blocks. they are 3x3x3 studs)

Here is the script:

for x = 1,100 do
	for z = 1,100 do
		local p = game:GetService("ReplicatedStorage").G:Clone()
		p.Parent = workspace.blocks
		local height = (math.noise(x / 20, seed, z / 20) + 2) * 50
		p.Position = Vector3.new(3*x,height-height%3,3*z)
		local am = 3
		for i = 1,3 do
			local p2 = game:GetService("ReplicatedStorage").Dirt:Clone()
			p2.Parent = workspace.blocks
			p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
			if p2.Position.Y < 48 then
				p2:Destroy()
			elseif p2.Position.Y == 48 then
				p2.Color = Color3.fromRGB(0,0,0)
				p2.Name = "Baseplate"
			end
			am = am + 3
		end
		for i = 1,22 do
			local p2 = game:GetService("ReplicatedStorage").Stone:Clone()
			p2.Parent = workspace.blocks
			p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
			if p2.Position.Y < 48 then
				p2:Destroy()
			elseif p2.Position.Y == 48 then
				p2.Color = Color3.fromRGB(0,0,0)
				p2.Name = "Baseplate"
			end
			am = am + 3
		end
		wait()
	end
end

I timed it on my iPad, and it took about 6 minutes to create a world. How could I quicken up this process?

1 Like

Render just the surface

If you need a mining system you can make it so when a block is mined, new ones are created around it.

Wait after every X amount of Blocks created would be one way of doing this.

local totalGenerated = 0
local waitForEvery = 50

function addToTotal()
 totalGenerated = totalGenerated + 1
 if totalGenerated % waitForEvery == 0 then wait() end
end

for x = 1,100 do
	for z = 1,100 do
		local p = game:GetService("ReplicatedStorage").G:Clone()
		p.Parent = workspace.blocks
		local height = (math.noise(x / 20, seed, z / 20) + 2) * 50
		p.Position = Vector3.new(3*x,height-height%3,3*z)
		local am = 3
        addToTotal()
		for i = 1,3 do
			local p2 = game:GetService("ReplicatedStorage").Dirt:Clone()
			p2.Parent = workspace.blocks
			p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
			if p2.Position.Y < 48 then
				p2:Destroy()
			elseif p2.Position.Y == 48 then
				p2.Color = Color3.fromRGB(0,0,0)
				p2.Name = "Baseplate"
			end
			am = am + 3
            addToTotal()
		end
		for i = 1,22 do
			local p2 = game:GetService("ReplicatedStorage").Stone:Clone()
			p2.Parent = workspace.blocks
			p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
			if p2.Position.Y < 48 then
				p2:Destroy()
			elseif p2.Position.Y == 48 then
				p2.Color = Color3.fromRGB(0,0,0)
				p2.Name = "Baseplate"
			end
			am = am + 3
            addToTotal()
		end
	end
end

Try using coroutines.

coroutine.wrap(function()
--Shizzle for one row
end)() --dont forget the () because it wont run without it

Hell here’s what I did for generating a grid:

--packet and gridpart generation
	for i=0, gSize, pSize do
		wait()
		coroutine.wrap(function()
			for j=0, gSize, pSize do
				wait()
				coroutine.wrap(function()
					local f = Instance.new("Folder")
					f.Name = "Packet"..(((i)/pSize)+1)..(((j)/pSize)+1)
					f.Parent = pCont
					
					local index1 = i
					local index2 = j
					for x=0, (pSize-1) do
						wait()
						coroutine.wrap(function()
							for z=0, (pSize-1) do
								local x1 = (index1 * gridPart.Size.X) + (x * gridPart.Size.X) + gridPart.Size.X/2
								local z1 = (index2 * gridPart.Size.Z) + (z * gridPart.Size.Z) + gridPart.Size.Z/2
								wait()
								local c = gridPart:Clone()
								c.Position = Vector3.new(x1, 0, z1)
								c.Parent = f
							end
						end)()
					end
				end)()
			end
		end)()
	end

Looks like:
Better%20Perlin

1 Like

I’m probably just being dumb, but where would I place the coroutines / what would I wrap in them?

Coroutines have many functions. But were just gonna focus on the wrapping function.

So we need one for loop outside the coroutine, this for loop instantiates or creates a new coroutine for each row/column. Next you need the coroutine inside the for loop to hold the next for loop. So your new code looks like this:

for x = 1,100 do
	coroutine.wrap(function()
		for z = 1,100 do
			local p = game:GetService("ReplicatedStorage").G:Clone()
			p.Parent = workspace.blocks
			local height = (math.noise(x / 20, seed, z / 20) + 2) * 50
			p.Position = Vector3.new(3*x,height-height%3,3*z)
			local am = 3
			for i = 1,3 do
				local p2 = game:GetService("ReplicatedStorage").Dirt:Clone()
				p2.Parent = workspace.blocks
				p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
				if p2.Position.Y < 48 then
					p2:Destroy()
				elseif p2.Position.Y == 48 then
					p2.Color = Color3.fromRGB(0,0,0)
					p2.Name = "Baseplate"
				end
				am = am + 3
			end
			for i = 1,22 do
				local p2 = game:GetService("ReplicatedStorage").Stone:Clone()
				p2.Parent = workspace.blocks
				p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
				if p2.Position.Y < 48 then
					p2:Destroy()
				elseif p2.Position.Y == 48 then
					p2.Color = Color3.fromRGB(0,0,0)
					p2.Name = "Baseplate"
				end
				am = am + 3
			end
			wait()
		end
	end)()
end

Tada, I hope it works (cause I made this in like 2 minutes)

Okay, I wrapped it like this

for x = 1,25 do
	coroutine.wrap(function()
		for z = 1,25 do
			local p = game:GetService("ReplicatedStorage").G:Clone()
			p.Parent = workspace.blocks
			p.Anchored = true
			p.Size = Vector3.new(3,3,3)
			p.TopSurface = Enum.SurfaceType.Smooth
			p.BackSurface = Enum.SurfaceType.Smooth
			p.Color = Color3.fromRGB(52, 142, 64)
			local height = (math.noise(x / 20, seed, z / 20) + 2) * 50
			p.Position = Vector3.new(3*x,height-height%3,3*z)
			local am = 3
			for i = 1,3 do
				local p2 = game:GetService("ReplicatedStorage").Dirt:Clone()
				p2.Parent = workspace.blocks
				p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
				if p2.Position.Y < 48 then
					p2:Destroy()
				elseif p2.Position.Y == 48 then
					p2.Color = Color3.fromRGB(0,0,0)
					p2.Name = "Baseplate"
				end
				am = am + 3
			end
			local am = 12
			for i = 1,22 do
				local p2 = game:GetService("ReplicatedStorage").Stone:Clone()
				p2.Parent = workspace.blocks
				p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
				if p2.Position.Y < 48 then
					p2:Destroy()
				elseif p2.Position.Y == 48 then
					p2.Color = Color3.fromRGB(0,0,0)
					p2.Name = "Baseplate"
				end
				am = am + 3
			end
			wait()
		end
	end)()
end

(its 25 because I’m in “testing” mode)

However it is only creating one layer.
I’m going to also go read up on coroutine.wrap

Ah sorry, that’s due to my crappy 2 minute job.
You’ll want the coroutine function to wrap around what’s inside the z loop.

for x = 1,25 do
	for z = 1,25 do
                coroutine.wrap(function()
		local p = game:GetService("ReplicatedStorage").G:Clone()
		p.Parent = workspace.blocks
		p.Anchored = true
		p.Size = Vector3.new(3,3,3)
		p.TopSurface = Enum.SurfaceType.Smooth
		p.BackSurface = Enum.SurfaceType.Smooth
		p.Color = Color3.fromRGB(52, 142, 64)
		local height = (math.noise(x / 20, seed, z / 20) + 2) * 50
		p.Position = Vector3.new(3*x,height-height%3,3*z)
		local am = 3
		for i = 1,3 do
			local p2 = game:GetService("ReplicatedStorage").Dirt:Clone()
			p2.Parent = workspace.blocks
			p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
			if p2.Position.Y < 48 then
				p2:Destroy()
			elseif p2.Position.Y == 48 then
				p2.Color = Color3.fromRGB(0,0,0)
				p2.Name = "Baseplate"
			end
			am = am + 3
		end
		local am = 12
		for i = 1,22 do
			local p2 = game:GetService("ReplicatedStorage").Stone:Clone()
			p2.Parent = workspace.blocks
			p2.Position = Vector3.new(p.Position.X,p.Position.Y-am,p.Position.Z)
			if p2.Position.Y < 48 then
				p2:Destroy()
			elseif p2.Position.Y == 48 then
				p2.Color = Color3.fromRGB(0,0,0)
				p2.Name = "Baseplate"
			end
			am = am + 3
		end
		wait()
                end)()
	end
end

Tho do note that if this doesn’t work Im really bad at 2 minute jobs.

2 Likes

It worked! That was great, normally a 25x25 world would take ~30 seconds or so but it was nearly instant with very minimal lag. Thanks!

And a 100x100 world now only takes ~25 seconds!

2 Likes