I have a skill GUI that displays usable skills by pressing a key on the keyboard or an image button on-screen (for mobile users).
I have a local script in StarterCharcterScripts that listens for a button to be pressed and fires an event on the server and controls the cooldown of the event. The event is in a script in ServerScriptService which loads the animation, sound, and clones a touched event script into the appropriate body part of the character doing the skill.
My question is where should I write the code to display the cooldown on that player’s GUI?
Does it go in the local script or the server script? I just want to make the image more transparent and display the time left until it is used again.
Also is there any way to improve this method I have used? (I am using about 10 different key-binds that alternate based upon which stance a player is in, so about 26 skills in total as some overlap.)
I have read a few other articles here on the subject, but I am still unclear.
I would personally put it in the server script because an exploiter can easily change the cool down on the LocalScript. Therefore, your event is prone to spam, which is a known method for exploiters to crash servers. Using :tick() is an effective way. You can check the thread here.
You should write the code to display the cooldown in the player’s GUI, and in playerGUI’s only local scripts will work. But to make the game exploit-proof, you should do the code for the countdown itself in a script, since only the server should be able to change the cooldown, not the client itself.
You can do this by counting down for the actual skill in a script, sent an event from server to client that the button needs to be disabled, and after the countdown, send an event that they are able to use the button again. But the skill itself will only look for the value of the cooldown in the script, not in the localscript.
Never trust the client for things like countdowns which affect also other players’ gameplay.
I may be misinformed, but I was told that by having the cooldown in a localscript instead of say, an IntValue would make it impossible to be changed. I also have the remote event being created by the server each time, which is not the most efficient way, but those exploiters would not be able to create an event and fire it. I am not disagreeing in any way, I am down for doing it however is the best way. Thanks for your input. I started reading about the tick method and went down a hyperlink rabbit hole. I will have to come back to this later and let you know.
No. The variable is “stored” in a LocalScript meaning its somewhere in memory on the client and can be overwritten. Its even easier to overwrite if you use the variable in a function.
Always do it on both. The server should be using a future time model where it doesn’t allow a remote call to pass if a certain time hasn’t been elapsed yet and the client should be using prediction to figure out when their cooldown ends. That way, you have a good divide where the server isn’t expending resources.
The server would have something like this:
local currentTime = tick()
if currentTime > lastFireTime + cooldown then
lastFireTime = currentTime
doAction()
end
While the client could count down from a simple for loop to a Heartbeat-based counter:
for i = cooldown, 0, -1 do
showTimeUntilCooledDown(i)
end
A side note is that sometimes the cooldown would not go off if I was mashing the button so I changed it to be offset 0.1 of a second in either direction so technically the cooldown is 0.2 seconds longer, but not noticeable as it starts .1 later and ends .1 later, but this adds a nice buffer for the animations as well.