Hi, I am making a simulator game and whenever you buy a tool, that tool will be saved in your playerTools (not player backpack) to verify it has been bought and you don’t have to buy it again. Now I want to save those tools in that folder when you leave and rejoin. The script I have now is:
local players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local ServerStorage = game:GetService("ServerStorage")
local DataStore = DataStoreService:GetDataStore("Storage")
local ItemsFolder = ServerStorage:FindFirstChild("Tools")
local starterTool = ServerStorage:FindFirstChild("StarterTool")
players.PlayerAdded:Connect(function(Player)
local loadedData
local playerTools = ServerStorage:FindFirstChild("PlayerTools"):WaitForChild(Player.Name)
local worked, err = pcall(function()
loadedData = DataStore:GetAsync(Player.UserId)
for i, v in pairs(loadedData) do -- problem here
if v:IsA("Tool") then
v:Clone().Parent = playerTools
print("yes")
end
end
end)
if loadedData ~= nil then
for i , v in pairs(loadedData) do
local Tool = starterTool:GetChildren(v)
if Tool then
Tool:Clone().Parent = Player.Backpack
Tool:Clone().Parent = Player.StarterGear
end
end
end
end)
players.PlayerRemoving:Connect(function(Player)
local tools = {}
local playerTools = ServerStorage:FindFirstChild("PlayerTools"):WaitForChild(Player.Name)
for i,v in pairs(playerTools:GetChildren()) do
if v:IsA("Tool") then
table.insert(tools,v.Name)
end
end
local worked, err = pcall(function()
DataStore:SetAsync(Player.UserId,tools)
end)
if not worked then warn(err)
end
end) -- this works
However, when you join it doesn’t load the tools back into the playerTools. I think it has something to do with the loop not getting the children, I have tried changing the for i, v in pairs(loadedData) do to for i, v in pairs(loadedData:GetChildren()) do but that didn’t work either. Is there anyone that can help me with this?
Why would you do this to verify if someone already has brought something when you could just check the data storage to see if someone has brought something already.
when you buy an item it gets placed in the playertools, so the shop can see that you bought it and equip it, and I want to save those items you bought so you don’t have to buy them again when you rejoin
loadedData = DataStore:GetAsync(Player.UserId)
for i, v in pairs(loadedData) do -- problem here
if v:IsA("Tool") then
v:Clone().Parent = playerTools
print("yes")
end
end
In this section you are loading the data that is saved for the player. When the player is leaving you are saving the tool names (which is the correct way). However, in this section you are expecting that the datastore is loading the tools itself ( if v:IsA("Tool") then ).
Problem 2:
if loadedData ~= nil then
for i , v in pairs(loadedData) do
local Tool = starterTool:GetChildren(v)
if Tool then
Tool:Clone().Parent = Player.Backpack
Tool:Clone().Parent = Player.StarterGear
end
end
end
at the line local Tool = starterTool:GetChildren(v) did you mean to use FindFirstChild?
The second problem is the part for when the player first joins, so I will try that later but for what do I need to search then, do I need to look for a string? if yes, how?
Here’s your issue, you cannot call :GetChildren() on a datastore table. You can iterate through a table using a for i,v in pairs loop but this is incorrect.
This isn’t going to be a simple fix, as your entire code is referencing invalid objects, :IsA() cannot be called on a Datastore, and checking whether it’s a tool is just going to error.
If you replace the GetChildren(v) with FindFirstChild(v) it should work perfectly.
As for the first problem I reported you could remove this entire loop and combine it with the second one. It will look like this then
if loadedData ~= nil then
for i , v in pairs(loadedData) do
local Tool = starterTool:FindFirstChild(v)
if Tool then
Tool:Clone().Parent = Player.Backpack
Tool:Clone().Parent = Player.StarterGear
Tool:Clone().Parent = playerTools
end
end
end
Your entire code fixed would look like this
local players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local ServerStorage = game:GetService("ServerStorage")
local DataStore = DataStoreService:GetDataStore("Storage")
local ItemsFolder = ServerStorage:FindFirstChild("Tools")
local starterTool = ServerStorage:FindFirstChild("StarterTool")
players.PlayerAdded:Connect(function(Player)
local loadedData
local playerTools = ServerStorage:FindFirstChild("PlayerTools"):WaitForChild(Player.Name)
local worked, err = pcall(function()
loadedData = DataStore:GetAsync(Player.UserId)
end)
if loadedData ~= nil then
for i , v in pairs(loadedData) do
local Tool = ItemsFolder:FindFirstChild(v)
if Tool then
Tool:Clone().Parent = Player.Backpack
Tool:Clone().Parent = Player.StarterGear
Tool:Clone().Parent = playerTools
end
end
else
for i , v in pairs(starterTool:GetChildren()) do
if v:IsA("Tool") then
v:Clone().Parent = Player.Backpack
v:Clone().Parent = Player.StarterGear
v:Clone().Parent = playerTools
end
end
end
end)
players.PlayerRemoving:Connect(function(Player)
local tools = {}
local playerTools = ServerStorage:FindFirstChild("PlayerTools"):WaitForChild(Player.Name)
for i,v in pairs(playerTools:GetChildren()) do
if v:IsA("Tool") then
table.insert(tools,v.Name)
end
end
local worked, err = pcall(function()
DataStore:SetAsync(Player.UserId,tools)
end)
if not worked then warn(err)
end
end)
local players = game:GetService("Players")
local dss = game:GetService("DataStoreService")
local ss = game:GetService("ServerStorage")
local location = game.ServerStorage -- Location of Tools
local ds = dss:GetDataStore("Storage")
local data = {tools = {}}
game.Players.PlayerAdded:Connect(function(player)
local tools = ds:GetAsync(player.UserId)
if tools.tools then
for i,v in pairs(tools.tools) do
if location:FindFirstChild(v) then
location:FindFirstChild(v):Clone().Parent = player.Backpack
end
end
else
print("No tools stored")
end
end)
sadly, this didn’t work. That part is used for when the player has no data yet and it looks trough the starterTool to clone the starter tool in the players backpack. What I want is when a player buys something in the shop, which then gets cloned to the playerTools, for that tool to save in the playerTools.
To set someone’s tools, use this. (I had this for debugging purposes)
local data = {tools = {"Tool1","Tool2"}}
local player = game.Players.LocalPlayer
game:GetService("DataStoreService"):GetDataStore("Storage"):SetAsync(player.UserId,data)