Consecutive daily rewards

local LastLogin = RewardDataStore:GetAsync(player.UserId)
	
	local Streak = LastLogin.Streak or 0 -- error
			
	if LastLogin then
		local Seconds = os.time() - LastLogin
		local Minutes = Seconds / 60
		local Hours = Minutes / 60
		
		local StreakAwards = {50, 100, 250, 500, 1000}
		local Streak = LastLogin.Streak
		
		Streak = Streak + 1
		
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = LastLogin

		RewardDataStore:SetAsync(player.UserId, Data)
	end

[attempt to index local ‘LastLogin’ (a nil value)

What returns the error? LastLogin? Or streak?

Well Lastlogin doesn’t exist

local LastLogin = RewardDataStore:GetAsync(player.UserId)
	
local Streak = LastLogin.Streak or 0

If the player hasn’t previously played and had data saved then LastLogin returns nil

In that case, you could do

if LastLogin ~= nil then
    --code here
else
    --do nothing
end
local LastLogin = RewardDataStore:GetAsync(player.UserId)
			
	if LastLogin then
		local Seconds = os.time() - LastLogin
		local Minutes = Seconds / 60
		local Hours = Minutes / 60
		
		local StreakAwards = {50, 100, 250, 500, 1000}
		local Streak = LastLogin.Streak
		
		Streak = Streak + 1
		
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = LastLogin

		RewardDataStore:SetAsync(player.UserId, Data)
	else
		local StreakAwards = {50, 100, 250, 500, 1000}
		local Streak = LastLogin.Streak -- ERROR
		
		Streak = Streak + 1
		
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = LastLogin

		RewardDataStore:SetAsync(player.UserId, Data)
	end

[ attempt to index local ‘LastLogin’ (a nil value)]

Since LastLogin is nil, doing LastLogin.Streak is going to return an error.

Setting Streak to 1 instead of getting it from LastLogin will fix it.

Ok works the first time but if I rejoin it breaks

local LastLogin = RewardDataStore:GetAsync(player.UserId)
			
	if LastLogin then
		local Seconds = os.time() - LastLogin -- ERROR
		local Minutes = Seconds / 60
		local Hours = Minutes / 60
		
		local Streak = LastLogin.Streak
		
		Streak = Streak + 1
		
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = LastLogin

		RewardDataStore:SetAsync(player.UserId, Data)
	else
		local Streak = 1
				
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = LastLogin

		RewardDataStore:SetAsync(player.UserId, Data)
	end

[ attempt to perform arithmetic on local ‘LastLogin’ (a table value)]

Being that LastLogin is nil, setting Data.LastLogin to LastLogin makes it nil. You should set it to os.time(). That, and you have to do LastLogin.LastLogin to get the time.

Since LastLogin is now being set to a table value, holding both the time of their last arrival and they’re currently on, you need to Set LastLogin to

local LastLogin = [PickANewNameToReferenceTheKey].LastLogin

Still get same error on same line

local LastLogin = RewardDataStore:GetAsync(player.UserId)
			
	if LastLogin then
		local Seconds = os.time() - LastLogin -- ERROR
		local Minutes = Seconds / 60
		local Hours = Minutes / 60
		
		local Streak = LastLogin.Streak
		
		Streak = Streak + 1
		
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = LastLogin

		RewardDataStore:SetAsync(player.UserId, Data)
	else
		local Streak = 1
				
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = os.time()

		RewardDataStore:SetAsync(player.UserId, Data)
	end

[attempt to perform arithmetic on local ‘LastLogin’ (a table value)]

Do local Seconds = os.time() - LastLogin.LastLogin

Ok, now I can just join multiple times and get the rewards

local LoginData = RewardDataStore:GetAsync(player.UserId)
			
	if LoginData then
		local Seconds = os.time() - LoginData.LastLogin -- ERROR
		local Minutes = Seconds / 60
		local Hours = Minutes / 60
		
		local Streak = LoginData.Streak
		
		Streak = Streak + 1
		
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = os.time()

		RewardDataStore:SetAsync(player.UserId, Data)
	else
		local Streak = 1
				
		local Award = StreakAwards[Streak]
		if not Award then
			Award = StreakAwards[#StreakAwards]
		end

		UpdateCash(player, Award)
		DailyReward:FireClient(player, Streak, Award)

		local Data = {}
		Data.Streak = Streak
		Data.LastLogin = os.time()

		RewardDataStore:SetAsync(player.UserId, Data)
	end

So I join once, get reward one, join again get reward 2, etc. It’s not waiting a day

You need to check if the hours since last login is >= 24. Do

if Hours >= 24 then
    --code
end
1 Like
local DataStoreService = game:GetService('DataStoreService')
local RewardDataStore = DataStoreService:GetDataStore('RewardsDataStore', '001')

game.Players.PlayerAdded:connect(function(Player)
	local RewardData = RewardDataStore:GetAsync(tostring(Player.UserId))
	
	if typeof(RewardData) == "table" then
		local LastLogin = RewardData[1]
		local DaysInRow = RewardData[2]
		local Seconds = os.time() - LastLogin
		local Minutes = Seconds / 60
		local Hours = Minutes / 60
	
		if Hours >= 12 and Hours <= 36 then -- they logged in 12 to 36 hours since their last (change as you desire)
			RewardDataStore:SetAsync(tostring(Player.UserId), {os.time(), DaysInRow + 1})
			UpdateCash(Player, 50)
			DailyReward:FireClient(Player)
		end
	else
		RewardDataStore:SetAsync(tostring(Player.UserId), {os.time(), 0})
		UpdateCash(Player, 50)
		DailyReward:FireClient(Player)
	end
end)

This works. You need to check between X and Y hours. And it tracks how many days in a row, too!

3 Likes

Instead of using os.time(), I’d recommend you use tick(), because os.time() can be changed on the clients computer to something else.

…? This is being done on the server though. tick() returns the number of seconds since the UNIX Epoch in the server’s time zone, os.time() returns the number of seconds since the UNIX Epoch in UTC explicitly.

Why would you use tick over os.time? This is especially so when it’s on the server. If it’s on the client, then be it tick or os.time, the client can change what it returns easily.

4 Likes

This is false, it’s the other way around:

2 Likes

Use os.time() on server because different servers can be in different timezones - tick() is based on the local time of the machine that is running the script.

ohhhh, sorry about that…

30charslol

1 Like

You could add a Streak variable. Saving that along with LastLogin.
Each day add 1 to Streak then save. after 5 days reset it to 1 again just after the player receives their 5th day reward.

Rewards can be in a table like:
StreakRewards = {10, 20, 30, 40, 50}

using their streak to identify what index the day is like:
Streak = 3
print(StreakRewards[Streak]) – prints 30
use that to add to whatever.