Hello there do you mind helping me how to make an accurate time reward?
Here’s my code:
I use loop to make a countdown system and it is not accurate at all
for i= seconds, 0, -1 do
claim_button.Text = formatTime(i)
task.wait(1)
end
claim_button.Text = "CLAIM!"
can_claim = true
and here’s the all code if you want to look:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local client_player = Players.LocalPlayer
local packages = ReplicatedStorage:WaitForChild("Packages")
local Knit = require(packages.Knit)
local RewardController = Knit.CreateController {
Name = "RewardController"
}
local REWARD_DATA = {
60;
300;
600;
900;
1200;
1500;
1800;
2100;
2400;
2700;
}
local function formatTime(seconds)
return string.format("%02i:%02i", seconds/60%60, seconds%60)
end
function RewardController:Configure(rewardFrame: Frame)
local scrolling_frame = rewardFrame:WaitForChild("RewardScrolling"):WaitForChild("ScrollingFrame")
while not client_player:GetAttribute("DataLoaded") do
task.wait()
end
for _, v in scrolling_frame:GetChildren() do
if v:IsA("Frame") then
local claim_button = v:FindFirstChild("ClaimFrame"):FindFirstChild("ClaimButton")
local order_number = tonumber(string.match(v.Name, "%d+"))
local seconds = REWARD_DATA[order_number]
local can_claim = false
v.LayoutOrder = order_number
if claim_button then
if Knit.GetService("DataService"):Get("Rewards")[order_number] then
claim_button.Text = "CLAIMED."
return
end
claim_button.Active = true
claim_button.Activated:Connect(function()
if can_claim then
can_claim = false
claim_button.Text = "CLAIMED."
local RewardService = Knit.GetService("RewardService")
RewardService.Reward:Fire({
OrderNumber = order_number;
})
end
end)
task.spawn(function()
for i= seconds, 0, -1 do
claim_button.Text = formatTime(i)
task.wait(1)
end
claim_button.Text = "CLAIM!"
can_claim = true
end)
end
end
end
end
return RewardController
What I would try to do is first get a starting time that all of the timers will reference. I would put this before the for loop in RewardController:Configure
local startingTime = os.time()
Then, in the for i= seconds, 0, -1 do loop that you showed in the first code snippet, I would instead replace said loop with
while true do
task.wait(0.1)
claim_button.Text = formatTime(math.floor(os.time() - startingTime))
if math.floor(os.time() - startingTime) >= seconds then
break
end
end
im a goofball so im not sure if this will fix it but im theorizing since all the timers would reference the same startingTime that maybe this could sync the timers
as for the optimization, im not too knowledgeable so i wouldnt be able to help with that (i jus learned right now that I was supposed to use os.time() for timestamps)
wait did you mean adding up as in the timer ADDS up instead of decreasing or did i offset the timers by 5 seconds (added an additional 5 seconds to the wait time)?