Server slows down immensely from my code

I’m making a infinite voxel based mining game, the way the game functions is that there’s constant RemoteEvents firing from the player to let the server mine blocks, so that it’s based on ping instead of mining blocks based on a pickaxe’s speed. However, at some point, it takes longer to mine and the server slows down. I’ve looked through the code but there’s nothing at least that I know of that I could change anymore that could help make it faster. I’ve already tried some optimizations like adding a debounce to the mining speed so that the code isn’t running as much, and changing how some if statements run so that only the ones that are absolutely needed run at the time, but the game still slows down immensely even if it was helped by a little bit.

this is the code (at least the important parts of it), any help would be appreciated.

function choose(p, plr, id, clr , cv) --Rolling
	if p.Y<=0 then
		local clone, main = nil
		local rar = 0
		
		for _,v in pairs(ores:GetChildren()) do
			if v.Value>0 and v:GetAttribute("cave")==0 and v:GetAttribute("mindepth") <= math.abs(p.Y / 6) and v:GetAttribute("maxdepth") >= math.abs(p.Y / 6) and v:FindFirstChild("layer") == nil then
				local newrand = nil
				if plr ~= nil then
					newrand = randomyeah:NextInteger(1,math.clamp(v.Value/plr.Settings.Luck.Value, 2, 10000000000))
				else
					newrand = randomyeah:NextInteger(1,math.clamp(v.Value, 2, 10000000000))
				end
				if newrand == 1 and v.Value>rar then
					clone = game.ReplicatedStorage.Ores[v.Name]
				end
			elseif v.Value==0 and v:GetAttribute("cave") == -id then
				main = game.ReplicatedStorage.Ores[v.Name]
			elseif v.Value == 1 and v:GetAttribute("mindepth") <= math.abs(p.Y / 6) and v:GetAttribute("maxdepth") >= math.abs(p.Y / 6) and v:FindFirstChild("layer") then
				main = game.ReplicatedStorage.Ores[v.Name]
			end
		end
		if cv then
			for _,v in pairs(ores:GetChildren()) do
				if v.Value>0 and v:GetAttribute("cave")==id and v:GetAttribute("mindepth") <= math.abs(p.Y / 6) and v:GetAttribute("maxdepth") >= math.abs(p.Y / 6) and v:FindFirstChild("layer") == nil then
					local newrand = nil
					if plr ~= nil and v:GetAttribute("rarity")>7 then
						newrand = randomyeah:NextInteger(1,math.clamp(v.Value/plr.Settings.Luck.Value, 2, 10000000000))
					else
						newrand = randomyeah:NextInteger(1,math.clamp(v.Value, 2, 10000000000))
					end
					if newrand == 1 and v.Value>rar then
						clone = game.ReplicatedStorage.Ores[v.Name]
					end
				elseif v:GetAttribute("offlayerValue")>0 and v:GetAttribute("offlayer")==id and v:FindFirstChild("layer") == nil then
					local newrand = nil
					if plr ~= nil and v:GetAttribute("rarity")>7 then
						newrand = randomyeah:NextInteger(1,math.clamp(v:GetAttribute("offlayerValue")/plr.Settings.Luck.Value, 2, 10000000000))
					else
						newrand = randomyeah:NextInteger(1,math.clamp(v:GetAttribute("offlayerValue"), 2, 10000000000))
					end
					if newrand == 1 and v.Value>rar then
						clone = game.ReplicatedStorage.Ores[v.Name]
					end
				end
			end
		end
		if clone then --Ion & spec
			clone = clone:Clone()
			clone:SetAttribute("modifier", 1)
			if math.random(1, IonAndSpecChances[ores[clone.Name]:GetAttribute("rarity")])==1 then
				clone:SetAttribute("modifier", 2)
				if math.random(1, 15)==1 then
					clone:SetAttribute("modifier", 3)
					Spectralize(clone)
				else
					IonizeW1(clone)
				end
			end
		else
			clone = main:Clone()
		end
		if plr ~= nil then
			clone:SetAttribute("luck", plr.Settings.Luck.Value)
			clone:SetAttribute("owner", plr.Name)
		end
		
		local originalPosition = clone.Position
		
		clone.Position = p
		
		for i,v in pairs(clone:GetDescendants()) do
			if v:IsA("BasePart") then
				v.CollisionGroup = "Wispy_Ignore_Collide"
				v.Position = clone.Position + (v.Position - originalPosition)
			end
		end
		
		if game.ReplicatedStorage.OreData[clone.Name]:GetAttribute('rarity') == 1 then
			if clr ~= nil and clr ~= true then
				clone.Color = clr
			end
		end
		blocks[p]=true
		if ores[clone.Name]:GetAttribute("rarity")>7 then
			game.ReplicatedStorage.Effect:FireAllClients(clone.Name)
			game.ReplicatedStorage.SpawnedEventOre:Fire(clone.Name)
		end
		clone.CollisionGroup = "Wispy_Ignore_Collide"
		clone.Parent = workspace.Blocks
	end
