Time on 12 hour chest is broken

A friend and I are working on a 12 hour chest reward. It doesn’t subtract time consistently and we don’t know what’s wrong.

Code:

local hourWait = 12

game.Players.PlayerAdded:Connect(function(plr)
    local leftTime = plr:WaitForChild("stats").DailyTime.Value
    local timeNow = os.time()

    if plr:WaitForChild("stats").DailyRewardTimer ~= nil then
        if plr:WaitForChild("stats").DailyTime ~= nil then
            local diff = timeNow - leftTime
            plr.stats.DailyRewardTimer.Value -= diff
            
            if (diff / 3600) >= hourWait then
                print("Reward Available")
            end
        end
    end
end)
1 Like

In your post description you say “It doesn’t subtract time consistently and we don’t know what’s wrong.” What exactly does that mean? Do you mean that the player doesn’t get their reward when their supposed to? Please elaborate.

For example, when you leave and the timer shows ‘11:34:19’, and you join back 15 seconds later, it’ll show ‘11:03:08’ instead of ‘11:34:04’.

assuming dailyTime.Value is the last time they claimed the chest, the line where you put plr.stats.DailyRewardTimer.Value -= diff should just set it to diff instead of subtracting diff from it.
I’m not totally sure how you’ve set this up, as you haven’t given us all of your code, but I will try to explain how I would go about doing this.

When the player claims a chest it should instantly take note of the current time (probably using dataStores). Then when a player joins in, the difference is join time - the last time they claimed. From there it works to set a value that keeps track of how much time is left directly to the difference instead of subtracting.
Keep in mind that you don’t have to save data every time they log in, just only when they claim the chest.
Hope this helps!

Hey I’m the friend he is talking abt, and dailyTime isn’t the last time claimed, it’s the last time they joined. Basically what we’re trying to do is make the daily chest timer go down for offline players.

The method i suggested actually does make it go down for offline players, as it subtracts the current time from the time of the last claim to always be accurate in how long they have to wait.

Essentially:
Player claims chest at 10:20:21
This causes some data to be set to 10:20:21 (in seconds from epoch time ofc)

Player joins in at 11:15:21
The data is loaded in, and the current time is subtracted from the data that was loaded in (the time of the claim) to get how much time is left until their next claim. No data is saved.

Player joins in at 13:18:33
The data is loaded in, and again, the current time is subtracted from the data that was loaded in to get the remaining time before their next claim. Again, no data is saved.

Player joins at 23:55:34
Once again, the data is loaded in and the current time is subtracted from the data. But this time it is greater than 12 * 3600, which means that 12 hours have passed and the chest is ready for claiming. Once they claim the chest you can finally save their data as the current time.

Now you see why I do it this way?

Ok i’ve looked at your original post and what you’re saying is I check when they claimed, but what I want is when the player joins it gets the last time they left(Which I have in a data store) then it subtracts that from their current time. I’m confused bc your system only relies on claiming beforehand, but not saving before leaving.

The reason it only relies on the time that they claimed is because that plus the current time is all you need to tell how much time until the player can claim again.

Time until next claim is [Current Time] - [Last Claim Time]

1 Like

I think @Lit_skillzYT is describing a system sort of like this:

Yes, that’s basically exactly what I mean.

So something like this?

game.Players.PlayerAdded:Connect(function(plr)
	local lastClaimed = plr:WaitForChild("stats").DailyTime.Value
	local timeNow = os.time()

	if plr:WaitForChild("stats").DailyRewardTimer ~= nil then
		if plr:WaitForChild("stats").DailyTime ~= nil then
			local diff = timeNow - lastClaimed
			plr.stats.DailyRewardTimer.Value -= diff
			
			if (diff / 3600) >= hourWait then
				print("Reward Available")
			end
		end
	end
end)

DailyChestZone.playerEntered:Connect(function(plr)
	if plr.stats.DailyRewardTimer.Value == 0 then
		plr:WaitForChild("stats").DailyTime.Value = os.time()
		
		plr.stats.DailyRewardTimer.Value = 43200
	else
		print("Not ready")
	end
end)

Yeah, I think that looks good. My only suggestion is that instead of using waitforchild(“stats”) multiple times you just set a variable like local stats = plr:WaitForChild(“Stats”).

Good luck on the rest of your game!

Thanks a lot! This helped, also got it working.

TimeTillNextClaim = ClaimDelay - (CurrentTime - TimeFromLastClaim)

Is the correct formula.

I mean no need for this as it works and this is just overcomplicating it.