Roblox daily rewards script with a login streak
Short answer
Save the last claimed day as a UTC day number (os.time() // 86400) and the current streak. When a player claims: if today equals the last day, refuse; if it is the next day, add 1 to the streak; otherwise reset the streak to 1. Do it all on the server.
Copy-paste code
Daily reward logic (server)
local REWARDS = { 50, 75, 100, 150, 200, 300, 500 } -- day 1..7, then repeats
-- data = the player's saved profile table (see the DataStore guide)
local function claimDaily(data)
local today = os.time() // 86400 -- UTC day number
if data.lastDay == today then
return false, "Already claimed today"
end
if data.lastDay == today - 1 then
data.streak = (data.streak or 0) + 1
else
data.streak = 1
end
data.lastDay = today
local reward = REWARDS[(data.streak - 1) % #REWARDS + 1]
data.coins = (data.coins or 0) + reward
return true, reward
end
-- RemoteFunction the claim button calls
game.ReplicatedStorage.ClaimDaily.OnServerInvoke = function(player)
local data = profiles[player] -- from your data script
if not data then return false, "Loading" end
return claimDaily(data)
endGood to know
Use os.time() on the server, never a time sent by the client: a player can change their device clock.
Show the countdown to the next claim with (today + 1) * 86400 - os.time() seconds.
Studwright: Roblox systems that never lose saves
from $12Studwright includes tested DailyRewards and PlaytimeRewards modules, saved by its session-locked SaveData, plus 13 more systems.
Secure checkout · 14-day fix-or-refund if it doesn't work as described (terms)Questions
Why use UTC day numbers?
Everyone's day changes at the same moment and there is no time-zone or daylight-saving bug.
Can players claim twice by rejoining?
No, as long as lastDay is saved with the profile before they can rejoin; that is why the claim changes the saved data directly.
Free: the Roblox Starter Kit
7 free Luau modules (damage, pets, shop formatting, admin audit log, tycoon guards and more) plus 3 free calculators, then 5 short emails with the scripting fixes we see go wrong most often.