end

local dir = {
	Vector3.new(6,0,0),
	Vector3.new(0,6,0),
	Vector3.new(0,0,6),
	Vector3.new(-6,0,0),
	Vector3.new(0,-6,0),
	Vector3.new(0,0,-6)
}

function dig(p, plr, clr)
	for i = 1, #dir do
		if blocks[p + dir[i]]==false or not blocks[p + dir[i]] then
			task.spawn(function()
				choose(p+dir[i], plr, 0, clr)
			end)
		end
	end
end

game.ReplicatedStorage.Mine.OnServerEvent:Connect(function(p, t, clr, val)
	task.spawn(function()
		
		if t then
			if t.Parent == workspace.Placed then
				print('placed ore')
				if t:GetAttribute("owner") == p.Name then
					t:Destroy()
					game.ReplicatedStorage.PlaceMined:FireAllClients(p, 'Pickup')
				end
				return
			end
			
			if t.Parent == workspace.Blocks then
				
				if t:GetAttribute("owner") ~= "" and t:GetAttribute("owner") ~= p.Name then
					return
				end
				if (p.Character.HumanoidRootPart.Position - t.Position).Magnitude > 300 then
					return
				end
				if t:FindFirstChild("unbreakable") then
					if not p.Character:FindFirstChild("Steel Breaker") then
						return
					end
				end

				--print(t.Position)
				local pos = t.Position
				
				if math.noise(pos.X/100, pos.Y/100, pos.Z/100)<-0.5 then
					local far = true
					for _,v in pairs(currentcaves) do
						if (pos-v).Magnitude<75 then
							far = false
						end
					end
					if far then
						cave(p, pos)
					end
				end
				
				dig(t.Position, p, clr)
				local orename = t.Name
				local oremod = t:GetAttribute("modifier")
				p.leaderstats.Mined.Value += 1
				if t.Reflectance == 0 then
					t.Reflectance = 1
					t:Destroy()
					if oremod==1 then
						p.Normal[orename].Value += 1
					elseif oremod==2 then
						p.Ionized[orename].Value += 1
					elseif oremod==3 then
						p.Spectral[orename].Value += 1
					end
					if ores[t.Name]:GetAttribute("rarity")>5 then
						print("rare (there's actual code here but it's not important since it happens infrequently)")
					end
				end
			end
		end
	end)
end)

I do not see a single wait statement.

yielding is done locally

(minimum characters)

This will not answer your question, but have you looked into profiling your scripts as you’re hitting slow spots in your experience (i.e. LuauHeap, ScriptProfiler)? It may reveal information that will give you a greater insight as to what would actually be taking up the most amount of render and processing time in your experience. Good luck!

1 Like

I’ve genuinely never heard of these tools but after looking into it for (literally) a couple of minutes these look useful to figure out what’s causing the lag, thank you :​)