How would I make customizable cooldowns?

I am currently using a quite simple cooldown system, waiting with a coroutine inside it, but I want some moves to, for example shorten the cooldown of other moves if they are on cooldown. I am not sure how to start on this if I would use a module or not. Here’s what I use currently

	        coroutine.resume(coroutine.create(function()
		wait(15)
		cd = false
	end))

As you can see, it will always wait 15 seconds. What if during the waiting, someone uses a move to shorten all cooldowns by 5 seconds. How can I change my code to make it compatible with shortening cooldowns?

you can use a while loop to lower all cooldowns every second and have the cooldowns as a number variable and you can lower the variable with the other abilites

ex:

local cooldown = 0

mousedown-- detection or whenevcer ability activates
cooldown = 15
end

lowercooldown function ()
cooldown -=5 -- lowers cooldown time by 5
end

while true do
-- lower cooldowns
wait(1)
end

by no means should you use this exact code as this is to just give a rough example of what to do

This is best achieved by simply storing either

  • The timestamp the user can next perform a function
  • The timestamp the user performed the function

I tend to prefer the latter. Here’s an example of the implementation:

local lastClickTime = 0

local function performMove()
    if time() - lastClickTime < getCooldownLength() then
        -- User has performed action too fast, we return to stop the function from performing any other tasks.
        return
    end

    lastClickTime = time()
    -- continue with your normal function code from here..
end

Now you are able to define a getCooldownLength function which returns how many seconds the user should have to wait to act between moves. For example, if you wanted to make the user have a 5 second cooldown boost if they have more than 100 coins, you could do something like:

local function getCooldownLength(player)
    return player.coins.Value > 100 and 10 or 15
end

Of course, you would have to adapt the code and functions to suit your use case.

In my example, you would connect performMove to whatever you want, such as a RemoteEvent OnServerEvent, or a user click.

I want it to get reduced as the cooldown is going for example, so I did something like this. Would this work.?

	if cd > 0 then return end
	cd = 15
	reduceval = true
	        coroutine.resume(coroutine.create(function()
		while true do
			if status:FindFirstChild("CooldownReduce") and reduceval == true then
				reduceval = false
				cd = cd - status:FindFirstChild("CooldownReduce").Value		
			end
			wait(.1)
			if cd > 0 then
				cd = cd - .1
			end
			game.ReplicatedStorage:WaitForChild("Effect"):FireClient(player, "Cooldown", nil, nil, nil, nil, cd, script.Parent.Name, nil)
			if cd <= 0 then break end
		end
	end))