Why does my datastore script not work?

--Datasave 

local players = game:GetService('Players')
local DSS = game:GetService('DataStoreService')
local runService = game:GetService('RunService')
local RS = game:GetService('ReplicatedStorage')

local dataStore = DSS:GetDataStore('MyDataStore')

local startingData = {
	Wins = {'IntValue', 0, 'leaderstats'};
	CraftingTables = {'IntValue', 0, 'stats'};
	DamageDealt = {'NumberValue', 0, 'stats'};
	TrailItems = {'StringValue', '', 'stats'};
	NoseTypes = {'StringValue', '', 'stats'};
}

local playersavedata = {}
local autoSaveInterval = 180


local function loadStarterData(plr)
	local STATS = Instance.new('Folder', plr)
	STATS.Name = 'stats'
	local leaderstats = Instance.new('Folder', plr)
	leaderstats.Name = 'leaderstats'

	for name, value in pairs(startingData) do
		local TABLE = value
		local typeValue = TABLE[1]
		local startingValue = TABLE[2]
		local folder = TABLE[3]

		local newValue = Instance.new(typeValue, plr:FindFirstChild(folder))
		newValue.Name = name
		newValue.Value = startingValue

	end
end

local function loadData(plr)
	local data

	local succ, err = pcall(function()
		data = dataStore:GetAsync(plr.UserId)
	end)

	if succ then
		print('Getting ' .. plr.Name.. "'s data was successful!")
	else
		warn('Something went wrong when loading ' .. plr.Name .. " 's data." )
	end

	if data then
		for name, value in pairs(data) do
			plr:FindFirstChild(value[3]):FindFirstChild(name).Value = value
		end
		print(plr.Name .. "'s data has been loaded!")
	else
		print(plr.Name .. ' has no data, generating new data.')
	end
end

local function saveData(plr)
	
	local data = {}
	
	for _, stat in pairs(plr.stats:GetChildren()) do
		data[stat.Name] = stat.Value
	end
	
	for _, stat in pairs(plr.leaderstats:GetChildren()) do
		data[stat.Name] = stat.Value
	end
	
	local succ, err = pcall(function()
		if data then
			dataStore:UpdateAsync(plr.UserId, function(oldValue)
				local previousData = oldValue or {DataId = 0}
				if data.DataId == previousData.DataId then
					data.DataId = data.DataId + 1
					return data
				else
					return nil
				end
			end)
		end
	end)
	
	if succ then
		print(plr.Name.."'s data has been successfully saved!")
	else
		warn('Something went wrong when saving ' .. plr.Name.. "'s data.")
	end
end

players.PlayerAdded:Connect(function(plr)
	playersavedata[plr] = tick()
	loadStarterData(plr)
	loadData(plr)
end)

players.PlayerRemoving:Connect(function(plr)
	saveData(plr)
end)

while true do
	wait(1)
	for _, plr in pairs(players:GetPlayers()) do
		if tick() - playersavedata[plr] >= autoSaveInterval	then
			saveData(plr)
			playersavedata[plr] = tick()
		end
	end
end

All the print statements are returning that the script is working, but it isn’t saving data. It may be with the update async pcall function, but I don’t really know. Thank you!

You forgot to use SetAsync in your code

You’ve forgotten to :SetAsync() in the main function, yet you still use :GetAsync() in loadData, just think, “what are you getting if you haven’t set it?”

He uses UpdateAsync instead, which seems to be considered better practice.

2 Likes

Ok, so how would I use UpdateAsync? Do I still have to use :GetAsync()?

Yes you can still use GetAsync, I’m not familiar with using UpdateAsync but you could use this to help you.

It seems like the issue is in the saveData function.

data.DataId is never assigned, which means it will be nil by default, however previousData.DataId is set to 0 when no data is found.

That would result in data.DataId == previousData.DataId returning false (and therefore, cancelling UpdateAsync), because data.DataId is nil, but previousData.DataId is 0.

1 Like

So would I have to use :GetAsync() inside of the saveData function to get a DataId?