Datastore Preset Values Are Being Ignored?

Issue:

I have a game datastore which handles all important elements of my game, including, but not limited to, number, values, strings, and booleans. The issue is, despite the datastore script not erroring, it always sets each value to 0 when the data is fetched from each datastore. This is annoying as due to this, it’s affecting other elements of my game.

For more detail:

The most relevant part of the code (which is causing the issue), is here:

if data ~= nil  and owned ~= nil then
			local module = require(game.ServerStorage.ModuleScript)
			spleefCoins.Value = data[1] 
			wins.Value = data[2]
			benefits.Value = data[3] or 1
			Levels.Value = data[4] or 1
			XP.Value = data[5] or 0
			XP_Limit.Value = data[6] or 30
			CRW.Value = data[7] or false
			rank.Value = data[8] or "Newbie"
			Equipped.Value = data[9] or "1"
			EquippedEffect.Value = data[10] or "1"			
			ownedPlaceHolder = owned

As you can see, to handle situations when returned data is nil, I have “or” arguments for the most important ones.

I was expecting, even if the data was to fail, for the preset values to be put in place, but that doesn’t work, with proof it saying that my Level is 0 even though it is supposed to be 1.

I have no idea what could be causing this and I’ve looked over the datastoreHandler countless times.

Help much appreciated

Full Code:

local DS = game:GetService("DataStoreService") --- Gets Datastore Service
local CSS = DS:GetDataStore("ChaosSpleefStore_6")
local OwnedDatastore = DS:GetDataStore("OwnedDatastore_7")
local OwnedTrailsDatastore = DS:GetDataStore("OwnedDatastoreTrails")
local ownedPlaceHolder , ownedEffectsPlaceHolder = {}, {}
game.Players.PlayerAdded:Connect(function(plr)
	local owned = {}
	

	local ldbrd = Instance.new("Folder")
	ldbrd.Name = "leaderstats"
	ldbrd.Parent  = plr
	
	local CRW =Instance.new("BoolValue")
	CRW.Parent = plr
	CRW.Name = "CRW"
	
	local benefits = Instance.new("IntValue")
	benefits.Parent = plr
	benefits.Name = "Benefits"
	
	local rank = Instance.new("StringValue")
	rank.Parent = plr
	rank.Name = "Rank"

	local spleefCoins = Instance.new("IntValue")
	spleefCoins.Parent = plr
	spleefCoins.Name = "SpleefCoins"

	local wins = Instance.new("IntValue")
	wins.Parent = ldbrd
	wins.Name = "Wins"
	
	local Levels = Instance.new("NumberValue")
	Levels.Parent = plr
	Levels.Name = "Level"
	

	
	local XP = Instance.new("NumberValue", Levels)
	XP.Name = "XP"
	local XP_Limit =Instance.new("NumberValue", Levels)
	XP_Limit.Name = "XP_Limit"
	
	local  Equipped = Instance.new("StringValue")
	Equipped.Parent = plr
	Equipped.Name = "Equipped"

	local  EquippedEffect = Instance.new("StringValue")
	
	EquippedEffect.Parent = plr

	EquippedEffect.Name = "EquippedEffect"
	
	local playeruserid = "Player_"..plr.UserId
	local data = {}
	local owned
	local s, e = pcall(function()
		data = CSS:GetAsync(playeruserid)
		owned = OwnedDatastore:GetAsync(playeruserid)
		ownedEffectsPlaceHolder =OwnedTrailsDatastore:GetAsync(playeruserid)
	end)
	if s then
		if data ~= nil  and owned ~= nil then
			local module = require(game.ServerStorage.ModuleScript)
			spleefCoins.Value = data[1] 
			wins.Value = data[2]
			benefits.Value = data[3] or 1
			Levels.Value = data[4] or 1
			XP.Value = data[5] or 0
			XP_Limit.Value = data[6] or 30
			CRW.Value = data[7] or false
			rank.Value = data[8] or "Newbie"
			Equipped.Value = data[9] or "1"
			EquippedEffect.Value = data[10] or "1"			
			ownedPlaceHolder = owned		
		else
			spleefCoins.Value = 0
			wins.Value = 0
		end
	else
		error(e)
	end
	
	game.ReplicatedStorage.sendEquippedEffect:FireClient(plr, Equipped.Value)
	game.ReplicatedStorage.sendOwnedEffects:FireClient(plr, ownedEffectsPlaceHolder)

end)

game.ServerStorage.PassAlongOwnedTrails.Event:Connect(function(o)
	ownedPlaceHolder = o
end)

game.ServerStorage.PassAlongOwnedEffects.Event:Connect(function(owneed)
	ownedEffectsPlaceHolder = owneed
end)


function Save()
	local players = game.Players:GetPlayers()
	for _, player in pairs(players) do
		local userId = "Player_"..player.UserId
		local data = {player.SpleefCoins.Value, player.leaderstats.Wins.Value, player.Benefits.Value,player.Level.Value, player.Level.XP.Value, player.Level.XP_Limit.Value, player.CRW.Value,player.Rank.Value, player.Equipped.Value,player.EquippedEffect.Value}
		if data then
			-- wrap in pcall to handle any errors
			local success, result = pcall(function()
				-- SetAsync yields so will stall shutdown (@-@)
				CSS:SetAsync(userId, data)
				OwnedDatastore:SetAsync(userId, ownedPlaceHolder)
				OwnedTrailsDatastore:SetAsync(userId, ownedEffectsPlaceHolder)
			end)
			if not success then
				warn(result)
			else
				return true
			end   
		end
	end
end

while wait(10) do
	if Save()then
		print("Saved Data")
	end
end
game.Players.PlayerRemoving:Connect(function(player)
	Save()
	if Save() then
		print("Saved "..player.Name.."'s data before they left")
	end
end)

game:BindToClose(Save)

This is causing it. The only case where you have (implicit) or set (explicit) zero values is if this condition doesn’t pass. Both data and owned need to be non-nil for your script to rifle through player data or use preset values. Looks like one or both are nil.

You might’ve looked it over many times but have you actually debugged it? Debugging reveals more information than eyeing up your code. Observing it is more for a cursory look at if you’ve triggered any underlines but not if you’re trying to figure out a problem with no errors to help guide you.

1 Like

Thanks, I removed a unnecessary conditional and now it works!