I want to make a loadout system, however the inventory saving script I have doesn’t work as intended, for example, if I buy a primary, then leave, and then rejoin to replace that primary, the previous primary does not get replaced and there’s just 2 primaries now due to the saved one being treated as a seperate item : (
Here’s a screenshot to see what I mean:
Here’s my data saving script:
local DataStoreService = game:GetService("DataStoreService")
local conf = game.ReplicatedStorage:WaitForChild("Configuration")
local currencyName = conf:WaitForChild("CurrencyName")
local startingCurrency = conf:WaitForChild("StartingCurrency")
local dsKey = conf:WaitForChild("DatastoreKey")
local datastore = DataStoreService:GetDataStore(dsKey.Value)
local CreateLeaderstats = require(game.ServerScriptService.ShopServer.ModuleScripts.CreateLeaderstats)
-- Function to save player data
local function SaveData(player)
if not player then
return
end
local plrKey = player.UserId
local plrCash = player:FindFirstChild("leaderstats") and player.leaderstats[currencyName.Value].Value or 0
-- Collect player's tools data
local tools = {}
local function collectToolsFromContainer(container)
for _, tool in ipairs(container:GetChildren()) do
if tool:IsA("Tool") then
tools[tool.Name] = true -- Use a table to ensure uniqueness
end
end
end
collectToolsFromContainer(player.Backpack)
if player.Character then
collectToolsFromContainer(player.Character)
end
local ownedTools = player:FindFirstChild("OwnedTools")
if ownedTools then
for _, tool in ipairs(ownedTools:GetChildren()) do
tools[tool.Name] = true
end
end
local toolsList = {}
for toolName, _ in pairs(tools) do
table.insert(toolsList, toolName)
end
local plrData = { Cash = plrCash, Tools = toolsList }
local success, err = pcall(function()
datastore:SetAsync(plrKey, plrData)
end)
if not success then
warn("Error saving " .. player.Name .. "'s (" .. plrKey .. ") data:\n" .. err)
else
print("Data saved successfully for player:", player.Name)
end
end
-- Function to load player data
local function LoadData(player)
if not player then
return
end
local plrKey = player.UserId
local dataFailedWarning = Instance.new("BoolValue")
dataFailedWarning.Name = "DataLoadFailed"
dataFailedWarning.Value = true
dataFailedWarning.Parent = player
local success, plrData = pcall(function()
return datastore:GetAsync(plrKey)
end)
if success and plrData then
if not player:FindFirstChild("leaderstats") then
CreateLeaderstats(player, plrData.Cash or startingCurrency.Value)
end
-- Create the OwnedTools folder if it doesn't exist
local ownedTools = player:FindFirstChild("OwnedTools")
if not ownedTools then
ownedTools = Instance.new("Folder")
ownedTools.Name = "OwnedTools"
ownedTools.Parent = player
end
-- Give the player their saved tools
local backpack = player:WaitForChild("Backpack")
local toolNames = {}
for _, toolName in ipairs(plrData.Tools or {}) do
if not toolNames[toolName] then
toolNames[toolName] = true
local tool = nil
-- Search in the ReplicatedStorage folders
for _, folder in ipairs({"Coins", "Tools", "Gamepass"}) do
local folderRef = game.ReplicatedStorage:FindFirstChild(folder)
if folderRef then
tool = folderRef:FindFirstChild(toolName)
if tool then break end
end
end
if tool then
-- Add tool to OwnedTools folder
local ownedTool = tool:Clone()
ownedTool.Parent = ownedTools
-- Ensure only one instance of each tool in Backpack
local existingTool = backpack:FindFirstChild(toolName)
if existingTool then
existingTool:Destroy()
end
-- Clone tool to backpack
tool:Clone().Parent = backpack
end
end
end
dataFailedWarning.Value = false
else
warn("Error loading " .. player.Name .. "'s (" .. plrKey .. ") data.")
end
dataFailedWarning:Destroy()
end
-- Create OwnedTools folder for the player
game.Players.PlayerAdded:Connect(function(player)
local ownedTools = Instance.new("Folder")
ownedTools.Name = "OwnedTools"
ownedTools.Parent = player
player.CharacterAdded:Connect(function()
LoadData(player)
end)
end)
-- Connect function to player leaving event
game.Players.PlayerRemoving:Connect(function(player)
SaveData(player)
end)
-- Bind to close function to save data for all players
game:BindToClose(function()
for _, player in ipairs(game.Players:GetPlayers()) do
SaveData(player)
end
end)
local DataStoreService = game:GetService("DataStoreService")
local conf = game.ReplicatedStorage:WaitForChild("Configuration")
local currencyName = conf:WaitForChild("CurrencyName")
local startingCurrency = conf:WaitForChild("StartingCurrency")
local dsKey = conf:WaitForChild("DatastoreKey")
local datastore = DataStoreService:GetDataStore(dsKey.Value)
local CreateLeaderstats = require(game.ServerScriptService.ShopServer.ModuleScripts.CreateLeaderstats)
-- Function to save player data
local function SaveData(player)
if not player then
return
end
local plrKey = player.UserId
local plrCash = player:FindFirstChild("leaderstats") and player.leaderstats[currencyName.Value].Value or 0
-- Collect player's tools data
local tools = {}
local function collectToolsFromContainer(container)
for _, tool in ipairs(container:GetChildren()) do
if tool:IsA("Tool") then
tools[tool.Name] = true -- Use a table to ensure uniqueness
end
end
end
collectToolsFromContainer(player.Backpack)
if player.Character then
collectToolsFromContainer(player.Character)
end
local ownedTools = player:FindFirstChild("OwnedTools")
if ownedTools then
for _, tool in ipairs(ownedTools:GetChildren()) do
tools[tool.Name] = true
end
end
local toolsList = {}
for toolName, _ in pairs(tools) do
table.insert(toolsList, toolName)
end
local plrData = { Cash = plrCash, Tools = toolsList }
local success, err = pcall(function()
datastore:SetAsync(plrKey, plrData)
end)
if not success then
warn("Error saving " .. player.Name .. "'s (" .. plrKey .. ") data:\n" .. err)
else
print("Data saved successfully for player:", player.Name)
end
end
-- Function to load player data
local function LoadData(player)
if not player then
return
end
local plrKey = player.UserId
local dataFailedWarning = Instance.new("BoolValue")
dataFailedWarning.Name = "DataLoadFailed"
dataFailedWarning.Value = true
dataFailedWarning.Parent = player
local success, plrData = pcall(function()
return datastore:GetAsync(plrKey)
end)
if success and plrData then
if not player:FindFirstChild("leaderstats") then
CreateLeaderstats(player, plrData.Cash or startingCurrency.Value)
end
-- Create the OwnedTools folder if it doesn't exist
local ownedTools = player:FindFirstChild("OwnedTools")
if not ownedTools then
ownedTools = Instance.new("Folder")
ownedTools.Name = "OwnedTools"
ownedTools.Parent = player
end
-- Clear existing tools in Backpack and OwnedTools folder before loading saved tools
player.Backpack:ClearAllChildren()
ownedTools:ClearAllChildren()
-- Give the player their saved tools
local backpack = player:WaitForChild("Backpack")
local toolNames = {}
for _, toolName in ipairs(plrData.Tools or {}) do
if not toolNames[toolName] then
toolNames[toolName] = true
local tool = nil
-- Search in the ReplicatedStorage folders
for _, folder in ipairs({"Coins", "Tools", "Gamepass"}) do
local folderRef = game.ReplicatedStorage:FindFirstChild(folder)
if folderRef then
tool = folderRef:FindFirstChild(toolName)
if tool then break end
end
end
if tool then
-- Add tool to OwnedTools folder
local ownedTool = tool:Clone()
ownedTool.Parent = ownedTools
-- Ensure only one instance of each tool in Backpack
local existingTool = backpack:FindFirstChild(toolName)
if existingTool then
existingTool:Destroy()
end
-- Clone tool to backpack
tool:Clone().Parent = backpack
end
end
end
dataFailedWarning.Value = false
else
warn("Error loading " .. player.Name .. "'s (" .. plrKey .. ") data.")
end
dataFailedWarning:Destroy()
end
-- Function to replace old primary tool with new one
local function ReplacePrimaryTool(player, newToolName)
local backpack = player:WaitForChild("Backpack")
local oldPrimaryTool = backpack:FindFirstChildWhichIsA("Tool")
-- Remove old primary tool if it exists
if oldPrimaryTool then
oldPrimaryTool:Destroy()
end
-- Add new primary tool
local tool = nil
for _, folder in ipairs({"Coins", "Tools", "Gamepass"}) do
local folderRef = game.ReplicatedStorage:FindFirstChild(folder)
if folderRef then
tool = folderRef:FindFirstChild(newToolName)
if tool then break end
end
end
if tool then
local newTool = tool:Clone()
newTool.Parent = backpack
end
end
-- Create OwnedTools folder for the player
game.Players.PlayerAdded:Connect(function(player)
local ownedTools = Instance.new("Folder")
ownedTools.Name = "OwnedTools"
ownedTools.Parent = player
player.CharacterAdded:Connect(function()
LoadData(player)
end)
end)
-- Connect function to player leaving event
game.Players.PlayerRemoving:Connect(function(player)
SaveData(player)
end)
-- Bind to close function to save data for all players
game:BindToClose(function()
for _, player in ipairs(game.Players:GetPlayers()) do
SaveData(player)
end
end)
There is defenetlly another method, but sorry i cant really help you with that one, maybe it’s caused by other script because i have no idea why its saving old primary tool, also you tried to remove old primary tool then saving?