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.
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
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)
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).