#Seamless cooldown sync

1 messages · Page 1 of 1 (latest)

frigid geyser
#

I'm struggling to create a cooldown that starts right after the client creates one to avoid animation and vfx spamming but is also managed by the server to avoid exploiting. The setup I have now causes the client to request a cooldown be made multiple times before a cooldown is made

#

Local script

UserInputService.InputBegan:Connect(function(input, gpe)
  if not gpe and input.UserInputType == Enum.UserInputType.MouseButton1 and CanAct() then
    repeat

       if not CooldownManager:IsOnCooldown(Character, "M1") then
          if CombatTick >= 5 then
            CombatTick = 1
          else
            CombatTick += 1
            CooldownEvent:FireServer(Character, "M1", 5)
          end
       end
  end
end
raw sorrel
#

i would use a true/false variable but that can be easily exploited

brazen monolithBOT
#

studio** You are now Level 6! **studio

raw sorrel
#

so like

frigid geyser
#

A module script listens for a server event and creates an event that is visible to the server in replicated storage and the CooldownManager is another module that i use here to check if something is on cooldown, which it doesnt catch until after multiple events are fired

raw sorrel
#

i would create a new variable set to false then in the if:

if not CooldownManager:IsOnCooldown(Character, "M1") and deBounce == false then
deBounce = true
--blah blah other code
else
deBounce = false
end
frigid geyser
#

The module script checks if there are any values under a folder that contains data of the cooldown

#

If there are any items that fit the player's name and cooldown, it recognizes its on cooldown

frigid geyser
raw sorrel
#

i guess?

#

its like

#

a debounce

frigid geyser
#

a backwards one

#

okay

raw sorrel
#

i think it could work but im not really sure

frigid geyser
#

i'll try it

frigid geyser
raw sorrel
#

it waits before starting i assume

frigid geyser
#

It works

#

Ty

raw sorrel
#

nice

frigid geyser
#

I thought of it earlier but thought there had to have been a better way

#

One more question

#

actually nvm

jaunty dove
#

seamless is impossible without security risk

#

and if you ask me, any game that uses client-sided logic for hitboxes and whatnot is not really very well made

coarse elbow
#

Then you can handle any cooldown logic on the server and if multiple requests are still being sent despite them being on cooldown you kick/log them rather than executing your server logic

faint goblet
jaunty dove
#

Unless you have something that works for server-authenticated

#

And I'm not talking about doing quick checks to see if it's in the right ballpark, I'm talking about accurate, infallible hitboxes and likewise

coarse elbow
# frigid geyser A module script listens for a server event and creates an event that is visible ...

I could be wrong as I’m in bed and didn’t really look through everything but from what I understand right now your setup seems a little overkill and overcomplicates a very simple task you simply want to manage cooldowns on the server for security but are currently encountering an issue where the player is able to spam for a short duration before the server check kicks in preventing you from continuing to spam?

frigid geyser
frigid geyser
#

I have it on a repeat so you can just hold left click so it'll go through 4 melee attacks rapidly before stopping bc its on cooldown

coarse elbow
#

And you don’t want this?

frigid geyser
#

Nope

#

its going through the animations

coarse elbow
#

Alright so you need a local debounce on the client

frigid geyser
#

i literally already added this 😭

coarse elbow
#

Do the animations play before the debounce?

frigid geyser
#

no the issue is fixed now

#

ive run into another issue tho

coarse elbow
#

Like what?

frigid geyser
#

ill get back on studio bc i got off for dinner and to relax with smth else

#

So i'm trying to set up decimals for cooldown values so that I can make cooldown indicators. The value is created on the server and values sit in replicated storage so that the client can do changed events and update the guis (not added yet) but for some reason they lag and don't hit 0 only on these values

#

If I use the value in a gui text or just look at it in the folder, the value will not hit 0 before it disappears but it does when I print it

coarse elbow
#

Are you manually decreasing the cooldown rather than checking what the cooldown is and outputting it via time comparisons?

brazen monolithBOT
#

studio** You are now Level 3! **studio

frigid geyser
#

My cooldown system works by adding an item to the folder and the cooldown reader just checks if there's an item with the name of the cooldown

#

It's using debris service to add the parts instead of a clock or anything

#

well debrisgobbler which is a much more efficient version of debris service

coarse elbow
#

Hmm the setup seems a little convoluted for me to follow I’d probably need more snippets of your code to help find the problem but considering I’m just on my phone in bed right now I’d probably just wait for someone else to properly assist you

frigid geyser
#

I only use a module for cooldowns because it's going to be a lot more than just melee attacking but i'll show some of the code

#
function CooldownManager:CreateCooldown(Character, CooldownName, Duration)
    local plr = Players:GetPlayerFromCharacter(Character)
    
    local CharacterCooldowns = CooldownManager.Cooldowns[(plr or Character)]
    if not CharacterCooldowns then
        CooldownManager.Cooldowns[(plr or Character)] = {}
        CharacterCooldowns = CooldownManager.Cooldowns[(plr or Character)]
    end
    
    local Cooldowns = CharacterCooldowns[CooldownName]
    if not Cooldowns then
        CharacterCooldowns[CooldownName] = {}
        Cooldowns = CharacterCooldowns[CooldownName]
    end
    
    local CooldownArray = {}
    CooldownArray[1] = Duration
    CooldownArray[2] = Clock()
    CooldownArray[3] = CreateValue(CooldownName, Duration, plr) or nil
    
    local ArrayPos = (#Cooldowns + 1)
    table.insert(Cooldowns, ArrayPos, CooldownArray)
end
#

there's a folder for each player in game under this module script and the CreateValue function creates a numbervalue. The name of the value is the Cooldown name and the value is the cooldown which is supposed to decrement so that the client knows what the cooldown is on

#

i might just rework this thing entirely bc there's some redundant code and i already lost track of why half of this stuff is even here

coarse elbow
#

What all do you need this module for?

#

You want to check the duration of cooldowns store the last use for comparison

#

And just have an easy place to access this data?

frigid geyser
#

Yes

#

It’s the method i’m using for adding cooldowns for any attack and also checking if that thing is on cooldown at any time. It can also remove them

coarse elbow
#

I think the way you went about this overcomplicates things a bit so I would most likely recommend just remaking it

frigid geyser
#

I might switch to debounces for simplicity

coarse elbow
#

Yea I

#

I didn't mean to send my message so early but yea that works

#

if you do want extra information like the duration for things like displaying the time left on guis

frigid geyser
#

Are debounces exploitable

coarse elbow
#

debounces are just to ensure legit players cant keep spamming moves with cooldowns

#

you still need security checks on the server to ensure they can actually use the move

frigid geyser
#

How would I do that then

coarse elbow
#

assuming you already know how to include the debounce on the client where the server logic is you need to hold cooldown information similar to how you did if they dont already have cooldown information you create it ensuring the first use is free so the starting tick is 0 afterwards if they already have cooldown you log the new usetime and with every call to the server you check the last use with the current time and cooldown if they are able to use the move you proceed normally if not you log

#

them usually id have a value that raises every time they call the server despite being on cooldown and this value resets after a certain amount of time if they exceed the amount of fired remotes then you kick/ban proceed however you please but this usually indicates theres foul play

frigid geyser
#

Thats basically what im doing

coarse elbow
#

I think it could be the application then

frigid geyser
#
if not CooldownManager:IsOnCooldown(Character, "M1") and not Debounce then 
coarse elbow
#

cooldown manager should already be acting as a debounce so the second one is redundant there must be some error in the way time is saved/compared allowing them to spam

frigid geyser
#

CooldownManager is looking at a number created by the server

#

Debounce is the cooldown the client made

coarse elbow
frigid geyser
#

like i said

#

the spam issue is gone

#

i have a new problem entirely

coarse elbow
#

ah i see

frigid geyser
#

im trying to have it decrement in 100ths so that cd indicators can be more accurate

coarse elbow
#

Yea I saw that it disappears prematurely before reaching 0

frigid geyser
#

the cooldowns themselves work fine

coarse elbow
#

thats why i asked whether you are using a loop to manually decrease the value

frigid geyser
#

im using a loop

#
local function TickCooldown(Cooldown:NumberValue, Duration)
    for i = Duration, 0, -0.01 do
        Cooldown.Value = i
--        print(i)
        task.wait(0.01)
    end
end
coarse elbow
#

I would instead use the time difference as the number you are going off of

#

rather than manually decreasing the value yourself

frigid geyser
#

How do I keep track of its time left?

coarse elbow
#

you just display the timeleft via loop

frigid geyser
#

I'm not familiar with time differences

coarse elbow
#

cd (currtime - lastmovetime)

#

that gets you the time left

frigid geyser
#

how do i get the current and last time tho

coarse elbow
#

you can get the current time using os.clock i'd look into that yourself

#

and you also log the last time you used the move every time you use it

frigid geyser
#

Ok so lemme make sure i'm checking it right

#

If you declare a variable equal to os.clock, it continues to count time elapsed indefinitely or until the variable is no longer the clock

coarse elbow
#

not quite os.clock returns elasped time in seconds since an arbitrary baseline

#

so time since like 1/1/1990 or sum

#

i dont know the exact time

#

but you can use it to compare two different times since the value continues to increase to get time differences

#

which you can use to do time related things inside your game

frigid geyser
#

ooh

coarse elbow
#

I myself haven't really delved into os.clock that much I only recently switched from the deprecated tick so my explanation might not be that accurate

brazen monolithBOT
#

studio** You are now Level 4! **studio

coarse elbow
#

but thats the premise

frigid geyser
#

if a variable is set to os.clock it basically snapshots the unix timestamp

coarse elbow
#

yes yes

frigid geyser
#

oh thats tuff

coarse elbow
#

its also extremely accurate so you can get those fine tuned times

frigid geyser
#

i'll try to rewrite the time ticker then and see if i get better numbers

coarse elbow
#

yea that should definitely help out

#

my bad for the confusion lol

frigid geyser
#

nah ur good i'm just new to clocks

#

i haven't rly thought of learning it until now

coarse elbow
#

yes its gonna be extremely useful for any timer related things

frigid geyser
#

Should I use a while loop that breaks when the value is gone?

coarse elbow
#

precise cds

#

etc

#

when the timeleft reaches the cooldown then yea youd break the loop

#

or sorry when it reaaches

#

0

coarse elbow
#

I would look into the various os library yourself like I said before I'm not too experienced in it myself sorry about that mishap

frigid geyser
#

idk the terminology for that 😢

coarse elbow
#

it's the time since 1/1/1970

#

i think os.clock is more based around the system your on

#

cpu time sum like that

frigid geyser
#
local function TickCooldown(Cooldown:NumberValue, Duration, TimeUsed)
  while true do
    if not Cooldown then break end
    Cooldown.Value = (os.clock() - TimeUsed)
    task.wait(0.01)
  end
end
frigid geyser
#

its cpu time

coarse elbow
#

this should in theory give a more accurate time

#

make sure to use task.wait rather than wait though

frigid geyser
#

oops

#

i feel like im missing something

#

duration isnt used

coarse elbow
#

did you break the loop when the time reaches 0?

#

duration is calcuated via that equation

#

or atleast the timeleft

frigid geyser
#

When debris removes the cooldown, the loop will break

#

it basically wont hit 0 because debris removes it before then but i can add the check anyways just in case

coarse elbow
#

isn't the intended functionality for the time to reach 0 before the intvalue is destroyed?

frigid geyser
#

idk how to explain this

coarse elbow
#

also for accucary id probably break the loop when the time reaches 0 rather than when debris destroys the value pretty sure this would just be more efficient

frigid geyser
#

debris removes the number value before the game has the chance to set its value to 0

#

but yea im adding that check rn

coarse elbow
#

I get that I'm kinda just confused on why you have it set up like that

frigid geyser
#

wdym

#

Idk if its the most efficient way but it basically only ticks down as long as the cooldown value exists in the player's folder

coarse elbow
#

seems a little weird but if you are just trying to make your setup work for now i wouldnt sweat it too much

frigid geyser
#

I added

if Cooldown.Value <= 0 then break end
``` before the task.wait
coarse elbow
#

though you should definitely aim to ensure your code is as efficient and modular as it can be so you can continue to grow and not build bad habits

coarse elbow
frigid geyser
#

Thats why i have almost everything in a module right now

#

well time to test it

coarse elbow
#

fingers crossed

frigid geyser
#

uh

#

ok it works i just did my subtraction backwards

coarse elbow
#

nice! does the value decay smoothly?

frigid geyser
#

I think so yeah

#

Its much more accurate than my 100ths place version

#

Its now recording time on the 1000ths

#

i just need it to tick down instead of up and this will make my indicators so much better

coarse elbow
#

yea i noticed that

#

weird

#

could be a small error in the logic

frigid geyser
#

i just need to switch the usedtime and clock

#

i did my operation wrong

coarse elbow
#

alrighty you should be set then

frigid geyser
#

wait no

#

thats not it

coarse elbow
#

what issue are you encountering?

frigid geyser
#

i cant do it that way bc clock is greater than the used time so it would go below 0

coarse elbow
#

local timeleft = moveCD - (tick() - lastMoveTime)

it should look something like this

frigid geyser
#

oh yeah

#

oops

coarse elbow
#

of course youd replace tick with os.clock just grabbed this out of a previous game i was working on for practice

frigid geyser
#

done

#

it works good now

coarse elbow
#

alright should be nice for displaying

#

now id say all thats left is just for you to round as you see necessary

frigid geyser
#

I've run into a difficult part now

coarse elbow
#

to get those exact values

#

what is it?

frigid geyser
#

you might come up with a solution faster than me bc you seem more experienced but here

#

i need only some cooldowns to show up on my ui

#

"RandomCooldown" is a value I put in only as a placeholder that spawns after the 5 string combo and I want that one to show on my ui and update its value but not the M1 cooldown

#

i was thinking of adding an attribute to the number values that specifies if it'll show up on the ui or not but idk

#

creating a table of things that'll show up on there seems excessive

coarse elbow
#

so you want some kind of cooldown filter is what youre saying? and only certain cooldowns will display on your ui?

brazen monolithBOT
#

studio** You are now Level 5! **studio

frigid geyser
#

yeah

#

Most cooldowns will show up on their hotbar slot when I add the hotbar ui but other cooldowns for things not on there will show up on the additional ui

coarse elbow
#

id guess id probably have my ui configured via module and i can have certain moves use functions inside that module that show the cooldown on the ui and otherwise handle cooldowns regularly maybe by constantly changing the tool.name

#

if youre saying all cooldowns go through a system like this and you need a filter i guess additional data attached to the cooldown being sent could be used to determine whether that cooldown will be displayed on your hotbar or on the ui at the side of your screen

#

hope that makes sense

#

your approach would be valid for now but not scalable you could use a lookup table if you know what this is but i think a more central modular design would be more helpful and you mentioned you dont want to create a table

frigid geyser
#

just create a list of cooldowns that will be looked at in the indicator script and if it appears in the active cooldowns, it'll add the indicator to the ui