To preface this, no errors are shown, and this seemingly occurs randomly.
I have an inventory system for a game and I use a couple of separate datastores to detect the player’s inventory/tools and armor. Each datastore seemingly has the same issue, despite the fact I use the same saving logic that I use in other cases.
The datastores save every few minutes, otherwise they save when a player leaves.
For some reason, every now and then, there will be partial data wipes. Either the player’s armor data will be wiped, or their tools will be wiped, or sometimes items in their inventory will be wiped. I do not know the cause of this, and it has been persistent for the last several months.
I know the data gets wiped because in order to overwrite the data, I erase the datastore entry for the player and then try to input new data. Somewhere between that erasure and inputting the new data, something gets hung up and keeps the data empty, and I’m not sure why. Maybe the server is closing before the data gets saved, or something? I don’t know. I again emphasize no errors.
I’m going to drop my code below and hopefully somebody can point out an obvious issue. This is only one of my datastores (this one is for the Armor), but the other one works under the exact same logic.
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local myDatastore = DataStoreService:GetDataStore("ArmorSystem4")
local function save(Player)
local ArmorData = {}
for _, clothes in ipairs(game.ReplicatedStorage.PlayerInventories:FindFirstChild(Player.Name).Clothes:GetChildren()) do
warn(clothes.Name)
if clothes:IsA("Accessory") then
table.insert(ArmorData, {
clothes.Name,
clothes.Wearing.Value
})
elseif clothes:IsA("Model") then
table.insert(ArmorData, {
clothes.Name,
clothes.Wearing.Value
})
end
end
myDatastore:RemoveAsync(Player.Name)
local success, err
repeat
success, err = pcall(function()
print(ArmorData)
myDatastore:SetAsync(Player.Name, ArmorData)
end)
task.wait()
until success
if not success then
warn("SERVER: Failed to save data: " .. tostring(err))
end
end
local function load(Player)
Player.CharacterAdded:Wait()
wait(0.1)
if not Player.Character:FindFirstChild("Shirt") then
local shirt = Instance.new("Shirt")
shirt.Name = "Shirt"
shirt.Parent = Player.Character
end
if not Player.Character:FindFirstChild("Pants") then
local shirt = Instance.new("Pants")
shirt.Name = "Pants"
shirt.Parent = Player.Character
end
local success, err
local ArmorData
repeat
success, err = pcall(function()
ArmorData = myDatastore:GetAsync(Player.Name)
end)
until success
if not ArmorData then return end
if success then
for i, item in ipairs(ArmorData) do
warn(item[1])
if game.ReplicatedStorage.PartsAndModels.Armor:FindFirstChild(item[1]) then
local clothes = game.ReplicatedStorage.PartsAndModels.Armor:FindFirstChild(item[1]):Clone()
clothes.Parent = game.ReplicatedStorage.PlayerInventories:WaitForChild(Player.Name):WaitForChild("Clothes")
if item[2] == true then
clothes.Wearing.Value = true
if clothes:IsA("Model") then
if clothes:FindFirstChild("Shirt") then
Player.Character:FindFirstChild("Shirt").ShirtTemplate = clothes.Shirt.ShirtTemplate
end
if clothes:FindFirstChild("Pants") then
Player.Character:FindFirstChild("Pants").PantsTemplate = clothes.Pants.PantsTemplate
end
elseif clothes:IsA("Accessory") then
if clothes.AccessoryType == Enum.AccessoryType.Hat then
local helmet = clothes:Clone()
helmet.Parent = Player.Character
helmet.Handle.CanCollide = false
for _, hair in ipairs(Player.Character:GetChildren()) do
if hair:IsA("Accessory") then
if hair.AccessoryType == Enum.AccessoryType.Hair then
hair.Handle.Transparency = 1
end
end
end
if helmet:FindFirstChild("RequireNeck") then
if helmet.RequireNeck.Value == true then
local neckpiece = game.ReplicatedStorage.PartsAndModels.Armor["Neck Chainmail"]:Clone()
neckpiece.Parent = Player.Character
end
end
elseif clothes.AccessoryType == Enum.AccessoryType.Back then
if game.ReplicatedStorage.PartsAndModels.BackpackWeights:FindFirstChild(clothes.Name) then
game.ReplicatedStorage.PlayerInventories:FindFirstChild(Player.Name).MaxWeight.Value = game.ReplicatedStorage.PlayerInventories:FindFirstChild(Player.Name).MaxWeight.Value + game.ReplicatedStorage.PartsAndModels.BackpackWeights:FindFirstChild(clothes.Name).Value
end
clothes.Wearing.Value = true
clothes:Clone().Parent = Player.Character
end
end
if game.ReplicatedStorage.PartsAndModels.ArmorHealth:FindFirstChild(clothes.Name) then
Player.Character:FindFirstChild("Humanoid").MaxHealth = Player.Character:FindFirstChild("Humanoid").MaxHealth + game.ReplicatedStorage.PartsAndModels.ArmorHealth:FindFirstChild(clothes.Name).Value
Player.Character:FindFirstChild("Humanoid").Health = Player.Character:FindFirstChild("Humanoid").Health + game.ReplicatedStorage.PartsAndModels.ArmorHealth:FindFirstChild(clothes.Name).Value
end
end
end
end
else
warn("SERVER: Failed to load inventory data: " .. tostring(err))
end
end
--Player naturally disconnects
--Players.PlayerRemoving:Connect(function(Player)
-- save(Player)
--end)
--Player Joins the Server
Players.PlayerAdded:Connect(function(Player)
load(Player)
Player.CharacterRemoving:Connect(function(Character)
if game.ReplicatedStorage["LoadingData"].Loaded.Value == true then
save(Player)
end
end)
end)
game:BindToClose(function()
for _, plr in ipairs(Players:GetChildren()) do
if game.ReplicatedStorage["LoadingData"].Loaded.Value == true then
save(plr)
end
end
end)
--Autosave Function
while wait(120) do
for _, plr in ipairs(Players:GetChildren()) do
if game.ReplicatedStorage["LoadingData"].Loaded.Value == true then
save(plr)
end
end
end