How to make an accurate timed reward system?

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

Thanks in advance! :slight_smile:

3 Likes

wait first off, how isn’t the countdown system accurate?

is the timer off or is the reward off or idk

4 Likes

i mean the counting is aight its just not just synced. But idk if that’s a problem but is there other way of making it more optimize?

2 Likes

When you say its not synced, do you mean it does not give a reward exactly when it was supposed to, counting down is inconsistent, or what’s the deal?

3 Likes

probably the latter; its probably not giving the reward exactly when needed.

3 Likes

I’m not exactly sure what you’re referring to by the ladder, if you could specify, that would be appreciated.

1 Like

oh, sorry. its a way to refer to “the other option”, the last option. in this case, I was saying he probably meant it wasn’t synced. my bad :sob:

4 Likes

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)

1 Like

i mean it rewards in the exact time but its the ui countdown are not sycned

OHHHHH mb
hol up
30cahractersletsgooooo

this is the best solution so fat but it adds up instead of decreasing it

but i think this will be an easy fix thank you very much :slight_smile:

most likely change the two occurences of math.floor(os.time() - startingTime) to math.floor(os.time() - startingTime) - 5

im not sure if dat helps but i hope it does

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

yeah its adding up till the time is finished, like 1, 2, 3, 4, 5 etc… till 1 minute instead of 59, 58, 57, etc…

mb lemme see if i can fix dat real quick

1 Like

replace formatTime((math.floor(os.time() - startingTime))) with formatTime(seconds - (math.floor(os.time() - startingTime)))

2 Likes

You are the best my guy thank you very mucho :slight_smile:

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.