Data Saving Issues

In my game if you have a piece of clothing that you have to buy with in game currency it gives you a stat boost by 1.3x The only issue is that when the player leaves i have to take away the boost by /1.3 in order for it not to dupe when the player joins back. This Block Of Code Here Is The Issue, The problem is that I dont know how to make it to where if it doesnt find the clothing piece it doesnt return an error and forget about the rest of the script. If I simply do if not findfirstchild then return end, then the script will just end before it can save the players stuff. What do I do?

	if plr.Character:FindFirstChild("LuffyPants") then
		plr.Stats.Mana.Value = plr.Stats.Mana.Value / 1.3
		if plr.Character:FindFirstChild("LuffyShirt")  then
			plr.Stats.Sword.Value = plr.Stats.Sword.Value / 1.3
			if plr.Character:FindFirstChild("StrawHat")  then
				plr.Stats.Defense.Value = plr.Stats.Defense.Value / 1.3
				if plr.Character:FindFirstChild("ZoroShirt") then
					plr.Stats.Sword.Value = plr.Stats.Sword.Value / 1.3
					if plr.Character:FindFirstChild("ZoroPants") then
						plr.Stats.Defense.Value = plr.Stats.Defense.Value / 1.3	
						DS:SetAsync("id_"..plr.userId,{plr.leaderstats.Gold.Value, plr.Leaderstats.XP.Value,plr.Stats.Defense.Value,plr.Stats.Points.Value,plr.Stats.Sword.Value,plr.Stat
Mana.Value})
					end
				end
			end
		end
	end
end)```
1 Like

I’m not sure if I’m understanding this correctly but could you not just check each one individually and save at the end regardless?

if plr.Character:FindFirstChild("LuffyPants") then
    plr.Stats.Mana.Value = plr.Stats.Mana.Value / 1.3
end

if plr.Character:FindFirstChild("LuffyShirt")  then
    plr.Stats.Sword.Value = plr.Stats.Sword.Value / 1.3
end

if plr.Character:FindFirstChild("StrawHat")  then
    plr.Stats.Defense.Value = plr.Stats.Defense.Value / 1.3
end

if plr.Character:FindFirstChild("ZoroShirt") then
    plr.Stats.Sword.Value = plr.Stats.Sword.Value / 1.3
end

if plr.Character:FindFirstChild("ZoroPants") then
    plr.Stats.Defense.Value = plr.Stats.Defense.Value / 1.3 
end

DS:SetAsync(
    "id_"..plr.userId,
    {
        plr.leaderstats.Gold.Value,
        plr.Leaderstats.XP.Value,
        plr.Stats.Defense.Value,
        plr.Stats.Points.Value,
        plr.Stats.Sword.Value,
        plr.StatMana.Value
    }
)
2 Likes

I just tried it and it says " ServerScriptService.SaveData:26: attempt to index nil with ā€˜FindFirstChild’" line 26 is the first line of ur script. I think it has an error since it cant find a luffyshirt (just an example)

Your Character must be nil, you could try something like this although I think a better solution would be to consider using the PlayerRemoving / CharacterRemoving events.

local character = plr.Character or plr.CharacterAdded:wait()

if character:FindFirstChild("LuffyPants") then
    plr.Stats.Mana.Value = plr.Stats.Mana.Value / 1.3
end

if character:FindFirstChild("LuffyShirt")  then
    plr.Stats.Sword.Value = plr.Stats.Sword.Value / 1.3
end

if character:FindFirstChild("StrawHat")  then
    plr.Stats.Defense.Value = plr.Stats.Defense.Value / 1.3
end

if character:FindFirstChild("ZoroShirt") then
    plr.Stats.Sword.Value = plr.Stats.Sword.Value / 1.3
end

if character:FindFirstChild("ZoroPants") then
    plr.Stats.Defense.Value = plr.Stats.Defense.Value / 1.3 
end

DS:SetAsync(
    "id_"..plr.userId,
    {
        plr.leaderstats.Gold.Value,
        plr.Leaderstats.XP.Value,
        plr.Stats.Defense.Value,
        plr.Stats.Points.Value,
        plr.Stats.Sword.Value,
        plr.StatMana.Value
    }
)

https://developer.roblox.com/en-us/api-reference/event/Players/PlayerRemoving

https://developer.roblox.com/en-us/api-reference/event/Player/CharacterRemoving

1 Like

It still doesnt work but this time there isnt any error when someone leaves, but it have a warning saying ā€œdatastore inventory wont save as it was not updatedā€. Also I did play a little so there would be values the data store would need to save such as gold and xp. What also might help us to figure this out is that the data WILL save but because of that block of code tracking if the player has the clothing the data wont save and I don’t know how to make it to where: a) it tracks and divides the stat boosts correctly b) it saves the data AFTER the dividing of the stat boosts.

Update: I put your script inside another script and it works as intended. The only problem is the mana isnt saving and I did fix the typo you put. Is there any way to lighten the load on the datastore.

It could depend on the Mana value, if its 1 then 1 divided by 1.3 is 0.7 but I’m not too sure actually if Roblox supports saving decimals so all you could do is round it to the nearest whole number and then save it like that.

I knew this so I increased my stat by 1000 as a baseline and when i would leave and join back (in the real game not studio) the mana value would always return to 0.

Try rounding the number to a whole number before leaving.

This didn’t work sadly. But I got this warning saying DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests.Key. I think im overloading the datastore so i will look at another post to see if i can find a way to ease the load off the datastore.

I’m not a big fan of this implementation. I think a better approach would be to have a separate NumberValue for boosts which you would initialize when the player joins (no need to take it away when they leave), that way you only have to save the actual stat value without multiplying or dividing by some sorts of boosts.

try this

local function IsHere(v)
    return plr.Character:FindFirstChild(v)
end

if IsHere("LuffyShirt") or IsHere("ZoroShirt") then
     plr.Stats.Sword.Value /= 1.3
end

if IsHere("StrawHat") or IsHere("ZoroPants") then
     plr.Stats.Defense.Value /= 1.3
end

if IsHere("LuffyPants") then
     plr.Stats.Mana.Value /= 1.3
end

DS:SetAsync("id_"..plr.userId,{plr.leaderstats.Gold.Value, plr.Leaderstats.XP.Value,plr.Stats.Defense.Value,plr.Stats.Points.Value,plr.Stats.Sword.Value,plr.Stats.Mana.Value})

I didnt work unfortunately, ill put the entire script so you could help me find the problem. The stats are saving but if i leave and join back the mana is = 0 but everything else is saved properly then i leave and join back and my sword stat = 0 i leave and join back again but this time it doesnt make my health stat = 0. So the problem is no longer saving it is now wiping my entire data for a stat. Keep in mind this didn’t happen with just your script it happened with other peoples as well. Edit: The script itself works only if all that stuff about findfirstchild gets deleted.

game.Players.PlayerAdded:Connect(function(plr)
	wait(2)
	local plrkey = "id_"..plr.userId
	local save1 = plr.leaderstats.Gold
	local save2 = plr.Leaderstats.XP
	local save3 = plr.Stats.Defense
	local save4 = plr.Stats.Points
	local save6 = plr.Stats.Sword
	local save7 = plr.Stats.Mana
	local GetSaved = DS:GetAsync(plrkey)
	if GetSaved then
		save1.Value = GetSaved[1]
		save2.Value = GetSaved[2]
		save3.Value = GetSaved[3]
		save4.Value = GetSaved[4]
		save6.Value = GetSaved[6]
		save7.Value = GetSaved[7]
	else
		local NumberForSaving = {save1.Value, save2.Value, save3.Value, save4.Value, save6.Value,save7.Value}
		DS:GetAsync(plrkey, NumberForSaving)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	local function IsHere(v)
		return plr.Character:FindFirstChild(v)
	end

	if IsHere("LuffyShirt") or IsHere("ZoroShirt") then
		plr.Stats.Sword.Value /= 1.3
	end

	if IsHere("StrawHat") or IsHere("ZoroPants") then
		plr.Stats.Defense.Value /= 1.3
	end

	if IsHere("LuffyPants") then
		plr.Stats.Mana.Value /= 1.3
	end

	DS:SetAsync("id_"..plr.userId,{plr.leaderstats.Gold.Value, plr.Leaderstats.XP.Value,plr.Stats.Defense.Value,plr.Stats.Points.Value,plr.Stats.Sword.Value,plr.Stats.Mana.Value})
end)```

