I was working an a system to save the player’s tools with custom attributes to data store and load them whenever the player joins
local dss = game:GetService("DataStoreService")
local toolsDS = dss:GetDataStore("Sus")
local toolsFolder = game.ServerStorage:WaitForChild("Items")
game.Players.PlayerAdded:Connect(function(plr)
local toolsSaved = toolsDS:GetAsync(plr.UserId .. "-tools") or {}
for i, toolData in pairs(toolsSaved) do
local toolName = toolData.Name
local qy = toolData.qy
if toolsFolder:FindFirstChild(toolName) then
local toolClone = toolsFolder[toolName]:Clone()
toolClone:SetAttribute("qy",qy)
toolClone.Parent = plr.Backpack
end
end
plr.CharacterRemoving:Connect(function(char)
char.Humanoid:UnequipTools()
end)
end)
game.Players.PlayerRemoving:Connect(function(plr)
local toolsOwned = {}
for i, toolInBackpack in pairs(plr.Backpack:GetChildren()) do
local toolData = {
Name = toolInBackpack.Name,
qy = toolInBackpack:GetAttribute("qy")
}
table.insert(toolsOwned, toolData)
end
local success, errormsg = pcall(function()
toolsDS:SetAsync(plr.UserId .. "-tools", toolsOwned)
end)
if errormsg then
warn(errormsg)
end
end)
I have tried to search youtube and the dev forum but all i found is saving tools without attributes
In my script, I am saving a table with the tool’s name and an attribute called qy, which stands for the quantity, which is a number value. When I rejoin my tools don’t load and i don’t understand why
for i, toolInBackpack in pairs(plr.Backpack:GetChildren()) do
You are using pairs to iterate, but GetChildren returns an array, not a dictionary. Either use ipairs or get rid of the iterator function completely, which simplifies things a lot.
So try:
for i, toolInBackpack in plr.Backpack:GetChildren() do
In addition, toolsSaved is also not a dictionary, it has the structure of {toolData}. That is, it is an array of dictionaries. So using pairs in
local DataStoreService = game:GetService("DataStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local function cloneBackpackData(player)
local playerDataStore = DataStoreService:GetDataStore("PlayerBackpackData")
-- Retrieve the backpack data from the DataStore using the player's UserId as the key
local backpackData = playerDataStore:GetAsync(player.UserId)
-- Check if data was retrieved successfully
if backpackData then
-- Iterate through the backpack data and clone the tools
for _, child in pairs(backpackData) do
local toolTemplate = ReplicatedStorage.Items:FindFirstChild(child.name)
if toolTemplate then
local newTool = toolTemplate:Clone()
newTool.Parent = player.Backpack
newTool:SetAttribute("qy", child.quantity)
else
print("Tool not found:", child.name)
end
end
else
print("No backpack data found for player:", player.Name)
end
end
-- Create a function to save the backpack data to a DataStore
local function saveBackpackData(player, backpackData)
local playerDataStore = DataStoreService:GetDataStore("PlayerBackpackData")
-- Save the backpack data to the DataStore using the player's UserId as the key
playerDataStore:SetAsync(player.UserId, backpackData)
end
-- Create a function to get the backpack children
local function getBackpackChildren(player)
local backpack = player:WaitForChild("Backpack") -- Wait for the player's Backpack to load
local children = {} -- Table to store the backpack children
-- Iterate through each child of the backpack and add them to the table
for _, child in pairs(backpack:GetChildren()) do
local childData = {
name = child.Name,
quantity = child:GetAttribute("qy") or 0
}
table.insert(children, childData)
end
return children -- Return the table of backpack children
end
game:GetService("Players").PlayerAdded:Connect(function(player)
cloneBackpackData(player)
end)
game:GetService("Players").PlayerRemoving:Connect(function(player)
local backpackChildren = getBackpackChildren(player)
-- Save the backpack data to the DataStore
saveBackpackData(player, backpackChildren)
end)
Yeah, you got the error because now the script actually did something with toolsSaved after
for i, toolData in toolsSaved do
in
local toolName = toolData.Name
It was trying to use toolData.Name, which was empty because nothing was saved in the datastore yet. On line
local toolsSaved = toolsDS:GetAsync(plr.UserId … “-tools”) or {}
you assigned an empty table if GetAsync returns nil.
Instead of doing a simple check to see if #toolsSaved == 0, you go and copy paste an entirely new script. Thanks for wasting my time, I know not to bother helping you again.