DataStore not working

cc: @COUNTYL1MITS, @Jaycbee05

The reason why you use pcall with data stores is because data store requests often fail at no fault of the developer. Pcall allows you to catch the error and do something with that error like doing a custom retry method. Roblox uses DynamoDB for data stores so web calls have to be preformed to access it so pcall should be used.


The reason why your script ins’t working is because you aren’t actually using any saving method in the PlayerRemoving function. This means the data wont save to a data store because you havn’t told it to. To fix this you should use either SetAsync() or UpdateAsync() to save data. I would recommend UpdateAsync() because the developers hub recommends it over SetAsync() and because of this community tutorial: Stop using SetAsync() to save player data.

As I mentioned above you should always wrap your data store requests in pcall because they often fail at no fault of the developer. Having your requests in a pcall will allow you to catch the error and do something when the request fails.

Here is your script with the changes that I mentioned above.:

local datastore = game:GetService("DataStoreService")
local singleStorage = datastore:GetDataStore("PlayerSaves") 

game.Players.PlayerAdded:connect(function(plr)
    local folder = Instance.new("Folder")
    folder.Name = "leaderstats"
    folder.Parent = plr
    
    local coins = Instance.new("IntValue")
    coins.Name = "Coins"
    coins.Parent = folder
	coins.Value = 50
    
    local gems = Instance.new("IntValue")
    gems.Name = "Gems"
    gems.Parent = folder
	gems.Value = 10
    
    local kills = Instance.new("IntValue") 
    kills.Name = "Kills"
    kills.Parent = folder    
    
    local rank = Instance.new("IntValue")
    rank.Name = "Rank"
    rank.Value = 1
    rank.Parent = folder
	
	local Success, data = pcall(function() -- Added a pcall
		return singleStorage:GetAsync(plr.UserId)
	end)
	
	if not Success then -- The data failed to load
		-- Do something if the data faield
	else -- The data loaded successfully
		if data then 
        	coins.Value = data[1]
			gems.Value = data[2] 
        	kills.Value = data[3] 
        	rank.Value = data[4]
		else
			-- Give the player the default data
    	end 
	end
end)

game.Players.PlayerRemoving:Connect(function(plr)
    local leaderstats = plr:FindFirstChild('leaderstats')
	
	if leaderstats then
		local saveData = {
            leaderstats['Coins'].Value,
            leaderstats['Gems'].Value,
            leaderstats['Kills'].Value,
            leaderstats['Rank'].Value
        }
		
		local Success, Error = pcall(function() -- Added pcall
			singleStorage:UpdateAsync(plr.UserId, function(OldData) -- Calls the UpdateAsync() function
				return saveData
			end)
		end)
		
		if not Success then
			-- Do something if the save failed
		end
	end
end)

You should modify this script to fit your use case and where I have left comments. For further improvements you should add BindToClose() for saving data: BindToClose & Data Loss Risk - #2 by Tiffblocks