DataStore not saving that strongly

Hello everyone, I am not sure why The Inventory Save is not working like really well. There is a continuous loss of information.

game.Players.PlayerAdded:Connect(function(player)
	local data
	local module = require(1936396537)
	local tools = module("tools", player)
	data = tools:Get({})

	if typeof(data) == "table" then
		for _, toolName in next, data do
			local tool = game.ServerStorage.Tools:FindFirstChild(toolName)

			if player.Backpack:FindFirstChild(tool.Name) then
				return
			end

			if tool then
				local newTool = tool:clone()
				newTool.Parent = player.Backpack

				local newTool = tool:clone()
				newTool.Parent = player.StarterGear
			end
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local toolsTable = {}

	local module = require(1936396537)
	local tools = module("tools", player)

	for _, tool in next, player.Backpack:children() do
		if game.ServerStorage.Tools:FindFirstChild(tool.Name) then
			local newTable = tools:Get()
			table.insert(newTable, tool.Name)
			tools:Set(newTable)
		end
	end
end)
2 Likes

Are you using DataStore2? If so, then either of the following could be happening:

  • You variable, module is relying on a Roblox asset that is a completely outdated version of DS2. To get the most recent version, go to the documentation hub and download the latest version.

  • Do you have the BoolValue, SaveInStudio, checked true in the ServerStorage? If not then that could be causing the data loss within studio.

Also, your code seems to be relying on the PlayerRemoving function when the documentation explicity states that’s what you should NOT do.

  • You need to set your data stores as they change , not on PlayerRemoving.

The normal way of doing data stores is to keep a cache somewhere of a player’s data (such as in a folder or using leaderstats), then saving when the player leaves. It is wrong, however, to use DataStore2 this way . DataStore2 is built to be used whenever your data actually changes. You shouldn’t invoke DataStore2 in PlayerRemoving at all.

So instead of PlayerRemoving, you should be doing:

game.Players.PlayerAdded:Connect(function(player)
    --code
end)

I recommend looking at a video tutorial on doing this so you can get a better idea of how this is done.

1 Like

Yes this is a DataStore2. The SaveinStudio bool value is checked true too. This only happens in games to some players where they lose information. Also I do have game.player.player added:conncect(function() on the top. So why would I do this two times?

1 Like

That is not the correct way of using DataStore2. You have to set the data first, and then apply the changes from that data using :OnUpdate.

You are saving when the player leaves, DataStore2 already does that, so it causes data to not be saved.

When parenting the tool, :Set the data immediately at that time instead of .PlayerRemoving. DataStore2 automatically saves data on player removal.

The normal way of doing data stores is to keep a cache somewhere of a player’s data (such as in a folder or using leaderstats), then saving when the player leaves. It is wrong, however, to use DataStore2 this way . DataStore2 is built to be used whenever your data actually changes. You shouldn’t invoke DataStore2 in PlayerRemoving at all .

So do I not change the first part and instead just add the :Set the data to it and it would save?

Run the :Set function whenever you want to change the data. For example you need to add an item into an inventory, you will duplicate the tool in the inventory as usual, but instead of saving that tool in the DataStore2 when player leaves, you save it immediately when you add it.

You can also just only do the :Set function but attach an :OnUpdate on your DataStore2 and add the tool afterwards.

DataStore2 has functions similar to normal data store but is not meant to be used like normal data store. Please look at its documentation and thread carefully, you are missing a lot of points which were clearly mentioned in the post of DataStore2.

Also in this loop you are running :Get and :Set multiple times, this will cause data loss even in normal data stores!

for _, tool in next, player.Backpack:children() do
	if game.ServerStorage.Tools:FindFirstChild(tool.Name) then
		local newTable = tools:Get() -- RAN MULTIPLE TIMES!
		table.insert(newTable, tool.Name)
		tools:Set(newTable) -- RAN MULTIPLE TIMES!
	end
end

Also you are requiring the module everytime the player joins or leaves! You only need to require this once and store it in a variable at the top of the script.

Would this be better?

local module = require(1936396537)
game.Players.PlayerAdded:Connect(function(player)
	local data
	
	local tools = module("tools", player)
	data = tools:Get({})

	if typeof(data) == "table" then
		for _, toolName in next, data do
			local tool = game.ServerStorage.Tools:FindFirstChild(toolName)

			if player.Backpack:FindFirstChild(tool.Name) then
				return
			end

			if tool then
				local newTool = tool:clone()
				newTool.Parent = player.Backpack

				local newTool = tool:clone()
				newTool.Parent = player.StarterGear
			end
		end
	end
end)


local plyaer = game.Players.LocalPlayer
local Inventory = plyaer:WaitForChild("Backpack")
if Inventory:FindFirstChild(tool.Name) then
	local toolsTable = {}

	
	local tools = module("tools", player)

	for _, tool in next, player.Backpack:children() do
		if game.ServerStorage.Tools:FindFirstChild(tool.Name) then
			local newTable = tools:Get()
			table.insert(newTable, tool.Name)
			tools:Update(newTable)
		end
	end
end)