Funky Datastore Not Working

I am currently trying to make a data system, but I’m running into some issues with my script. I will update this post when and if I am able to fix it. I’ve tried removing and replacing sections, but no such luck. Sorry for the overall lack of detail in this post, I’m just trying to finish before I head to sleep.

Edit:
There is no actual error, just that sometimes the PlayerData doesn’t exist, and sometimes it does. Sometimes it prints, sometimes it doesn’t. I’ve tried forcing the data to load from another script and inside this one at it still varies.

The Code:

wait(.1) -- ensure that the player instace has at least been given the chance to load

-- Services

local ReplicatedStorage	= game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")

-- Constants

local Prefix = "alpha_"
local Datastore = DataStoreService:GetOrderedDataStore("Data")

local Save_Currency = true
local Save_Positions = true

local SaveData_Event = ReplicatedStorage.Events:FindFirstChild("SaveData")
-- Functions

local function loadData(Player)
	local startTime = tick()
	local strt = tick()
	local del
	print("Loading " .. Player.Name .. "'s data...") -- Let it be known that the data is attempting to be loaded
	
	local playerData	= script.PlayerData:Clone()
	playerData.Name		= "PlayerData"
	
	local saveData
	
	local Character = workspace:FindFirstChild(Player.Name)
	
	wait(1)
	
	local success, err = pcall(function()
		del = tick() - strt
		saveData = Datastore:GetAsync(Prefix..tostring(Player.UserId))
	end)
	
	if success then -- Data can currently be retrieved from the datastore
		if saveData then
			print("Success! " .. Player.Name .. "'s data has been initialized.") -- Let it be known that the data loaded
			print(Player.Name .. "'s data took" .. del .. "s to init, loading...") -- Tell how long it took to load (hopefully)
			if saveData.Currency then
				for stat, value in pairs(saveData.Currency) do
					if playerData.Currency:FindFirstChild(stat) then
						playerData.Currency[stat].Value = value
					end
				end
				for stat, value in pairs(saveData.Positions) do
					if playerData.Positions:FindFirstChild(stat) then
						playerData.Positions[stat].Value = value
					end
				end
			end
		else
			print("Warning! " ..Player.Name.. " has no data, setting to default...")
			
		end
		
	else
		warn("Warning! Datastore " .. Prefix .. tostring(Player.UserId) .. " is unable to save/load!" )
		local errorValue	= Instance.new("StringValue")
		errorValue.Name		= "ERROR_ON_LOAD"
		errorValue.Value	= err
		errorValue.Parent	= Player
	end
	playerData.Parent	= Player
	return playerData
end

local function saveData(Player)
	print("Saving " .. Player.Name .. "'s data...")
	local playerData	= Player:FindFirstChild("PlayerData")
	
	if playerData then
		
		if playerData:FindFirstChild("ERROR_ON_LOAD") then -- Abort saving if we can't
			warn("Data unsafe to save!")
			return false
		end
		
		local attempts = 0
		local success = false
		
		repeat
			attempts = attempts + 1
			print("Attempt " ..  tostring(attempts))
			success = pcall(function()
				Datastore:UpdateAsync(Prefix .. tostring(Player.UserId), function(saveData)
					if saveData then
						if not saveData.Currency then
							saveData.Stats = {}
						end
						if not saveData.Positions then
							saveData.Positions = {}
						end
					else
						saveData = {
							Currency = {};
							Positions = {};
							}
					end
					
					if Save_Currency then -- If we are saving their currency, then we save it.
						for _, currency in pairs(playerData.Currency:GetChildren()) do
							saveData.Currency[currency.Name] = currency.Value
						end
					end
					
					if Save_Positions then
						for _, position in pairs(playerData.Positions:GetChildren()) do
							saveData.Positions[position.Name] = position.Value
						end
					end
					
					return saveData
				end)
			end)
		until success or attempts == 5
		return success
	else
		return false	
	end
end
	
SaveData_Event.OnInvoke = saveData

Players.PlayerAdded:connect(function(Player)
	loadData(Player)
end)

Thanks again!

Could you please elaborate on what the error is?

2 Likes

Yes, sorry. I’ll respond here and then add the edit to the post.
There is no actual error, just that sometimes the PlayerData doesn’t exist, and sometimes it does. Sometimes it prints, sometimes it doesn’t.

Could be wrong but remove the wait at the beginning. The player could be being added before the wait, therefore the player added function will only activate if the player is added after the 0.1 seconds