I have a fully functioning roundSystem script which handles many key features of my game, including CFrames, Incrementing Of Values, etc. However, I’m not satisified fully with its state now, as it’s had a very bumpy past, constantly throwing errors, acting slow etc. One major factor, I believe, is the cleanup function.
I’ve had to clone/destroy models with hundreds of parts, in attempt to refresh the game once the round has occurred. This has lead to many script exhaustion time errors, and it’s disrupted gameplay heavily.
I managed to subdue the constant errors by introducing Runservice.Heartbeat:Wait and a lot of Waits but I still wonder if anything more can be done to optimize this (making it as fast as possible), to prevent long delays between rounds (Like I am experiencing at the moment.
Function
function CleanUp()
workspace.Current.Part.SurfaceGui.TextLabel.Text = "Regenerating Map For Next Round"
for i, v in pairs(workspace.SpleefMap:GetDescendants()) do
if v:IsA("Part") then
v:Destroy()
game:GetService('RunService').Heartbeat:Wait()
end
end
for i, v in pairs(workspace:GetChildren()) do
if v.Name == "Portal" or v.Name =="UFO" or v.Name == "JumpPad" then
v:Destroy()
game:GetService('RunService').Heartbeat:Wait()
end
end
local Clone = game.ServerStorage.SpleefMap:Clone()
wait(1)
game.ReplicatedStorage.GeneratingMap:FireAllClients(true)
wait(8)
print("Regenerating")
game.ReplicatedStorage.Regenerating.Value = true
Clone.Parent = workspace
local chosenColor = BrickColor.Random()
for i, v in pairs(Clone:GetDescendants()) do
if v:IsA("Part") then
v.BrickColor = chosenColor
game:GetService('RunService').Heartbeat:Wait()
end
end
wait(1)
local ss = game.ServerStorage.PartTagger:Clone()
ss.Parent = Clone
wait()
game.ReplicatedStorage.Regenerating.Value = false
workspace.Current.Part.SurfaceGui.TextLabel.Text = ""
end
Waits in there are annoying for me, and I want to find a way to remove as many of them as possible, as these are preventing the errors, but they are provoking more time to wait, which is makes the game more tedious. Thanks!
Possibly segment the waits by waiting every 2, 3, or 5 parts instead of every individual part so that it doesn’t take near as long? (will reduce the wait time by like 2, 3, or 5 times)
(Note you could maybe get away with 10 – might wanna test different speeds)
You can achieve this with the Modulus operator (%).
Example:
for i, v in pairs(Clone:GetDescendants()) do
if (i % 3) == 0 then
game:GetService('RunService').Heartbeat:Wait()
end
if v:IsA("Part") then
v.BrickColor = chosenColor
end
end
What is the Modulo operation?
“In computing, the modulo operation returns the remainder or signed remainder of a division, after one number is divided by another.”
I would recommend replacing the i in i, v in pairs() with an underscore (_) if you aren’t using it. I can also agree with Trayeus, you should try that.
No. But I suggest you do not use pairs with normal tables. Use ipairs when iterating normal tables. If you do not use a variable in Lua it is a good rule to leave it as_ which means it is a placeholder variable.
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Hearbeat = RunService.Heartbeat
local WaitAmount = 20 -- On every nth iteration it will wait a bit.
function CleanUp()
local TextLabel = workspace:FindFirstChild("Current"):FindFirstChild("Part"):FindFirstChild("SurfaceGui"):FindFirstChild("TextLabel")
TextLabel.Text = "Regenerating Map For Next Round"
workspace:WaitForChild("SpleefMap"):Destroy()
for i, v in pairs(workspace:GetChildren()) do
if v.Name == "Portal" or v.Name == "UFO" or v.Name == "JumpPad" then
v:Destroy()
if 1 % WaitAmount == 1 then
Hearbeat:Wait()
end
end
end
local Clone = ServerStorage:FindFirstChild("SpleefMap"):Clone()
Hearbeat:Wait()
ReplicatedStorage:FindFirstChild("GeneratingMap"):FireAllClients(true)
wait(8)
print("Regenerating...")
ReplicatedStorage:FindFirstChild("Regenerating").Value = true
Clone.Parent = workspace
local chosenColor = BrickColor.Random()
for i, v in pairs(Clone:GetDescendants()) do
if v:IsA("Part") then
v.BrickColor = chosenColor
if 1 % WaitAmount == 1 then
Hearbeat:Wait()
end
end
end
wait(1)
local New = ServerStorage:FindFirstChild("PartTagger"):Clone()
New.Parent = Clone
Hearbeat:Wait()
ReplicatedStorage:FindFirstChild("Regenerating").Value = false
TextLabel.Text = ""
end
Another optimisation you could make is to avoid using :IsA when not comparing abstract classes (such as BasePart).
You should instead compare the .ClassName property
if somePart:IsA("Part") then -- slower
if somePart.ClassName == "Part" then -- fast
-------------------------------------
-- very slow
if somePart.ClassName == "Part" or somePart.ClassName == "MeshPart" or somePart.ClassName = ... then
-- much faster! (and cleaner too)
if somepart:IsA("BasePart") then
:IsA is aroud half the speed of just comparing the ClassName, but you should always use :IsA when comparing abstract classes
No… Just why lol. Optimizations like that are not helpful at all. That’s a 0.0001 micro-optimization. Optimizations such as the time complexity of your program should be taken more in consideration.