Hello, I’d like to get tips on how to improve my model-pasting-welding code of the terrain generation script.
(it’s part of another function)
local assets = game.ReplicatedStorage.Assets.MapParts
local LandBlocks = {assets.StoneBlock, assets.CorruptedStoneBlock}
local DeepBlocks = {assets.BasaltBlock, assets.CorruptedBasaltBlock}
local GrassBlocks = {assets.Grass, assets.CorruptedGrass}
local C_HEIGHT = wp.MainIslands.Height
local function getPosCons(pos:Vector3): {Model} --there are only 3 positions that can already be in the map folder (4 if part pos is x, 1, z)
local pos0, pos1, pos2 = pos-Vector3.new(1, 0, 0), pos-Vector3.new(0, 0, 1), pos+Vector3.new(0, 1, 0)
local cons = {}
local f0, f1, f2 = game.Workspace.Map:FindFirstChild(tostring(pos0)), game.Workspace.Map:FindFirstChild(tostring(pos1)), game.Workspace.Map:FindFirstChild(tostring(pos2))
if f0 then table.insert(cons, f0) end
if f1 then table.insert(cons, f1) end
if f2 then table.insert(cons, f2) end
if pos.Y == 1 then
local pos3 = pos-Vector3.new(0, 1, 0)
local f3 = game.Workspace.Map:FindFirstChild(tostring(pos3))
if f3 then table.insert(cons, f3) end
end
return cons
end
local function createWeld(parent:Instance, primary:BasePart, primary2:BasePart)
local weld = Instance.new("WeldConstraint")
weld.Part0 = primary
weld.Part1 = primary2
weld.Name = "MapWeld"
weld.Parent = parent
end
local function pasteModel(pos:Vector3, model:Model, name:string?, rot:CFrame?)
local clone = model:Clone()
clone.Parent = game.Workspace.Map
rot = rot or CFrame.Angles(0, math.rad(math.round(RANDOM:NextInteger(0, 400)/100)*90), 0)
clone:PivotTo(CFrame.new(pos)*rot)
local pos2 = pos/10
pos2 = Vector3.new(math.round(pos2.X), math.round(pos2.Y), math.round(pos2.Z))
clone.Name = name or tostring(pos2)
if clone.PrimaryPart then clone.PrimaryPart.Anchored = true else clone:FindFirstChildWhichIsA("BasePart", true).Anchored = true end
return clone
end
local function afterPaste(model:Model)
task.wait(0.5)
local primary = model.PrimaryPart or model:FindFirstChildWhichIsA("BasePart", true)
local pos2 = model:GetPivot().Position/10
pos2 = Vector3.new(math.round(pos2.X), math.round(pos2.Y), math.round(pos2.Z))
if model.Name:find("Grass") then
local m = game.Workspace.Map:FindFirstChild(tostring(pos2))
if not m then return end
createWeld(model, primary, m.PrimaryPart or m:FindFirstChildWhichIsA("BasePart", true))
else
for _, m:Model in pairs(getPosCons(pos2)) do
local primary2 = m.PrimaryPart or m:FindFirstChildWhichIsA("BasePart", true)
createWeld(model, primary, primary2)
end
end
end
local function prepRandIndex(index:number, max:number)
local index2 = math.round(index*max)
return index2 == 0 and 1 or index2
end
local function groupAfterPaste(models: {Model})
for _, m:Model in pairs(models) do
coroutine.wrap(afterPaste)(m)
end
end
for i, pos2:Vector3 in pairs(worldBlocks) do --worldBlocks is a table with positions (Vector3)
if game.Workspace.Map:FindFirstChild(tostring(pos2)) then continue end
local pos = pos2*10
local zeroPos = Vector3.new(pos2.X, 0, pos2.Z)
local pastedModels = {} :: {Model}
local randomIndex = RNG(0, 100)/100
local randomInteger = RNG(0, 100)/100
--try to find a part at 0, 0, 0 and if not then create it
if table.find(worldBlocks, zeroPos) and pos2.Y > 0 and pos2.Y < C_HEIGHT+1 and (Vector3.new(pos2.X, 0, pos2.Z).Magnitude <= wp.MainIslands.CircleRadius+RMX+1) then
local zeroBlock = game.Workspace.Map:FindFirstChild(tostring(zeroPos)) :: Model?
if not zeroBlock then
if randomInteger*3 > 2 then
coroutine.wrap(afterPaste)(pasteModel(zeroPos*10, assets.LadderAbandonedBlock))
coroutine.wrap(afterPaste)(pasteModel(pos, assets.LadderAbandonedBlock))
continue
else
table.insert(pastedModels, pasteModel(zeroPos*10, DeepBlocks[prepRandIndex(randomIndex, #DeepBlocks)]))
end
elseif table.find(zeroBlock:GetTags(), "Ladder") then
coroutine.wrap(afterPaste)(pasteModel(pos, assets.LadderAbandonedBlock, nil, zeroBlock:GetPivot().Rotation))
continue
end
end
if pos2.Y == C_HEIGHT then
local index = prepRandIndex(randomIndex, #LandBlocks)
table.insert(pastedModels, pasteModel(pos, LandBlocks[index]))
if not table.find(worldBlocks, pos2+Vector3.new(0, 1, 0)) and randomInteger < 0.5 then
table.insert(pastedModels, pasteModel(pos, GrassBlocks[index], "Grass "..tostring(pos2)))
end
elseif pos2.Y < C_HEIGHT then
table.insert(pastedModels, pasteModel(pos, DeepBlocks[prepRandIndex(randomIndex, #DeepBlocks)]))
end
--now weld it up!
coroutine.wrap(groupAfterPaste)(pastedModels)
if i % 100 == 0 then
task.wait()
print("Pasting "..i.."/"..#worldBlocks)
end
end
Everything works fine, but I need more performance. On my pc it takes only 2-4 mins to generate a 300 * 300 blocks world with 100 blocks huge islands circle radius. But on the roblox server it’s 6-8 mins. I want it to take only up to 3 mins.
I already tried checking less positions for connections (cons), getting random number only 2 times in a loop and the coroutines. It worked, but I still need more performance and Idk what to do.