and I’ve finished working on daily reward chests,respawn products, and more, now all I need is to create a timer/countdown that shows how long you have left till your next reward.
This is my script so far :
local DataStore = game:GetService("DataStoreService"):GetDataStore("DailyReward")
local TimePeriod = 24*60^2 -- ==>> 86400 (1 DAY)
game.Players.PlayerAdded:Connect(function(plr)
local currenttime = os.time()
local RecordedPreviousTime = DataStore:GetAsync(plr.userId)
if RecordedPreviousTime then
if type(RecordedPreviousTime) == "number" then
timeelapsed = currenttime - RecordedPreviousTime
if timeelapsed >= TimePeriod then
if not workspace.Reward:FindFirstChild("Chest") then
DataStore:SetAsync(plr.userId, os.time())
RewardEvent(plr)
end
end
end
end
game:BindToClose(function()
DataStore:SetAsync(plr.userId, os.time())
end)
end)
game.Players.PlayerRemoving:Connect(function(plr)
DataStore:SetAsync(plr.userId, os.time())
end)
local Timer = workspace.Timer.Timer.Ui.Frame.Timer
while wait(1) do
--[[
I AM STUCK HERE :(
]]--
end
Btw I DONT REALLY KNOW HOW TO USE OS.TIME() AND STORING IT,SO PLEASE DON’T BULLY ME.
I don’t get why are you storing the os.time() on PlayerRemoving and after the server’s closure. Doesn’t that obbligate the player to stay online for an entire day?
Also, in case where there isn’t a RecordedPreviousTime, shouldn’t the player be able to get the chest, since it’s their first login?
You can use this article to learn more about os.time().
I think what you want to do is to only store the RecordedPreviousTime when the player gets their reward.
As for the timer, you can use math.max(TimePeriod - (os.time() - RecordedPreviousTime), 0) to calculate the amount of seconds left until the next reward is available, and then you can format that to any pattern you’d like (such as HH:MM:SS).
For the section you were struggling with, all you need to do is:
while wait(1) do
Timer.Text = os.difftime(RecordedPreviousTime, os.time())
end
However, you may want to change the previous part of the script to make it a bit more reliable. DataStores have a notorious reputation for errors and a throttle on requests so I would recommend having a retry system. Obviously, it won’t help if it fails all of the retries.
Keep in mind that:
GetAsync has a limit of 60 + (Number of players * 10)
Write requests (SetAsync, IncrementAsync, UpdateAsync and RemoveAsync) have a collective limit of 60 + (Number of players * 10)
Write requests (for the same key in a datastore) must have a 6 second gap between them.
GetSortedAsync has a limit of 5 + (Number of players × 2)
I personally do this for general usage:
local RetryInterval = 0.05 -- This can be anything above 0.03
local MaximumRetries = 3 -- This can be anything
local function SetAsync(DataStore, Key)
local Tries = 0
local Success
repeat
Tries = Tries + 1
Success = pcall(function()
DataStore:SetAsync(Key)
end)
if not Success then wait(RetryInterval) end
until Tries == MaximumRetries or Success
if not Success then
warn("Error processing SetAsync.")
end
end
local RetryInterval = 0.05
local MaximumRetries = 3
game.Players.PlayerAdded:Connect(function(plr)
currenttime = os.time()
RecordedPreviousTime = DataStore:GetAsync(plr.userId)
local function SetAsync(DataStore, Key)
local Tries = 0
local Success
repeat
Tries = Tries + 1
Success = pcall(function()
DataStore:SetAsync(Key)
end)
if not Success then
wait(RetryInterval)
end
until Tries == MaximumRetries or Success
if not Success then
warn("Error processing SetAsync.")
end
end
if RecordedPreviousTime then
if type(RecordedPreviousTime) == "number" then
local timeelapsed = currenttime - RecordedPreviousTime
if timeelapsed >= TimePeriod then
if not workspace.Reward:FindFirstChild("Chest") then
SetAsync(plr.userId, timeelapsed)
RewardEvent(plr)
end
end
end
end
end)
local Timer = workspace.Timer.Timer.Ui.Frame.Timer
while wait(1) do
Timer.Text = "Next Chest In : " .. os.difftime(RecordedPreviousTime, currenttime)
end
but output send me this : '[invalid argument #1 to 'difftime' (number expected, got nil)])'