BLOXBUILDS
Discord
Back
UI/UX

Daily Rewards

Split this at the SPLIT line. Paste the top into ServerScriptService as a Script and the bottom into StarterPlayerScripts as a LocalScript. A player can claim one streak reward every 24 hours. Enable Studio Access to API Services.

-- SERVER SCRIPT. Paste into ServerScriptService.
-- Enable Game Settings > Security > Enable Studio Access to API Services.

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local DAY = 24 * 60 * 60
local REWARDS = { 50, 75, 100, 150, 200, 300, 500 }
local store = DataStoreService:GetDataStore("DailyRewards")

local remote = ReplicatedStorage:FindFirstChild("ClaimDaily")
if not remote then
	remote = Instance.new("RemoteEvent")
	remote.Name = "ClaimDaily"
	remote.Parent = ReplicatedStorage
end

local function getCash(player: Player): IntValue
	local leaderstats = player:FindFirstChild("leaderstats")
	if not leaderstats then
		leaderstats = Instance.new("Folder")
		leaderstats.Name = "leaderstats"
		leaderstats.Parent = player
	end
	local cash = leaderstats:FindFirstChild("Cash")
	if not cash then
		cash = Instance.new("IntValue")
		cash.Name = "Cash"
		cash.Value = 0
		cash.Parent = leaderstats
	end
	return cash :: IntValue
end

local function key(player: Player): string
	return "daily_" .. player.UserId
end

local function readData(player: Player)
	local ok, data = pcall(function()
		return store:GetAsync(key(player))
	end)
	if ok and typeof(data) == "table" then
		return data
	end
	return { last = 0, streak = 0 }
end

remote.OnServerEvent:Connect(function(player)
	local data = readData(player)
	local now = os.time()
	if data.last and now - data.last < DAY then
		remote:FireClient(player, false, data.streak or 0, DAY - (now - data.last))
		return
	end

	local streak = 1
	if data.last and now - data.last < DAY * 2 then
		streak = (data.streak or 0) + 1
	end
	if streak > #REWARDS then
		streak = 1
	end

	local reward = REWARDS[streak]
	getCash(player).Value += reward
	pcall(function()
		store:SetAsync(key(player), { last = now, streak = streak })
	end)
	remote:FireClient(player, true, streak, reward)
end)

-- SPLIT
-- LOCAL SCRIPT. Paste into StarterPlayer > StarterPlayerScripts.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = Players.LocalPlayer
local remote = ReplicatedStorage:WaitForChild("ClaimDaily")
local gui = Instance.new("ScreenGui")
gui.Name = "DailyRewards"
gui.ResetOnSpawn = false
gui.Parent = player:WaitForChild("PlayerGui")

local frame = Instance.new("Frame")
frame.AnchorPoint = Vector2.new(0.5, 0.5)
frame.Position = UDim2.fromScale(0.5, 0.5)
frame.Size = UDim2.fromOffset(320, 180)
frame.BackgroundColor3 = Color3.fromRGB(19, 22, 28)
frame.Parent = gui

local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -24, 0, 36)
title.Position = UDim2.fromOffset(12, 16)
title.BackgroundTransparency = 1
title.Text = "Daily Reward"
title.TextColor3 = Color3.new(1, 1, 1)
title.Font = Enum.Font.GothamBold
title.TextSize = 22
title.Parent = frame

local status = Instance.new("TextLabel")
status.Size = UDim2.new(1, -24, 0, 48)
status.Position = UDim2.fromOffset(12, 56)
status.BackgroundTransparency = 1
status.Text = "Claim today's coins."
status.TextColor3 = Color3.fromRGB(148, 163, 184)
status.Font = Enum.Font.Gotham
status.TextSize = 16
status.TextWrapped = true
status.Parent = frame

local claim = Instance.new("TextButton")
claim.Size = UDim2.new(1, -24, 0, 36)
claim.Position = UDim2.fromOffset(12, 124)
claim.BackgroundColor3 = Color3.fromRGB(99, 102, 241)
claim.Text = "Claim"
claim.TextColor3 = Color3.new(1, 1, 1)
claim.Font = Enum.Font.GothamBold
claim.TextSize = 16
claim.Parent = frame

claim.MouseButton1Click:Connect(function()
	remote:FireServer()
end)

remote.OnClientEvent:Connect(function(granted, streak, amountOrWait)
	if granted then
		status.Text = "Day " .. streak .. " claimed: " .. amountOrWait .. " coins."
	else
		local hours = math.ceil(amountOrWait / 3600)
		status.Text = "Come back in about " .. hours .. " hours. Streak " .. streak .. "."
	end
end)