DataStore not saving

Hi, I found a datastore script elsewhere on the devforum, and am unable to figure out why it’s not working.

-- // Assigning variables //
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Currency") -- This can be changed to whatever you want

local function saveData(player) -- The functions that saves data

	local tableToSave = {
		['Money'] = player.leaderstats.Money.Value; -- First value from the table
		['Miasma'] = player.leaderstats.Miasma.Value;	-- Second value from the table
		['Dawn'] = player.leaderstats.Dawn.Value	-- Third value from the table
	}

	local success, err = pcall(function()
		dataStore:SetAsync(player.UserId, tableToSave) -- Save the data with the player UserId, and the table we wanna save
	end)

	if success then -- If the data has been saved
		print("Data has been saved!")
	else -- Else if the save failed
		print("Data hasn't been saved!")
		warn(err)		
	end
end

game.Players.PlayerAdded:Connect(function(player) -- When a player joins the game

	-- // Assigning player stats //
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Money = Instance.new("IntValue")
	Money.Name = "Money"
	Money.Parent = leaderstats

	local Miasma = Instance.new("IntValue")
	Miasma.Name = "Miasma"
	Miasma.Parent = leaderstats
	
	local Dawn = Instance.new("IntValue")
	Dawn.Name = "Dawn"
	Dawn.Parent = leaderstats

	local data -- We will define the data here so we can use it later, this data is the table we saved
	local success, err = pcall(function()
		data = dataStore:GetAsync(player.UserId) -- Get the data from the datastore
	end)

	if success then -- If there were no errors and player loaded the data
		data['Money'] = Money.Value -- Set to the first value of the table (data)
		data['Miasma'] = Miasma.Value -- Set to the second value of the table (data)
		data['Dawn'] = Dawn.Value -- Set to the third value of the table (data)

	else -- The player didn't load in the data, and probably is a new player
		print("The player has no data!") -- The default will be set to 0
		Money.Value = 100
	end
end)

game.Players.PlayerRemoving:Connect(function(player) -- When a player leaves
	local success, err  = pcall(function()
		saveData(player) -- Save the data
	end)
	if success then
		print("Data has been saved!")
	else
		print("Data has not been saved!")
	end
end)

game:BindToClose(function() -- When the server shuts down
	for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
		local success, err  = pcall(function()
			saveData(player) -- Save the data
		end)

		if success then
			print("Data has been saved!")
		else
			print("Data has not been saved!")
		end
	end
end)

Hey, this should fix your issue.

-- // Assigning variables //
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Currency") -- This can be changed to whatever you want

function saveData(player)
     local tableSaver = {}
     table.insert(tableSaver, plr:WaitForChild("leaderstats"):WaitForChild("Money").Value)
     table.insert(tableSaver, plr:WaitForChild("leaderstats"):WaitForChild("Miasma").Value)
     table.insert(tableSaver, plr:WaitForChild("leaderstats"):WaitForChild("Dawn").Value)
 

      local success, response = pcall(function()
      dataStore:SetAsync(player.UserId, tableSaver)
      end)

    if success then
      print("Succesfully saved data of " .. player.Name)
       else
      warn(response)
    end
end


game.Players.PlayerAdded:Connect(function(player)
       local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Money = Instance.new("IntValue")
	Money.Name = "Money"
	Money.Parent = leaderstats

	local Miasma = Instance.new("IntValue")
	Miasma.Name = "Miasma"
	Miasma.Parent = leaderstats
	
	local Dawn = Instance.new("IntValue")
	Dawn.Name = "Dawn"
	Dawn.Parent = leaderstats

       local data = dataStore:GetAsync(player.UserId)
       if data ~= nil then
       Money.Value = data[1]
       Miasma.Value = data[2]
       Dawn.Value = data[3]
     else
        Money.Value = 0
       Miasma.Value = 0
       Dawn.Value = 0
       end
end)


game.Players.PlayerRemoving:Connect(function(player)
      local success, err  = pcall(function()
      saveData(player)
    end)

              if success then
			print("Data has been saved!")
		else
			print("Data has not been saved!")
	end
end)

By the way sometimes datastores don’t work in studio and make sure datastore services are toggled through game settings.

This doesn’t seem to wanna work either, sadly. it recognises there is data, but the data values arent added

This

game:BindToClose(function() -- When the server shuts down
	for _, player in pairs(game.Players:GetPlayers()) do -- Loop through all the players
		local success, err  = pcall(function()
			saveData(player) -- Save the data
		end)

		if success then
			print("Data has been saved!")
		else
			print("Data has not been saved!")
		end
	end
end)

Is a very bad demonstration of how you can get dataloss. Instead:

game:BindToClose(function() -- When the server shuts down
     wait(3)
end)
1 Like

Hi, I made some changes to the script. Scroll down further, for an explanation of the new parts.
Script:

-- // Assigning variables //
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Currency") -- This can be changed to whatever you want