Ill consider this if I cant get my current situation to work. Thanks for the advice!

try now

local Currency = {
	"Gold",
	"XP",
	"Defense",
	"Points",
	"Sword",
	"Mana"
}

game.Players.PlayerAdded:Connect(function(plr)
	wait(2)
	local plrkey = "id_"..plr.userId
	
	local GetSaved = DS:GetAsync(plrkey)
	
	if GetSaved then		
		for i = 1, #Currency do
			local FindCurrency = plr.leaderstats:FindFirstChild(i) or plr.Stats:FindFirstChild(i)	
			FindCurrency.Value = GetSaved[i]
		end	
	else
		local NumberForSaving = {}
		
		for i = 1, #Currency do
			local FindCurrency = plr.leaderstats:FindFirstChild(i) or plr.Stats:FindFirstChild(i)	
			NumberForSaving[i] = FindCurrency.Value
		end	
		
		DS:GetAsync(plrkey, NumberForSaving)
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
	local plrkey = "id_"..plr.userId
	
	local function IsHere(v)
		return plr.Character:FindFirstChild(v)
	end

	if IsHere("LuffyShirt") or IsHere("ZoroShirt") then
		plr.Stats.Sword.Value /= 1.3
	end

	if IsHere("StrawHat") or IsHere("ZoroPants") then
		plr.Stats.Defense.Value /= 1.3
	end

	if IsHere("LuffyPants") then
		plr.Stats.Mana.Value /= 1.3
	end
	
	local NumberForSaving = {}

	for i = 1, #Currency do
		local FindCurrency = plr.leaderstats:FindFirstChild(i) or plr.Stats:FindFirstChild(i)	
		NumberForSaving[i] = FindCurrency.Value
	end	
	
	DS:SetAsync(plrkey,NumberForSaving)
end)

Thanks so much! Have a nice life because you deserve it!

1 Like