✓ Accepted answer
Data Stores cannot save instances themselves (A tool is an instance)
So, to save a player's backpack I put tools in the "ServerStorage" like so:
http://gyazo.com/3746b89ded1f686afb71ad8c97a935dc
local ds = game:GetService("DataStoreService"):GetDataStore("tools")
local defaultTools = {game.ServerStorage.Pistol,game.ServerStorage.Sword}
game.Players.PlayerAdded:connect(function(ply)
local key = "user_"..ply.userId
local playerTools = ds:GetAsync(key)
if playerTools == nil then
for i,t in ipairs(defaultTools) do
local newClone = t:Clone()
newClone.Parent = ply.Backpack
end
else
for i,pt in ipairs(playerTools) do
for i2,st in ipairs(game.ServerStorage:GetChildren()) do
if st.Name == pt then
local newClone = st:Clone()
newClone.Parent = ply.Backpack
break
end
end
end
end
end)
game.Players.PlayerRemoving:connect(function(ply)
local key = "user_"..ply.userId
local playerTools = {}
for i,b in ipairs(ply.Backpack:GetChildren()) do
table.insert(playerTools,b.Name)
end
ds:UpdateAsync(key,function(old)
return playerTools
end)
end)
When the player joins the game (when the "PlayerAdded" event is called) then the "GetAsync" is called to retrieve the player's saved backpack. If they haven't saved then the value will be nil. So, I created a table (defaultTools) that stores the Instances of Tools in the ServerStorage. This is looped through and adds to the player's backpack.
However, if the retrieved backpack is not nil then the stored values are names of tools. This is looped through, then looping through the children in ServerStorage and checking if the values are the same then if so, adding a clone of the Tool instance (in ServerStorage) to the player's backpack.
Then, when the player leaves ("PlayerRemoving") I looped through the player's backpack adding the tool's name to a table which is then saved using "UpdateAsync".
Hope this helps. I have tested and it works for myself.