DataStore not saving/storing tools in the player's inventory

Hi, so I made a script that save tools (with a little help from tutorials). It was working fine before but suddenly, it stopped saving my tools. Anybody know what’s happening to my script?
Here’s the toolsave script:

local ds = game:GetService("DataStoreService"):GetDataStore("ToolSave")
game.Players.PlayerAdded:Connect(function(plr)
	local key = "id-"..plr.UserId
	pcall(function()
		local tools = ds:GetAsync(key)
		if tools then
			for i,v in pairs(tools) do
				local tool = game.ServerStorage.ToolsFolder:FindFirstChild(v)
				if tool then
					tool:Clone().Parent = plr:WaitForChild("Backpack")
					tool:Clone().Parent = plr:WaitForChild("StarterGear")
				end
			end
		end
	end)
end)

game.Players.PlayerRemoving:Connect(function(plr)
	local key = "id-"..plr.UserId
	pcall(function()
		local toolstosave = {}
		for i,v in pairs(plr.Backpack:GetChildren()) do
			if v then
				table.insert(toolstosave, v.Name)

			end
		end
		ds:SetAsync(key, toolstosave)
	end)
end)
1 Like

You cannot save instances (like Models, Parts and Tools) in a table inside a DataStore. You may only save strings, numbers and other tables. Try saving the name of the tool instead, then reference the name of the tool to clone the toolname into the player’s backpack.

1 Like

Sorry late reply, anyways, it still won’t work sadly… But do you have any more solutions other than that? Maybe it might help.

I think you could probably make a ModuleScript inside ReplicatedStorage with IDs for each tool, just so you could save them to your datastore once the player leaves, it would also take up less data than saving it by their name. I can probably get you an example in a minute.

1 Like

This is not something that will make it suddenly work (probably), but try to get the children from StartarGear from a player instead of Backpack.

Also your pcalls are bad. They don’t retry, they won’t warn, try adding some functionality.

1 Like

Okay, found a basic setup for you, hopefully you can learn from it from now on.

Module Script:

local Index = 1
local Tool = nil

local Tools = {}

local NewTool = function(name)
	local data = {
    	ID = Index,
    	Name = name,
	}
	
	table.insert(Tools, Index, data)
	Index = Index + 1
	
	return data
end

Tool = NewTool("Sword")
Tool = NewTool("Wand")

return Tools

Note: Please make sure to keep adding the tools in the order, if you add something in the middle or above another tool, then it’ll mess up the order. Always place a new one below the last tool, of course you can improve this system, though.

Server Script:

local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")

local ToolsData = DataStoreService:GetDataStore("ToolsData") -- Your datastore
local Tools = require(ReplicatedStorage:WaitForChild("Tools")) -- The module inside ReplicatedStorage
local ToolStorage = ServerStorage:WaitForChild("ToolStorage") -- Folder with the tools

local function GetToolById(id)
	local tool = nil
	for _, v in pairs(Tools) do
		if v.ID == id then
			tool = v.Name
		end
	end
	
	if tool and ToolStorage:FindFirstChild(tool) then
		tool = ToolStorage:FindFirstChild(tool)
	else
		tool = nil
	end
	
	return tool
end

local function ConvertToId(name)
	local id = nil
	for _, v in pairs(Tools) do
		if v.Name == name then
			id = v.ID
		end
	end
	
	return id
end

local function DataStoreRetry(dataStoreFunction)
	local tries = 0
	local success = false
	local msg = nil
	local data = nil
	repeat
		tries = tries + 1
		success, msg = pcall(function()
			data = dataStoreFunction()
		end)
		if not success then
			print(msg)
			wait(1)
		end
	until tries >= 3 or success
	
	if not success then
		warn("Could not access DataStore! Warn players that their data might not get saved!")
	end
	
	return success, data
end

local function GetToolsData(key)
	return DataStoreRetry(function()
		return ToolsData:GetAsync(key)
	end)
end

local function SaveToolsData(key, data)
	return DataStoreRetry(function()
		ToolsData:SetAsync(key, data)
	end)
end

Players.PlayerAdded:Connect(function(player)
	local key = "tools_" .. tostring(player.UserId)
	local success, data = GetToolsData(key)
	if not player.Character then
		repeat
			wait()
		until player.Character or not player.Parent
	end
	if success and data and player:FindFirstChild("Backpack") then
		for _, v in pairs(data) do
			local tool = GetToolById(v)
			if tool then
				tool:Clone().Parent = player.Backpack
			end
		end
	end
end)

Players.PlayerRemoving:Connect(function(player)
	local key = "tools_" .. tostring(player.UserId)
	local tools = {}
	if player:FindFirstChild("Backpack") then
		for _, v in pairs(player.Backpack:GetChildren()) do
			local found = ConvertToId(v.Name)
			if found then
				table.insert(tools, found)
			end
		end
		local success = SaveToolsData(key, tools)
		if success then
			print("Data saved for " .. tostring(player.Name) .. "!")
		else
			warn("Couldn't save " .. tostring(player.Name) .. "'s data!")
		end
	end
end)

Let me know if it works, even though it worked perfectly for me.

2 Likes