Optimizing Mass Part Spawning for Procedurally Generated Terrain

I made one of these a while back. Builds in a circle around the player, super fast. But, I had to go to the client to get that kind of performance out of it. The fact you are as far as you are now is a bit shocking with a server script doing this.

They are generating the terrain on the server and sending it to the client, they aren’t creating parts on the server.

Obviously I was talking about the terrain generation.

Well it shouldn’t be that expensive, it’s just math.

It’s a night and day difference on the client.

Why are you gatekeeping your benchmark’s code?

I’m not trying to gatekeep but here:

--!optimize 2

task.wait(1)

local part = script.Part
local iters = 50

local timings = {}

local function timeFunction <T>(label: string, func: (...T) -> (), ...: T?)
	local start = os.clock()
	
	func(...)
	
	timings[label] = os.clock() - start
end

-- Create parts
local parts = {}

for i = 1, 1000 do
	local new = part:Clone()
	new.Parent = script.Parent
	
	parts[i] = new
end

task.wait()

timeFunction(".CFrame", function()
	for i = 1, iters do
		local desiredCFrame = CFrame.new(i, i, i)
		
		for _, part in parts do
			part.CFrame = desiredCFrame
		end
	end
end)

task.wait()

local pivotTo = part.PivotTo

timeFunction(":PivotTo", function()
	for i = 1, iters do
		local desiredCFrame = CFrame.new(i, i, i)
		
		for _, part in parts do
			pivotTo(part, desiredCFrame)
		end
	end
end)

task.wait()

timeFunction(":BulkMoveTo", function()
	for i = 1, iters do
		workspace:BulkMoveTo(parts, table.create(#parts, CFrame.new(i, i, i)), Enum.BulkMoveMode.FireCFrameChanged)
	end
end)

for label, timing in timings do
	print(`[{label}]: {timing * 1000}ms`)
end
1 Like