Checking if a player is eligible to claim a reward?

Hey!

I’m currently making a tri-daily reward system (Every 3 days), and I’d like to know the best way to check if the player is eligible to claim the reward on the client.

I have a TimeUntilReward variable which is the time until the player can claim the reward, however I’d like to know the best way to “count-down” on the client. (This variable is managed on the server and is easily accessible by the client - I have this part covered.)

I tried using a loop (& RenderStepped) but it didn’t work as hoped + it wasn’t practical.

Also, I don’t want the game to automatically make a pop up with a claim button or the server automatically reward the player, I want the client to claim it themselves from the gifts menu I have.

Thanks!

You would simply save the time when they got the reward (save os.time() into a datastore) then to check how long it has been you would simply do:

local claimedtime = --whatever the claimed time was
local timeleft =  259200 - (os.time() - claimedtime) --259200 is the seconds in 3 days

you can translate that into a time with more math

1 Like

yes, i have all of this information already

however I want to know an efficient way of counting down a timer on the client until the player is eligible to claim it

the last login time & the time until the player can claim the reward is already internally handled by my datastore manager

Oh, if that’s what you need, you should use :FireClient() to send the time to the player (when they join) and then count it down from there.

1 Like

well this probably wouldnt work

i have a remotefunction that is sent from the client to the server and that function returns the time until the player is eligible to claim

but the way of counting down is what im struggling with
loops wont work and nor will renderstepped/heartbeat

You don’t exactly need it to be fast, assuming the lowest time is seconds, you can just use

while wait(1) do
end
1 Like

I just said a loop can’t work due to the fact another function is needed to be ran when the remaining time is 0, and if this function keeps repeating itself then well it’ll be a hot mess

Then you should use coroutines.

That wouldn’t help either, i’ve already tried them

This post doesn’t really matter anymore, I’ve gone for a different approach which is easier

1 Like

Alright, sorry I couldn’t help, but good luck!

1 Like

What @Kaid3n22 suggested about using os.time(), which returns UTC time, is legit. Use that value as the source of truth for when the reward is claimable.

However the timing suggestions they made are very problematic - the client can do its own timing by calling os.time() itself without the server needing to inform it with a RemoteEvent, and especially don’t use a while wait(...) do ... end - it’s an anti-pattern. Use RunService.Heartbeat to update something that needs updating based on real-life time.

Replicate the UTC timestamp wherein the player can next claim the reward somewhere simple, like a like a NumberValue in the Player. Then. do something like this to show the time remaining:

local vNextRewardTimestamp = game.Players.LocalPlayer:WaitForChild("NextRewardTimestamp")

local textLabel = script.Parent

local function getNextRewardTimestamp()
    return vNextRewardTimestamp.Value
end

local function update()
   local timeLeft = getNextRewardTimestamp() - os.time()
   if timeLeft > 0 then
      textLabel.Text = "Time left: " .. timeLeft
   else
      textLabel.Text = "Available!"
   end
end

update()
game:GetService("RunService").Heartbeat:Connect(update)
1 Like

Thanks for the detailed response, I don’t think I made myself too clear in the original post so I’ll just clear some things up regarding my issue.

My remote function already returns a time until the reward is ready to be claimed, I’m not going to handle this risky business on the client.

I know how to format the number ect, I just didn’t know how to make it countdown “well” (can’t think of any better word)

I’m using @ForeverHD’s TopBar+ module to create the button to claim the reward, and when the reward is ready to be claimed I’d call a function called :notify() onto the claim button, adding a little 1 above the button letting the user know it was ready to be claimed. If I called this notify function every second or frame, it will obviously build up: 1, 2, 3… ect. And as far as I’m aware I can’t check how many notifications a button has which is quite annoying.

Once again, thanks for the response. I’m no longer going to update the text every second or frame, I’ll just let the user know how long is left when they click the claim button.

Sounds like you have the solution right there, then. Time it on a loop or however you please, and on the frame you first realize it’s available, call notify once and set some flag that API was called. Clear the flag when they claim the reward (ie the reward timestamp changed).

1 Like