While loop not breaking properly

local runService = game:GetService("RunService")

local changeAmount = .125
local updateThread;

script.Parent:WaitForChild("ChangeEnergyRun").OnServerEvent:Connect(function(plr, action)
	local char = plr.Character
	local energy = plr:FindFirstChild("Energy")
	
	if action == "Start" then
		if char:FindFirstChild("Decreasing") then
		else
			local decreasing = Instance.new("BoolValue")
			decreasing.Name = "Decreasing"
			decreasing.Parent = char
		end
		
		if action == "Stop" then
			if char:FindFirstChild("Decreasing") then
				char:FindFirstChild("Decreasing"):Destroy()
			end
		end
	end
	
    if not updateThread and action == "Start" then
		updateThread = task.spawn(function()
			while runService.Heartbeat:Wait() do
				energy.Value -= changeAmount
			end
		end)
    elseif updateThread and action == "Stop" then
        task.cancel(updateThread)
    end
end)

Is your intention only having this event connect once? if so you can try using :Once() instead of :Connect() to avoid multiple threads creating

It needs to be fired everytime the player starts running and stops running as it’s meant to alter the energy value.

That didn’t give a big error which is good, but then it stopped working from this small error:
cannot resume dead coroutine

thats impossible because its creating the coroutine each time…

show us your script

Here:

local runService = game:GetService("RunService")

local changeAmount = .125
local updateThread;

script.Parent:WaitForChild("ChangeEnergyRun").OnServerEvent:Connect(function(plr, action)
	local char = plr.Character
	local energy = plr:FindFirstChild("Energy")

	if action == "Start" then
		if char:FindFirstChild("Decreasing") then
		else
			local decreasing = Instance.new("BoolValue")
			decreasing.Name = "Decreasing"
			decreasing.Parent = char
		end
	end
	
	if action == "Stop" then
		if char:FindFirstChild("Decreasing") then
			char:FindFirstChild("Decreasing"):Destroy()
		end
	end
	
	if not updateThread and action == "Start" then
		updateThread = task.spawn(function()
			while runService.Heartbeat:Wait() do
				energy.Value -= changeAmount
			end
		end)
	elseif updateThread and action == "Stop" then
		task.cancel(updateThread)
	end
end)

It’s the same one made by Jqck

try this while i think of something

(not updateThread and action == "Start")

(updateThread and action == "Stop")

Sorry, still gives that same error

Still giving same error for some reason

Ahh mb, I forgot threads don’t get set to nil automatically

local runService = game:GetService("RunService")

local changeAmount = .125
local updateThread;

script.Parent:WaitForChild("ChangeEnergyRun").OnServerEvent:Connect(function(plr, action)
	local char = plr.Character
	local energy = plr:FindFirstChild("Energy")

	if action == "Start" then
		if char:FindFirstChild("Decreasing") then
		else
			local decreasing = Instance.new("BoolValue")
			decreasing.Name = "Decreasing"
			decreasing.Parent = char
		end
	end
	
	if action == "Stop" then
		if char:FindFirstChild("Decreasing") then
			char:FindFirstChild("Decreasing"):Destroy()
		end
	end
	
	if not updateThread and action == "Start" then
		updateThread = task.spawn(function()
			while runService.Heartbeat:Wait() do
				energy.Value -= changeAmount
			end
		end)
	elseif updateThread and action == "Stop" then
		task.cancel(updateThread)
        updateThread = nil
	end
end)

Ooh it’s actually working now without any problems, but it keeps giving that same error on the output each time.

Seems to be an engine issue

Ah I see, well then would it be a good idea to add a pcall function to stop those errors for this?

Seems kinda hacky but you can do it ofc if it works, my proposed idea (not tested) would be to replace the Heartbeat:Wait with task.wait(1/60) as Heartbeat fires every 1/60th of a frame. But while we are at that we can also talk about the whole system in general. So from what I understand, you are changing the amount of smth every frame by a small factor (.125). This is just inefficient for not only are you wasting server resources tryna compute all this but also replicating unnecessary data each frame to all clients. So my proposed solution is you update it every second, which is much better imo. But to get the same result, you would have to modify the changeAmount to 60 times the initial amount (since it is being changed 60 times a second) i.e .125 * 60 = 7.5. Anyways that’s just my opinion. The only drawback I see with this system is that if the thread closes .9 secs or smth after the last change, the newest change won’t be registered but that seems like a minor inconvenience. You can also up the rate of change to 1/10th of a second for more precision.

Edit: Added some stuff at the bottom @Ragnability

1 Like

Fair enough, but really thanks very much for this solution because your script also helped me learn about these new thread functions which I never knew about. I’m also glad everybody came to help to try to fix this since it really did take long to figure it out.

Anytime

Also there is bit of calculation mistake on my part, it should have been .125 * 60 = 7.5, fixed it in the post.

Oh right that’s fine lol no worries

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