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)