Cooldowns, and how to handle them?

I’m going to try and keep this as simple and short as possible, just as a small question. What’s the best way of handling cooldowns? By storing them in a table, indexing by the player, and then if equal to the attack inside the table then don’t fire as a server check?
Or would I be better off making a cooldown folder inside the character, an object that would store inside the player so that way the server can check for it, and if it is there, then don’t fire?

Or am I completely oblivious to the best option possible? Please let me know! Thanks! :smiley:

ALSO, for reference, these are like attacks and cooldowns on them, for reference. How I handle my attacks is use a single server sided script, have modules with the attacks in them, and if the keycode is equal to the value of their ability within the module, then it runs that function.

2 Likes

Here’s one way of doing it:

local ATTACK_DELAY = 1

local playersLastAttackTicks = {}
local t = tick()

function playerAttack(player)
	playersLastAttackTicks[player] = t
end

function playerCanAttack(player)
	t = tick()
	local lastAttackTick = playersLastAttackTicks[player] or 0
	if t - lastAttackTick > ATTACK_DELAY then
		return true
	else
		return false
	end
end

game.ReplicatedStorage.DoPlayerAttack.OnServerEvent:Connect(function(player)
	if playerCanAttack(player) then
		playerAttack(player)
	end	
end)

I’ve also got a Timer library that you can use if you want. It’s not very well documented, but if you’re okay with that let me know and I’ll post it here.

well yeah i know how to do that, but is this the most efficient method? that’s what im looking for. thank you again for the help!

what im asking for is like cross-modulization cooldowns, for instance; i call a move then do a cooldown on the move that was activated, how would i get the table to the server? and what about multiple tables?

the basis of what im asking here is what is the most efficient method to handling cooldowns?

There’s no simple answer. It’s going to depend on your use case. If you’re going to have many timers, it might make sense to use a library or some abstracted, reusable way of creating timers. Here’s just about the simplest way of implementing timers:

function newTimer(length, endedCallback)
	coroutine.wrap(function()
		wait(length)
		endedCallback()
	end)()
end

which you can use like this:

function playerAttack(player)
	playersCoolingDown[player] = true
	newTimer(ATTACK_COOLDOWN, function()
		playersCoolingDown[player] = false
	end)
end

The library I’ve got is a lot more complicated, so unless you need the complexity it’s probably better to use something simple like this.

You have a timer on the client and another timer on the server. The GUIs and effects that show if the cooldown is over are handled on the client. The actual effect on the game happens on the server, if you’re using an approach where only the server can make changes that affect other players. So the server checks if its version of the cooldown has ended. You kind of just repeat the logic on the client and server.

Not sure what you mean. If you mean systems in multiple scripts, you can use BindableFunctions inside scripts that return whether a specific cooldown is done.

6 Likes

ok, thank you, i’ll see what i can do and maybe get back to you

1 Like

what is the coroutine.wrap() for?