Making a daily reward timer?

-- NinjoOnline --

print('start reward')

local rewardTime = 24*60*60

print('1')

local dataStoreService = game:GetService('DataStoreService')
local rewardDataStore = dataStoreService:GetDataStore('RewardsDataStore', 'Alpha')
local player = script.Parent.Parent.Parent.Parent.Parent.Parent.Parent
local lastLogin = rewardDataStore:GetAsync(player.UserId) or os.time()
print('2')
while true do
	print('3')
	while true do
		print('4')
	    local seconds = rewardTime - (os.time() - lastLogin)
	    if seconds <= 0 then 
			break 
		end
		print('1')
	    minutes = seconds/60
	    hours = minutes/60  
	    script.Parent.Text = ('Daily Reward: %.2d:%.2d:%.2d'):format(hours, minutes%(60), seconds%(60))
	    wait(1)
	end
	lastLogin = os.time()
end

Trying to create a timer that shows how long you have left till your next reward. Using this in a normal script. This works great in Play Solo but not in real games. When I run an online test, check the console, there’s no prints in either console or server

9 Likes

Server scripts won’t run correctly as a descendant of PlayerGui because of how they’re replicated from game.StarterGui. Best practice is to just not use them at all on the client, after all localscripts do exist.

1 Like

Yea, but cant access datastores from LocalScripts. I thought maybe using a remoteevent or something, but then it’d have to be fired every second, and would send different values, depending on the player. If I have 16 players all with different times for their respective rewards I thought it’d screw with a RemoteEvent.

You could achieve your desired result without spamming RemoteEvents by pinging the client with the time left until they receive their daily reward every time they respawn and then counting down based on that number from the client.

i.e

-- Server

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

	Player.CharacterAdded:Connect(function()
		
		Event:FireClient(Player, timeleft)
		
	end)

end)

-- Client

Event.OnClientEvent:Connect(function(timeleft)

   -- Display countdown based on time sent

end)

Additionally once the time left on the client reaches 0 you could request the server sends the time again, that way it updates without having to respawn.

Edit: extra info

2 Likes

You should save the last os.time() they received their award in a datastore, and cache that information on the client when they join the game. Then you can take os.time() - lastRewardTime to get how long it’s been since they received their last reward. Then to calculate time left to their next reward you take max(timeBetweenRewards - timeSince, 0).

os.time is given in seconds.

1 Like

os.time() should be used, not tick(). Tick uses local time while os uses UTC (It’ll be the same across different servers)

1 Like

Edited post, thank you.

How do I get it to fire when the player respawns tho? Atm I’ve got this:

-- NinjoOnline --

local rewardTime = 24*60*60

local replicatedStorage = game:GetService('ReplicatedStorage')
local events = replicatedStorage:WaitForChild('Events')
local dailyRewardTime = events:WaitForChild('DailyRewardTime')

dailyRewardTime.OnClientEvent:Connect(function(login)
	lastLogin = login
end)

while true do
	while wait() do
		if lastLogin then
		    local seconds = rewardTime - (os.time() - lastLogin)
		    if seconds <= 0 then 
				break 
			end
		    minutes = seconds/60
		    hours = minutes/60  
		    script.Parent.Text = ('Daily Reward: %.2d:%.2d:%.2d'):format(hours, minutes%(60), seconds%(60))
		    wait(1)
		end
	end
end

And the remoteevent fires when the lastLogin has been determined the server. So it works when you join, but when you reset it does nothing.

player.CharacterAdded:Connect(function(character)
    if character then
		print('1')
		if lastLogin then
			print('2')
			dailyRewardTime:FireClient(player, lastLogin)
		end
    end
end)

It prints 1 and 2 too early. I figured if I had the if Character then it would wait until the player has respawned and character loaded before firing any further, but no, just fires as soon as you die. Tried it in a Died function too, same thing. Even with a repeat wait() until player.Character

1 Like

as per our dm exchange the issue you’re experiencing should be fixed (letting people know so no additional replies are sent)

Why did discussion need to be moved to private messages? These threads can be helpful for other users experiencing the same (or similar) issue, but not when discussion happens elsewhere.

5 Likes

In the future please don’t do this. The forums are a community resource. It would be great if OP could share the solution.

8 Likes