Exhaused Allowed Execution Time?

I have a regeneration function that clones and randomly edits a map from server storage. Until lately, its been fine. But now it keeps on provoking the error:

'ServerScriptService.RoundSystem' Line 189, Exhausted Allowed Execution Time

I don’t understand what the issue is. Help would be greatly appreicated

Section Of Code Linked To This Within the round system handler

		if roundtime.Value == 0 then
				game.ReplicatedStorage.StartPowerups:FireAllClients(false)
				wait()

				TeleportPlayersBackToLobby()
				wait()
				CleanUp() -- Erroring Here?


				wait(1)

				AwardPlayers()	
				wait()

			end
		end

Cleanup Function/ Regenarate function

function CleanUp()
	if workspace:WaitForChild("SpleefMap",5) then
		workspace:FindFirstChild("SpleefMap"):Destroy()
	end
	wait(1)
	print("Regenerating")
	wait()
	local Clone = game.ServerStorage.SpleefMap:Clone()
	wait()
	Clone.Parent = workspace
	wait()
	

	local chosenColor = BrickColor.Random()
	wait()
	for i, v in pairs(Clone:GetDescendants()) do
		if v:IsA("Part") then
			v.BrickColor = chosenColor
		end
	end
	wait()
	local ss = game.ServerStorage.PartTagger:Clone()
	wait()
	ss.Parent = Clone
	wait()

end

Thanks!

How many parts are in this “SpleefMap” model?

1 Like

I have a lot of parts within the model. Is this the reason?

The large amount of parts in the model could be the reason, so add a delay in any loops inside if your function, since that error usually occurs in an infinite loop.

1 Like

It would be there you would need a short yield. Or you can just reduce the amount of objects to change color onto. Or again like mentioned above reduce parts in the model.

1 Like

so just add a wait() or something?

Not wait() but RunService.Heartbeat:Wait()

It’s a shorter wait, which would come in more useful.

for i, v in pairs(Clone:GetDescendants()) do
		if v:IsA("Part") then
           game:GetService('RunService').Heartbeat:Wait()
			v.BrickColor = chosenColor
		end
	end

Not sure yielding is the best solution here, but it’s all I got for now

1 Like

what’s the difference between using wait and heartbeat wait anyway

https://developer.roblox.com/en-us/api-reference/event/RunService/Heartbeat

As Heartbeat fires every frame, it runs on a variable frequency . This means the rate will vary depending on the performance of the machine. If the game is running at 40 FPS, then Heartbeat will fire 40 times per second and the step argument will be roughly 1/40th of a second.

It’s much quicker than wait and would save you much more time compared to using wait()

1 Like

I’ll test it and let you know the results

1 Like

No difference.

This chunk seems to be causing the issue:

if workspace:WaitForChild("SpleefMap",5) then
		workspace:FindFirstChild("SpleefMap"):Destroy()
	end
	wait(1)

I’ll double check though

That seems odd, maybe remove that 5 as second argument in WaitForChild? Shouldn’t make much of a difference.

Oh also, don’t use FindFirstChild there, you would use FindFirstChild only if you are expecting something to be there like true or false but in this case we are 100% sure the map would be there. So,

if workspace:WaitForChild("SpleefMap") then
		workspace.SpleefMap:Destroy()
	end
	wait(1)

I remember reading a post saying the . is 6 times quicker than FindFirstChild

1 Like

Unless you’re waiting for something to load in, you otherwise only need FindFirstChild to check for an object’s existence. FindFirstChild also returns the object so you only need to call it once here.

local oldMap = workspace:FindFirstChild("SpleefMap")
if (oldMap) then
	oldMap:Destroy()
end
wait(1)

Also, if your map is really big then calling Destroy on it may also be what is taking up a lot of resources.

@uhi_o The reason FindFirstChild takes longer is because it is doing a linear search of all the object’s children. Using the “.” is just indexing an object directly when you know for sure the object will be there. FindFirstChild is meant for searching for a child with the possibility it may not exist.

2 Likes

If Destroy is causing the timeout, you may also implement a custom destroy function with a slight delay, using the idea that @Phazenine mentioned earlier.

local rs = game:GetService("RunService")
local partLimit = 100 -- how many parts to destroy before waiting
local counter = 0
local function slowDestroy(item)
	counter = (counter + 1) % partLimit
	if (counter == 0) then
		rs.Heartbeat:Wait()
	end
	for _, child in ipairs(item:GetChildren()) do
		slowDestroy(child)
	end
	item:Destroy()
end
2 Likes

Unfortunately, it’s still erroring at line 16. Maybe the wait isn’t enough

I feel like this will probably fix my problems but seeing as I’m not on pc rn, I’ll check on it tomorrow. Thanks anyway

You fixed the first issue. Kinda. It’s erroring with the function you gave, with the exhausted allowe execution time error.

Current code:

function Destroy(item)
	local pl = 100
	local counter = 0
	counter = (counter+1) % pl
	if counter == 0 then
		game["Run Service"].Heartbeat:Wait()
		
	end
	for i, v in pairs(item:GetDescendants()) do
		Destroy(v) ---ERRORING HERE, EXHAUSTED ALLOWED  EXHACUTIONN TIME
	end
	item:Destroy()
end

The counter needs to be outside the function. Otherwise it is starting at 0 every time a recursive call is made, meaning it never reaches ‘pl’ to make the function wait.

Also, use GetChildren() instead of GetDescendants(). The reason I used GetChildren is so that the function does a recursive DFS, so that items at the bottom of the hierarchy with no descendants get deleted first, then their parent, etc. That allows for the wait time between every 100 items.

1 Like