DataStore2 Not Saving Only for Certain Functions

I’ve recently come across a bug in my code that is preventing my daily login bonus from saving its added values. I am using DataStore2 and it has worked alright until now. For some reason, I am able to add experience from other functions in the game, but when I add experience using the daily login bonus it doesn’t save. I’ve even put in a print statement to test if the value is saved and it appears as though it has.

--My Experience Adder Script
function XPperLevel(level)
	local XPNeeded = 1000 + 500 * level
	return XPNeeded
end
local xpdebounces = {}
game.ServerStorage.AwardXP.Event:Connect(function(plr, experiencegiven)
	while xpdebounces[plr] == true do
		wait(1)
	end
	xpdebounces[plr] = true
	local xpStore = DataStore2("xp", plr)
	local levelStore = DataStore2("level", plr)
	local levelold = levelStore:Get(1)
	local level = levelold
	local xp = xpStore:Get(0)
	game.ReplicatedStorage.RemoteEvents.AddXP:FireClient(plr, experiencegiven, xp)
	if not plr then
		xpdebounces[plr] = false
		return false
	end
	xpStore:Increment(experiencegiven)
	local xp = xpStore:Get(0)
	print('newxp is', xp)
	local XPNeeded = XPperLevel(level)
	while xp > XPNeeded do --while player's xp is greater than needed to level up
        local LeftOverXP = xp-XPperLevel(level) --calculate amt left over
		levelStore:Increment(1) --level + 1
		level = level + 1
		plr.Level.Value = level
        xpStore:Increment(-XPNeeded) --player's xp set to leftover
		xp = xp - XPNeeded
		plr.XP.Value = xp
		XPNeeded = XPperLevel(level)
	end
    if xp == XPperLevel(level) then
        levelStore:Increment(1)
		level = level + 1
		plr.Level.Value = level
        xpStore:Increment(-XPperLevel(level))
		xp = xp - XPperLevel(level)
		plr.XP.Value = xp
	end
	if levelold < level then
		game.ServerStorage.UpdateOverhead:Fire(plr)
	end
	xpdebounces[plr] = false
	return
end)


--My line to initiate this in the claim reward script

game.ServerStorage.AwardXP:Fire(player, game.ReplicatedStorage.ClientResources.Rewards['Day' .. (lastreward + 1)].XP.Value)


--A line that updates experience but also saves it
game.ServerStorage.AwardXP:Fire(players[i], game.ServerStorage.XPPerWin.Value)

In the end I’m just confused about what could cause the actual DataStore2 value to update for both of the functions, but then only remain upon login for one of the functions?

Edit: Here is the rest of my code in the server-side login reward manager

local ServerScriptService = game:GetService("ServerScriptService")
local DataStore2 = require(ServerScriptService.DataStore2)

local debounces = {}
function claimReward(player)
	if debounces[player] == true then return end
	debounces[player] = true
	local newtime = os.time()
	if (newtime - game.Players[player.Name].lastreward.Value)/60/60 < 24 then
		debounces[player] = false
		return false
	elseif (newtime - game.Players[player.Name].lastreward.Value)/60/60 > 24 then
		local loginStore = DataStore2("dailylogin", player)
		local lastrewardtime = loginStore:Get(0)
		local rewardsStore = DataStore2("numrewardsclaimed", player)
		local lastreward = rewardsStore:Get(0)
		if newtime - lastrewardtime < 86400 then
			game.Players[player.Name].lastreward.Value = lastrewardtime
			debounces[player] = false
			return false
		elseif newtime - lastrewardtime > 86400 then
			loginStore:Increment(newtime - lastrewardtime)
			game.Players[player.Name].lastreward.Value = newtime
			if lastreward == 4 then
				game.ServerStorage.AwardCredits:Invoke(player, game.ReplicatedStorage.ClientResources.Rewards.Day5.Ice.Value)
				game.ServerStorage.AwardXP:Fire(player, game.ReplicatedStorage.ClientResources.Rewards.Day5.XP.Value)
				game.Players[player.Name].rewardsclaimed.Value = 0
				rewardsStore:Increment(-4)
				debounces[player] = false
				return true
			else
				game.ServerStorage.AwardCredits:Invoke(player, game.ReplicatedStorage.ClientResources.Rewards['Day' .. (lastreward + 1)].Ice.Value)
				---------ADDING THE EXPERIENCE FROM THE DAILY LOGIN BONUS HERE VVVV----------------
				game.ServerStorage.AwardXP:Fire(player, game.ReplicatedStorage.ClientResources.Rewards['Day' .. (lastreward + 1)].XP.Value)
				rewardsStore:Increment(1)
				game.Players[player.Name].rewardsclaimed.Value = game.Players[player.Name].rewardsclaimed.Value + 1
				debounces[player] = false
				return true
			end
		end
	end
end

game.ReplicatedStorage.RemoteFunctions.ClaimReward.OnServerInvoke = function(player)
	claimReward(player)
end

Edit2: I tried changing the key, but that didn’t do anything. I also experimented some more and found that when the experience from the daily login bonus is added, it just appears as though it’s added. Everything runs as though it’s added. But then when more experience is added from other sources, it reverts back to what it was. The attached screenshot shows what the console looks like for the corresponding print statements. The first part is adding the daily login bonus experience, then adding other experience which adds to the old value because it didn’t actually update for the daily login or something.

3 Likes

Did you ever find a solution for this? I’m having a similar problem.
I’m no game programmer, but I know OOP for the web, so I have a little knowledge, but I’m constantly wondering if I’m building things wrong when it comes to game dev since issues like this stump me.

For my case, what’s happening is I have Oxygen which is reduced every 0.2s, and then I have Items which can be picked up. Both are stored in a combined datastore2 under ‘Oxygen’ and ‘Item’. I’m finding in some random cases the Item count is not incremented when picking them up. My output is the same, itemStore:Get() after incrementing returns that it has been incremented correctly, but on the next pickup its reverted back as though the last pickup never happened.

Completely disabling the Oxygen loop seems to fix the issue. I’ve tried putting the Oxygen loop in a coroutine or in a while loop at the end of the script, but in all cases when it’s updating at 0.2s I get this weird issue. The issue seems to go away if I set the interval to 1s but it may just be that it’s less likely to hit this oddity when it runs less frequently.

I’ve fixed it by moving Oxygen to a session variable (strangely, is how I understand datastore2 works before saving on player leave), since I didn’t actually need to store it, I only needed to store their max Oxygen. However I’m worried in future I WILL need to store something and update it very often and this is going to occur again, or even worse this will happen again in rare cases where multiple things are incrementing at the same time…

For now I’m proceeding cautiously and keeping this issue in mind

1 Like

I’m not 100% sure what my issue was, but I think it was that I was using :Get too often. To my knowledge, you can use :Increment as much as you want, but using :Get should be limited. I started just using a value stored under the player to base my Increments off of, with the OnUpdate function setting that player value to the new value, or just setting the player value right after incrementing. I agree with moving Oxygen to a session variable because it’s not something that needs to be saved across servers. I’m not sure how inefficient this is, but if your issues persist and you’re not able to save something that often, maybe you could run a server while loop to go through the players every 10 seconds or so and use :Set to update the Datastore2 values to the session values. Also, another issue I had that I didn’t know was causing so much of an issue is that I was using a Datastore2 key that wasn’t combined. It was glitched from being a previously used key and wouldn’t let me combine, so I had to make a new key and combine that one. If you have any more problems I’d be happy to look over your code.

Edit: I’m not actually sure that’s how :Get works after reading the documentation, but it’s worth a shot I guess. It’s most likely uncombined keys if I was to guess.

1 Like