function saveData(player)
	local tableSaver = {}
	table.insert(tableSaver, player:WaitForChild("leaderstats"):WaitForChild("Dawn").Value)
	table.insert(tableSaver, player:WaitForChild("leaderstats"):WaitForChild("Miasma").Value)
	table.insert(tableSaver, player:WaitForChild("leaderstats"):WaitForChild("Money").Value)


	local success, response = pcall(function()
		dataStore:SetAsync(player.UserId, tableSaver)
	end)

	if success then
		print("Succesfully saved data of " .. player.Name)
	else
		warn(response)
	end
end


game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Money = Instance.new("IntValue")
	Money.Name = "Money"
	Money.Parent = leaderstats

	local Miasma = Instance.new("IntValue")
	Miasma.Name = "Miasma"
	Miasma.Parent = leaderstats

	local Dawn = Instance.new("IntValue")
	Dawn.Name = "Dawn"
	Dawn.Parent = leaderstats

	local data 
	local success, err = pcall(function()
		data = dataStore:GetAsync(player.UserId)
	end)	
	
	if success then
		Money.Value = data and data[1]
		Miasma.Value = data and data[2]
		Dawn.Value = data and data[3]
	else
		Money.Value = 0
		Miasma.Value = 0
		Dawn.Value = 0
	end
end)


game.Players.PlayerRemoving:Connect(function(player)
	local success, err  = pcall(function()
		saveData(player)
	end)
	
	if success then
		print("Data has been saved!")
	else
		print("Data has not been saved!")
	end
end)

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

As DeveloperBLK already said, using this function can prevent data loss. It basically slows down the games process of shutting down, so you will have enough time to save the data

local data 
local success, err = pcall(function()
	data = dataStore:GetAsync(player.UserId)
end)	

I made this into a pcall, because otherwise, it will return “” or nil/error:
image
Maybe this only applies to studio, but :man_shrugging: ^^^

local data 
local success, err = pcall(function()
	data = dataStore:GetAsync(player.UserId)
end)	
-- Already went through this ^^^

if success then
	Money.Value = (data and data[1]) or 0
	Miasma.Value = (data and data[2]) or 0
	Dawn.Value = (data and data[3]) or 0
else
	Money.Value = 0
	Miasma.Value = 0
	Dawn.Value = 0
end

I made it check if the pcall is a success, instead of checking if data ~= nil because, it data may not be saved, but still not be equal to nil.

Money.Value = (data and data[1]) or 0

Basically what (data and data[1]) or 0 means, is if data is found then return data[1]. Otherwise, returns 0.

Example:

print((data and data[1]) or 0)
--[[ Output if data found
> 123
-- Output if data not found
> 0  
2 Likes

alright. Thanks for letting me know.

I’ve done that, so WHY, STILL, does it refuse to work?!

-- // Assigning variables //
local DataStoreService = game:GetService("DataStoreService")
local dataStore = DataStoreService:GetDataStore("Currency") -- This can be changed to whatever you want

function saveData(player)
	local tableSaver = {}
	table.insert(tableSaver, player:WaitForChild("leaderstats"):WaitForChild("Money").Value)
	table.insert(tableSaver, player:WaitForChild("leaderstats"):WaitForChild("Miasma").Value)
	table.insert(tableSaver, player:WaitForChild("leaderstats"):WaitForChild("Dawn").Value)


	local success, response = pcall(function()
		dataStore:SetAsync(player.UserId, tableSaver)
	end)

	if success then
		print(player.Name.."'s currency data has been saved!")
	else
		warn(player.Name.."'s data did not save, due to "..response)
	end
end


game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local Money = Instance.new("IntValue")
	Money.Name = "Money"
	Money.Parent = leaderstats

	local Miasma = Instance.new("IntValue")
	Miasma.Name = "Miasma"
	Miasma.Parent = leaderstats

	local Dawn = Instance.new("IntValue")
	Dawn.Name = "Dawn"
	Dawn.Parent = leaderstats

	local data 
	local success, resp = pcall(function()
		data = dataStore:GetAsync(player.UserId)
	end)	
	-- Already went through this ^^^

	if success then
		print(player.Name.." has data!")
		Money.Value = (data and data[1]) or 0
		Miasma.Value = (data and data[2]) or 0
		Dawn.Value = (data and data[3]) or 0
	else
		print(player.Name.." is new!")
		Money.Value = 0
		Miasma.Value = 0
		Dawn.Value = 0
	end
end)


game.Players.PlayerRemoving:Connect(function(player)
	local success, resp   = pcall(function()
		saveData(player)
	end)
end)

game:BindToClose(function() -- When the server shuts down
	wait(3)
end)
1 Like

Can you tell us what is working and what is not?

pcall prints that savedata() is successful, however, data does not save.
everything else works fine, but my guess is the table does not work for me at all

So the setasync is working but the getasync is not?
I would also print out the table.

the table always stays at 0.
getasync is not working…