Why is my data store not working?

local DataStoreS = game:GetService(“DataStoreService”)
local PlayerDataS = DataStoreS:GetDataStore(“PlayerData”)

game.Players.PlayerAdded:Connect(function(player)

local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player

local Coins = Instance.new("IntValue")
Coins.Name = "Coins"
Coins.Value = 0
Coins.Parent = leaderstats

local plrData 

local succes,errormsg = pcall(function()
	local playerId = player.UserId
	plrData = PlayerDataS:GetAsync(playerId)
end)

if succes then
	if plrData then
		Coins.Value = plrData[1]
	end
else
	warn(errormsg)
end

end)

local function savedata(player)

local leaderstats = player.leaderstats
local playerData = {leaderstats.Coins.Value}

local success, errormsg = pcall(function()
	PlayerDataS:SetAsync(player.UserId,playerData)
end)

if not success then
	warn(errormsg)
end

end

game.Players.PlayerRemoving:Connect(function(player)
savedata(player)
end)

game:BindToClose(function()
for _ , v in pairs(game.Players:GetPlayers()) do
savedata(v)
end
end)

What error messages do you get?

First, a few things.

The implementation that you have here does have failsafe measures, but only for Roblox events. You do not have any sanitization done with your functions to prevent multiple unnecessary calls, such as seen with savedata. You are calling savedata for every player when the game is getting ready to close, but also calling the function when PlayerRemoving fires. I recommend creating a buffer that stores player objects as the data is saving, then removing the player object from the buffer when the data is finished saving. This might not catch every case where PlayerRemoving and BindToClose fire decently far apart, but it will prevent possible data overwriting scenarios. You could also create a data saving queue system so if you really want to have data save as the function is called, you enter it into the queue and some external thread reads from that queue list and only takes the most recent index, and discarding all the others. If you have, or plan to make, an incremental datastore system, you will have to take from the queue list and combine all of the changes, then save the data all in one SetAsync call. I recommend for those types of systems, you use UpdateAsync instead to prevent data loss.


Now, to fix your issue, it appears you didn’t provide what exactly wasn’t working. Without this crucial information, there isn’t much I can do.

However, it seems you are using an array to save player data. I recommend using a dictionary. So instead of having to do data[1] to access the player’s coins, you do data.Coins, and so on.

I was just being dumb the script works. But how would I go about making a buffer for it because it seems like a better method