#Datastore saving backpack issue
1 messages · Page 1 of 1 (latest)
`local datastore = game:GetService("DataStoreService")
local dataname = datastore:GetDataStore("BackpackData")
local serverstorage = game:GetService("ServerStorage").Tools
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Wait()
local backpack = plr:WaitForChild("Backpack")
local plrdata = plr.UserId
local success, currenttools = pcall(function()
return dataname:GetAsync(plr.UserId)
end)
if success and currenttools then
for _, tool in pairs(currenttools) do
if serverstorage:FindFirstChild(tool) then
serverstorage[tool]:Clone().Parent = backpack
end
end
end
end)
game.Players.PlayerRemoving:Connect(function(plr)
local tools = {}
local backpack = plr:WaitForChild("Backpack")
local plrdata = plr.UserId
for _, v in pairs(backpack:GetChildren()) do
if v:IsA("Tool") then
table.insert(tools, v.Name)
end
end
for _, v in pairs(plr.Character:GetChildren()) do
if v:IsA("Tool") then
table.insert(tools, v.Name)
end
end
local success, err = pcall(function()
dataname:SetAsync(plr.UserId, tools)
end)
if not success then
warn("error"..err)
end
end)
`
keep track of the equipped tool as they equip/unequip
there's thousands of ways to do it so pick one
right but where am I going to track the equipped event, like from each tool??
there's thousands of ways and that is one of them
wym thousands 😭
well you could do it from within every tool, or you could do character.childadded/removed, or you could make your own backpack system and track it that way, or you could do it from a script that reads every tool and connects to their ancestrychanged or tool.equip/unequip, or you could hold all tools in memory so they dont get deleted when the player leaves regardless of where they are. there's more but these are probably the most obvious.
have you never seen the word 'thousands' before?
gang i just started to learn script last month
that's a, "did i misspeak?", you indeed heard me correctly - thousands. what else would you mean by wym. there's an infinite number of ways to formulate code and do pretty much anything.
very, very rarely is there a one definitive correct answer
yeah but ive never thought there is many ways to format this
Just keep a list of all the tools that the player has and save/load based on it.
Or be lazy and fetch every tool the player has in both their character and backpack.
thats what i did
but it doesnt work
then choose another solution.
Several of which are here.
most annoying part is you can only access characterremove after you write playerremoved
which makes it useless
@acoustic coral if there is alot of way to fix this, what is the most ideal way in your opinion?
whichever suits your game the best
i mean i am not making a game, it is just practising
then practice making all of them
all of them
ok let's say this, if you were me which one you gonna use?
you cant just use all of them
i'd make all of them and figure out the difference between each one and decide for myself which one i'd want to use when i want to use them later on
which one is the simpliest way
you can't decide for yourself if you don't know the pros and cons of each solution
eh they're all about the same difficulty. making your own backpack is probably hardest tho
yea you're gonna have to get used to the fact that there is no straight forward easy answers.
i mean in comparison to all methods
there is 100% a way that is simple
if there is alot of methods
and that one method changes on what you're trying to do
you're also talking as if i haven't made all of them myself, i have.
just a simple backpack saving
not asking you to do something i wouldn't do myself.
and you said you wanted practice ey - pick one at random and go with that.
thats why I am seeking for help, since youre experienced def there is a beginner friendly method
but i dont really understamd the methods lol
you can spend the next week deciding which one to use based on other people's opinions, or you can spend the same time making each one and get to the same answer
Just give the man his answer stop being so egotistical holy
** You are now Level 1! **
I just wanted to learn 😅
just give the man his answer dont be so egotistical
Literally
i'll let you take it from here 
Jesus man
well is there any way not to insert a script to every single tool, or less clumsy way to do it
i reckon there is a way that isnt clumsy and doable in a single script
i am practising as organised as possible as well
You use OOP coding?
yeah
Got a player class?
what is a player class😭
i mean i have this script
Make a player class and a player service, log player joins, create a player class when they join
Then, inside the class set an inventory class
And log every tool in the inventory class
That is how i would do it
i successfully saves the player backpack, but not when the player equiped the tool which brings the tool into a children of the character's
like when i hold the tool, i rejoin it wont save
this is the issue I am facing rn
Let me look at your script rq
alright
Oh youre accessing the character when the player has already left
I think a better approach would be
Yeah the thing is you cant
ik 😭
So the best solution is probably to just
Hold a table with every table,
Player*
And have their tools there and it updates whenever a tool is added to their character
Then access that table on player leave
Honestly id say using a player object would simplify it by like,
99999%
a month lol
Oh I see thats good progress
thanks man
Do you know about services?
No i mean like
** You are now Level 2! **
LOL yes those
oh yea
Have you heard of Knit?
Id really recommend dabbling in Knit using Services/Controllers and using OOP classes
But for now,
Ok so do this
At the top of your code define a table something like
local playerTools = {}
yep
So now you have a table that will hold all the tools right
So now when you add a player you do player.PlayerAdded:Connect(function(player)) and inside it do
playerTools[player.UserId] = {}
like this
So now your table holds a reference to the player and sets up a table for it
Yessir!
Do plr lol
oh so the table saves the userid
oh ye
yep
Now you wanna save the tools they get right
You have the tools in replicated storage?
in the backpack or the character
so whenever a tool is added
Add it to the table
At Player.UserId
So like for example
wait isnt local playerTools = {}
is a table for a list of userid?
since it is playerTools[plr.UserId] = {}
Its a table that holds UserId's, that holds tables
Its a table inside a table
So it looks like this
is this like metatable or smth, correct me if im wrong xd
playerTools = {
[UserId] = {"sword","shield"},
[AnotherUserId = {"sword"},
[UrUserId] = {"hammer"},
}
It looks like that
Lowkey i dont exactly know what it means but i know exactly how it works
ohhhhhh
oh oh oh ok
So basically you have a table holding userId's, that holds a table that has their tools!
So now you can do,
character.ChildAdded:Connect(function(child))
And then you can check if its a tool,
Bro your post has 150 replies mine dont even have one
LOL
xdxd
Im teaching 🙏🏽
Then you do,
If child:IsA("tool") then
playerTools[player.UserId] = child
Boom!
where do i put character.ChildAdded:Connect(function(child))
On player added
liek i have to crete a character
oh
okok let me digest it rq
Well would you check mine if youre available?
like this?
oh close
** You are now Level 3! **
its plr.CharacterAdded:Connect character and thenn character.ChildAdded!
You wanna check what gets added inside the "character" 😁
imma send an example
** You are now Level 9! **
lol is it like this
heck yeah now you do one for the backpack
but you wanna make sure the child doesnt already excist
wait so what did i just did 
ok wait
you wanna check the backpack instead actually
so when a child is added to the backpack, add it to the table
ok wait hold
i totally forgot its a table
lol
ok let me send an example hold
alr alr
OK
here we go
you have to use table.insert not playerTools[player.UserId] since itd overwrite the table with the child woopsies
ok so basically that saves all the tools to the playerTools table
WAIT.
important question
are you storing like, multiple instances of the same tool
multiple instance?
like what are you putting in the inventories
oh
i got some cloned tools
same tools
the most frustrating problem all along is I am unable to save the tool if the player is holding the tool, since it got removed from the player's backpack. Otherwise every single tool in the backpack when i leave remains when i rejoin lol
yeah lol i get that
i struggled with saving tools for my grow a garden clone game with scaling tools
that shit took me so long to figure out 🤣
lmao
lowkey just copy this honestly
local Players = game:GetService("Players")
local playerTools = {}
local function addTool(player, tool)
local tools = playerTools[player.UserId]
-- Avoid duplicates
for _, t in ipairs(tools) do
if t == tool then return end
end
table.insert(tools, tool)
end
local function removeTool(player, tool)
local tools = playerTools[player.UserId]
for i = #tools, 1, -1 do
if tools[i] == tool then
table.remove(tools, i)
break
end
end
end
local function trackTools(player)
playerTools[player.UserId] = {}
local function onToolAdded(tool)
if tool:IsA("Tool") then
addTool(player, tool)
-- Connect to removal to keep table accurate
tool.AncestryChanged:Connect(function(child, parent)
if not parent then
removeTool(player, tool)
end
end)
end
end
local backpack = player:WaitForChild("Backpack")
backpack.ChildAdded:Connect(onToolAdded)
backpack:GetChildren() -- in case tools already there
for _, tool in ipairs(backpack:GetChildren()) do
onToolAdded(tool)
end
local function onCharacterAdded(character)
character.ChildAdded:Connect(onToolAdded)
for _, tool in ipairs(character:GetChildren()) do
onToolAdded(tool)
end
end
if player.Character then
onCharacterAdded(player.Character)
end
player.CharacterAdded:Connect(onCharacterAdded)
end
Players.PlayerAdded:Connect(trackTools)
this entire thing keeps track of tools
then when you need to access them just do local tools = playerTools[player.UserId]
and then do for _, tool in ipairs(playerTools[player.UserId] do functionystuff end
this saves the tool?
ok hi
local Players = game:GetService("Players")
local playerTools = {}
local function addTool(player, tool)
local tools = playerTools[player.UserId]
if not tools then return end
-- Avoid duplicates
for _, t in ipairs(tools) do
if t == tool then return end
end
table.insert(tools, tool)
end
local function removeTool(player, tool)
local tools = playerTools[player.UserId]
if not tools then return end
for i = #tools, 1, -1 do
if tools[i] == tool then
table.remove(tools, i)
break
end
end
end
local function trackTools(player)
playerTools[player.UserId] = {}
local function onToolAdded(tool)
if tool:IsA("Tool") then
addTool(player, tool)
tool.AncestryChanged:Connect(function(_, parent)
if not parent then
removeTool(player, tool)
end
end)
end
end
local backpack = player:WaitForChild("Backpack")
backpack.ChildAdded:Connect(onToolAdded)
for _, tool in ipairs(backpack:GetChildren()) do
onToolAdded(tool)
end
local function onCharacterAdded(character)
character.ChildAdded:Connect(onToolAdded)
for _, tool in ipairs(character:GetChildren()) do
onToolAdded(tool)
end
end
if player.Character then
onCharacterAdded(player.Character)
end
player.CharacterAdded:Connect(onCharacterAdded)
end
Players.PlayerAdded:Connect(trackTools)
Players.PlayerRemoving:Connect(function(player)
print("PlayerRemoving for", player.Name)
local tools = playerTools[player.UserId]
if tools then
print("Tools count:", #tools)
for i, tool in ipairs(tools) do
-- do thing save to datastore
end
playerTools[player.UserId] = nil -- cleanup
else
print("No tools tracked for this player")
end
end)
how it is gonna save without data store service
what do you mean 
** You are now Level 4! **
you add it 
🤯
ok lowkey i think i just made this a lot more complicated than needs be
OK
i got a bare bones version with absolutely no safety made!
local Players = game:GetService("Players")
local playerTools = {}
Players.PlayerAdded:Connect(function(player)
playerTools[player.UserId] = {}
player.CharacterAdded:Connect(function(character)
local backpack = player:WaitForChild("Backpack")
for _, child in pairs(backpack:GetChildren()) do
if child:IsA("Tool") then
print("CHILD ADDED")
table.insert(playerTools[player.UserId], child)
end
end
for _, child in pairs(character:GetChildren()) do
if child:IsA("Tool") then
print("CHILD ADDED")
table.insert(playerTools[player.UserId], child)
end
end
backpack.ChildAdded:Connect(function(child)
if child:IsA("Tool") then
print("CHILD ADDED")
table.insert(playerTools[player.UserId], child)
end
end)
character.ChildAdded:Connect(function(child)
if child:IsA("Tool") then
print("CHILD ADDED")
table.insert(playerTools[player.UserId], child)
end
end)
end)
end)
Players.PlayerRemoving:Connect(function(player)
local tools = playerTools[player.UserId]
if tools then
for _, tool in ipairs(tools) do
print(tool.Name)
end
playerTools[player.UserId] = nil
end
end)
literally all this does is logs what tools the player has
so keep your script as it was
but this would be the playerAdded script
and then when the player removes,
the tools will be inside playerTools[player.UserId]
oops forgot 1 safety
when i recieve the tools, it printed child added and when i leave it printed the tool name
local Players = game:GetService("Players")
local playerTools = {}
local function toolAlreadyTracked(tools, tool)
for _, t in ipairs(tools) do
if t == tool then
return true
end
end
return false
end
Players.PlayerAdded:Connect(function(player)
playerTools[player.UserId] = {}
player.CharacterAdded:Connect(function(character)
local backpack = player:WaitForChild("Backpack")
for _, child in pairs(backpack:GetChildren()) do
if child:IsA("Tool") and not toolAlreadyTracked(playerTools[player.UserId], child) then
print("TOOL ADDED")
table.insert(playerTools[player.UserId], child)
end
end
for _, child in pairs(character:GetChildren()) do
if child:IsA("Tool") and not toolAlreadyTracked(playerTools[player.UserId], child) then
print("TOOL ADDED")
table.insert(playerTools[player.UserId], child)
end
end
backpack.ChildAdded:Connect(function(child)
if child:IsA("Tool") and not toolAlreadyTracked(playerTools[player.UserId], child) then
print("TOOL ADDED")
table.insert(playerTools[player.UserId], child)
end
end)
character.ChildAdded:Connect(function(child)
if child:IsA("Tool") and not toolAlreadyTracked(playerTools[player.UserId], child) then
print("TOOL ADDED")
table.insert(playerTools[player.UserId], child)
end
end)
end)
end)
Players.PlayerRemoving:Connect(function(player)
local tools = playerTools[player.UserId]
if tools then
for _, tool in ipairs(tools) do
--TODO
--DO SOMETHING WITH DATA STORE HERE EX SAVING
end
playerTools[player.UserId] = nil
end
end)
it got 1 extra tool when i hold the tool
yeah i forgot to make sure the child doesnt already exists
so what you have to do for tracking tools is constantly check
yep
- scan through backpack / character first
then 2. listen for new children added / when the tool is destroyed
so actually your script becomes this long now!
oh zamn
yep
gotta account for
everything
where it says TODO save tools to data store save the tools there
yep alr
basically just do everything you were already doing
how about when player is added
but use that to keep track of the tools, and save them on player leave
what do you mean
yeah just do exactly what you were doing
alr
but use that seperately to
save the tools in a table
and then use the table on player leave
ok ill try
am i right for this
sadly not
wait how did you save it before
did you save each individual tool by doing
data:SetAsync(player, tool)
before
im not gonna lie i have never dabbled in DataStore but i have dabbled in everything else
ok wait nvm i got it
so player.UserId, then playerTools[player.UserId]
this makes sense but confusing at the same time 😭
ok im gonna dm you hold on
alr
accept my friend request