Daily Reward Timer Bugged when Claiming

Hey guys,

Whenever a player opts to collect from my daily reward GUI, a related textlabel shows its typical text (yellow) but an unusual number. However, when the player rejoins, the number is what should be expected (e.g., 23 hours left). To resolve this issue, I would like the textlabel to show the player has 24 hours remaining. I have attached some media to illustrate this issue:

image

Server Script:

game.Players.PlayerAdded:Connect(function(Player)

local CurrentTime = os.time()

		pcall(function()
			Data = DataStore:GetAsync(Player.UserId.."-DailyReward")
		end)
		
		local RewardsDataStore = game:GetService("DataStoreService"):GetDataStore("DailyRewards")
		
		local TimeSinceLastClaim = CurrentTime - Data -- Number of seconds since last reward was claimed
		Duration = 24 -- Hours
		RewardsTable = {20, 20, 20, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 75, 75, 75, 100, 100, 200, 1000}
		
		if (TimeSinceLastClaim / 3600) >= Duration then
			local Reward = RewardsTable[math.random(1, #RewardsTable)]
			game.ReplicatedStorage.PresentDailyReward:FireClient(Player, Duration, Reward, true, TimeSinceLastClaim)

			local Connection 
			Connection = game.ReplicatedStorage.ClaimDailyReward.OnServerEvent:Connect(function(RequestingPlayer)
				if RequestingPlayer == Player then
					Player.Credits.Value = Player.Credits.Value + Reward
					DataStore:SetAsync(Player.UserId.."-DailyReward", os.time())
					Connection:Disconnect() -- Prevents Player from constantly triggering Daily Reward Button and receiving rewards
				end 
			end)
		else
			game.ReplicatedStorage.PresentDailyReward:FireClient(Player, Duration, RewardsTable[math.random(1, #RewardsTable)], false, TimeSinceLastClaim)
		end
	else
		local Reward = RewardsTable[math.random(1, #RewardsTable)]
		game.ReplicatedStorage.PresentDailyReward:FireClient(Player, Duration, Reward, true, 0)
		local Connection 
		Connection = game.ReplicatedStorage.ClaimDailyReward.OnServerEvent:Connect(function(RequestingPlayer)
			if RequestingPlayer == Player then
				Player.Credits.Value = Player.Credits.Value + Reward
				DataStore:SetAsync(Player.UserId.."-DailyReward", os.time())
				Connection:Disconnect() -- Prevents Player from constantly triggering Daily Reward Button and receiving rewards
			end 
		end)
	end

-- End of block

Local Script:

local ShopGUI = script.Parent
local DailyRewardScreen = ShopGUI.Shop.Home.DailyReward
local CollectButton = DailyRewardScreen.Collect
local Time = DailyRewardScreen.Time

game.ReplicatedStorage.PresentDailyReward.OnClientEvent:Connect(function(Duration, Reward, CanBeClaimed, TimeLeft)
	local RoundedTime = math.round((TimeLeft / 60) / 60)
	if CanBeClaimed == true then
		Time.Text = "Daily Reward Available!"
		CollectButton.MouseButton1Click:Connect(function()
			game.ReplicatedStorage.ClaimDailyReward:FireServer()
			Time.TextColor3 = Color3.new(255, 255, 0)
			Time.Text = "Awarded "..Reward.." credits"
			task.wait(5)
			Time.TextColor3 = Color3.new(255, 255, 255)
			Time.Text = "Next reward in ".. Duration - RoundedTime.." hours"
		end)
	else
		Time.Text = "Next reward in ".. Duration - RoundedTime.." hours"	
	end
end)

Your error is on client-side where you’re displaying the hour value.
When you click collect button, you’re still using old value of TimeLeft variable.
After sending RemoteEvent to the server to claim the reward, set TimeLeft variable to 0. Also I recommend naming your variables correctly, so as you used on your server side TimeSinceLastClaim.

Also it is strongly recommended to use DateTime.now().UnixTimestamp instead of os.time(), because Roblox servers are in different locations all the time and os.time() uses local server time, which is also time in that region. So if player claims reward in USA, and then connects to the server in Asia, the remaining time could be 8 hours instead of 24 (If USA is -8 timezone and Asia is +8 timezone). DateTime.now().UnixTimestamp will use UTC timezone which is centralized time and will always be same in any location of the world.

1 Like

Makes sense.

I have made the recommended change to set the TimeSinceLastClaim variable to 0 in my Server Script but the GUI displays the text as “-24”. Most likely an incorrect placement or we are missing something.

Here is the code block for critique:

			local Connection 
			Connection = game.ReplicatedStorage.ClaimDailyReward.OnServerEvent:Connect(function(RequestingPlayer)
				if RequestingPlayer == Player then
					Player.Credits.Value = Player.Credits.Value + Reward
					DataStore:SetAsync(Player.UserId.."-DailyReward", DateTime.now().UnixTimestamp)
					Connection:Disconnect()
					TimeSinceLastClaim = 0 ----------------- Here
				end 
			end)
		else
			game.ReplicatedStorage.PresentDailyReward:FireClient(Player, Duration, RewardsTable[math.random(1, #RewardsTable)], false, TimeSinceLastClaim)
		end
	else
		local Reward = RewardsTable[math.random(1, #RewardsTable)]
		game.ReplicatedStorage.PresentDailyReward:FireClient(Player, Duration, Reward, true, 0)
		local Connection 
		Connection = game.ReplicatedStorage.ClaimDailyReward.OnServerEvent:Connect(function(RequestingPlayer)
			if RequestingPlayer == Player then
				Player.Credits.Value = Player.Credits.Value + Reward
				DataStore:SetAsync(Player.UserId.."-DailyReward", DateTime.now().UnixTimestamp)
				Connection:Disconnect()
				TimeSinceLastClaim = 0 ----------------- and here
			end 
		end)
	end

I meant that you should change it in your client script.
Exactly this part:

game.ReplicatedStorage.ClaimDailyReward:FireServer()
RoundedTime = 0 -- Added line, we can reset it to 0 since we've claimed the reward
Time.TextColor3 = Color3.new(255, 255, 0)
Time.Text = "Awarded "..Reward.." credits"
task.wait(5)
Time.TextColor3 = Color3.new(255, 255, 255)
Time.Text = "Next reward in ".. Duration - RoundedTime.." hours"
1 Like

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