Data store working only half the time

--saving player data
game.Players.PlayerRemoving:Connect(function(plr)

	--find player's folder in "PlayerData"
	local plrFolder = repStorage.PlayerData:FindFirstChild(plr.Name)

	--if there wasn't a data failure upon joining the game, then
	if not plrFolder:FindFirstChild("DATAFAILURE") then
		print("moving on")

		--save equipped persona
		local persona = dStore:GetDataStore("EquippedPersona")
		persona:SetAsync(plr.Name, plrFolder.EquippedPersona.Value)

		--save equipped character role
		local role = dStore:GetDataStore("EquippedCharacter")
		role:SetAsync(plr.Name, plrFolder.EquippedCharacter.Value)



		--save updated persona kills table
		local pKills = dStore:GetDataStore("PersonaKills")
		--create dictionary for kills
		local killTable = {}
		--loop through the persona kills folder in player data and add new entries/data for each value
		for i, data in pairs(plrFolder.PersonaKills:GetChildren()) do
			killTable[data.Name] = data.Value
		end
		print(killTable)

		--update data store with new table
		pKills:SetAsync(plr.Name, killTable)


	end

	--delete player folder
	plrFolder:Destroy()




end)

This is the saving half of my datastore. The loading half seems to be working perfectly.
The print at the top, “moving on”, always seems to print, but the “killTable” print sometimes doesn’t. It’s not empty or anything, it just doesn’t print.

I have no idea why this is happening, my only thought being that the server dies before being able to finish the code? Not sure, any help is welcome.

2 Likes

The print happens before you saved the data? that could be why

1 Like

I’m not printing the saved data, I’m just printing the table of data that I’m about to save. But the print statement doesn’t run maybe half the time.

The server may shut down before data can be saved, you can keep the server up for 30 extra seconds if you use the game:BindToClose()
If you make a table with all the loaded players inside, you can repeatedly loop:

while next(loaded) ~= nil do
        task.wait()
end

Whenever saving player data, after it saves, you need to remove the player from the loaded table

Also when calling DataStore:GetAsync() you should call it in protected mode so if an error happens, you can kick the player to let them know about the error

local success, value = pcall(DataStore.GetAsync, DataStore, player.UserId)
if success == false then player:Kick() return end

—value is what Datastore:GetAsync() normally return

You should use player.UserId since players can change their username

1 Like

if i were to, for example, just add a lil

game:BindToClose(function())
   wait(5)
end)

would this work fine, or cause any unforeseen errors?

In big servers, when all players get kicked at the same time, some might experience minor-data loss
I would still recommend using the while loop since it may take longer than expected to save data, and also if you are saving a large amount of data

1 Like

Hi there, can I please ask you to not include the GetDataStore functions inside of PlayerRemoving, it’d be much better if you only did it once at the start of the code one after another. In addition, it’s also suggested that you use pcall’s for setting and getting data from datastores, this makes them much safer to use and also provide errors too! One more thing, I’d recommend to keep all data in one table and update that accordingly, this will allow you to save all data at once and also get it at once, granted you can split them into two or three parts for organization purposes too. Hope this helps.

1 Like