Help with decreasing value

I am making a wave system and I want my wave to last 20 seconds. The duration starts when a bool value turns true.

The problem is that if the bool changes, the duration will change faster.

local IsBattling = player:WaitForChild("IsBattling")
	local duration = 20
	
	IsBattling.Changed:Connect(function(value)
		if value == true then
			coroutine.wrap(function()
				while duration > 0 and IsBattling.Value == true do
					duration -= 1
					if duration <= 0 then
						break
					end
					task.wait(1)
				end
			end)()
		end
	end)
1 Like

You should make a variable to hold the thread, so when the value changes. You can cancel it using coroutine.close() ln that thread

Right now you ate basically creating a new thread everytime the value changes.

2 Likes

The issue with your current code is that every time the IsBattling value changes, a new coroutine is started, which leads to multiple coroutines running simultaneously and updating the duration value at different rates. Instead, you can modify your code to use a single coroutine that starts when IsBattling becomes true, and stops when it becomes false. Here’s an example:

local IsBattling = player:WaitForChild("IsBattling")
local duration = 20
local waveCoroutine = nil

IsBattling.Changed:Connect(function(value)
    if value == true then
        waveCoroutine = coroutine.create(function()
            while duration > 0 and IsBattling.Value == true do
                duration -= 1
                task.wait(1)
            end
            -- Wave ended, reset duration and coroutine
            duration = 20
            waveCoroutine = nil
        end)
        coroutine.resume(waveCoroutine)
    else
        -- Wave ended prematurely, stop the coroutine and reset duration
        if waveCoroutine then
            coroutine.resume(waveCoroutine, true)
            duration = 20
            waveCoroutine = nil
        end
    end
end)

In this updated code, a single coroutine is created when IsBattling becomes true, and it runs until either the duration reaches 0 or IsBattling becomes false. If the wave ends normally, the duration is reset and the coroutine is set to nil . If the wave ends prematurely, the coroutine is stopped, the duration is reset, and the coroutine is set to nil . Note that the coroutine.resume() function is used to start and stop the coroutine. If the coroutine is stopped prematurely, the coroutine.resume() function is called with the second argument set to true , which causes the coroutine to return immediately.

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