Is a script performance rate of over 20,000 ok?

I have a script that is creating thousands of coroutines to handle animation on thousands of tentacles. The rate for this script is getting unbelievably high! How can I improve my script performance?
Screenshot 2023-11-24 at 1.34.06 PM

This is my current code:

local function Animate(rig)
	local anim = script.TentacleAnim
	local animator = rig.AnimationController
	local playerDetectionRange = 500
	local playing = false

	local function isPlayerNearby()
		local players = game:GetService("Players"):GetPlayers()

		for _, player in ipairs(players) do
			local character = player.Character
			if character then
				local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
				if humanoidRootPart and (script.Parent.Tentacle.Position - humanoidRootPart.Position).Magnitude <= playerDetectionRange then
					return true
				end
			end
		end

		return false
	end

	while task.wait(1) do
		if isPlayerNearby() and playing == false then
			playing = true
			local animation = animator:LoadAnimation(anim)
			animation.Looped = false
			animation:Play()
			animation.Ended:Wait()
		end
	end

end

script.Parent.ChildAdded:Connect(function(child)
	if child:IsA("ProximityPrompt") then
		print("proximityPrompts")
	elseif child:FindFirstChild("Tentacles") then	
		local tentacles = child.Tentacles:GetChildren()
		for _, tentacle in pairs(tentacles) do
			coroutine.wrap(Animate)(tentacle)
		end
	end
end)

You should put constant values or functions outside the animate function because it creates a new function/variable everytime you call it which is unnecessary and wastes performance/memory.

Ah! Great idea. I can’t believe I didn’t take the isPlayerNearby() function out. :man_facepalming: I dont know if this will take the performance down enough though. It’s still climbing into the thousands very quickly.
Screenshot 2023-11-24 at 1.42.46 PM

Maybe destroy the animation track and use runservice.heartbeat and then use deltatime to replace the task.wait(1).

:grimacing:, sounds pretty complicated. I haven’t worked much with deltatime, could you show me a code snippet?

Is gonna be hard cuz im on mobile but just give me a moment to try, okay?

1 Like

I was thinking, would it be better to handle this on the client? Should I try and see if it will work better?

local counter = 0
game:getService("runservice").Heartbeat:connect(function(deltaTime)
Counter += deltaTime
If counter >= 1 then -- one is the cooldown time and can be replaced if wanted.
     -- run animation
     Counter = 0
End

Animations are always better to handle on client. Just use fireallclients

1 Like

Ima try this and get back to you.

1 Like

unfortunately, the code you gave me makes the system not work at all. Im going to try stepped instead of heartbeat.

Can you show it because i might have explained it weirdly

local playerDetectionRange = 500

local function isPlayerNearby(tentacle)
	local players = game:GetService("Players"):GetPlayers()

	for _, player in ipairs(players) do
		local character = player.Character
		if character then
			local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
			if humanoidRootPart and (tentacle.TentacleRig.Position - humanoidRootPart.Position).Magnitude <= playerDetectionRange then
				return true
			end
		end
	end

	return false
end

local function Animate(rig)
	local anim = script.TentacleAnim
	local animator = rig.AnimationController
	local playing = false
	local counter = 0
	
	game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
		counter += deltaTime
		if counter >= 1 then
			if isPlayerNearby(rig) and playing == false then
				playing = true
				local animation = animator:LoadAnimation(anim)
				animation.Looped = false
				animation:Play()
				animation.Ended:Wait()
			end
		end
		counter = 0
	end)

end

script.Parent.ChildAdded:Connect(function(child)
	if child:IsA("ProximityPrompt") then
		print("proximityPrompts")
	elseif child:FindFirstChild("Tentacles") then	
		local tentacles = child.Tentacles:GetChildren()
		for _, tentacle in pairs(tentacles) do
			coroutine.wrap(Animate)(tentacle)
		end
	end
end)

EDIT: I fixed it by adding the local counter = 0 inside the if statement.

1 Like

The script rate is too high mostly because you’re doing too much infinite loops, so it is going to make the game super laggy and crash.

You should do only one loop that handle all tentacles in coroutines.
Something like this

game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
    for _, Child in pairs(script.Parent:GetChildren()) do
        if Child:FindFirstChild("Tentacles") then
            local tentacles = child.Tentacles:GetChildren()
            coroutine.wrap(Animate)(tentacles)
        end
    end
end)

How would I do that on the Animate function though?

You have to remake the function, probably using a table to check each tentacle status, here is an exemple:

local TentaclesTable = {}

local function Animate(rig)
	local anim = script.TentacleAnim
	local animator = rig.AnimationController

    if not TentaclesTable[rig] then
        TentaclesTable[rig].playing = false
    end

	if isPlayerNearby(rig) and TentaclesTable[rig].playing == false then
	    TentaclesTable[rig].playing == true
		local animation = animator:LoadAnimation(anim)
		animation.Looped = false
		animation:Play()
		animation.Ended:Wait()
        TentaclesTable[rig].playing == false
	end
end
1 Like

Thank you so much! You brought down the rate tremendously!

Screenshot 2023-11-24 at 4.10.12 PM

1 Like

Mmm…if it’s truly okay with you,go for it. But otherwise,I think if you have script problems,there must be a way to shorten it for you to find the problem easier.

Sorry for the late response though good sir.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.