Saving tools data with DataStore2

I made an adaptation on the script written originally by Shiro75, so that it would work with DataStore2 for saving tools data. When i add or remove tools on the player´s backpack, the data is saved. However, the last tool present at the player´s backpack is never removed. How can i solve this issue? Here is the code:

local library = game:GetService("ServerStorage").toolFolder
local DataStore2 = require(game:GetService("ServerScriptService").MainModule)
--< directory functions

local dir = {}

local function edit(player, list)
	dir[player.Name] = list
end

local function setup(player, list)
	for i = 1, #list do
		local tool = library:FindFirstChild(list[i])
		if tool then
			local clone = tool:Clone()
			clone.Parent = player.Backpack
		else
			print(list[i] .. " not found")
		end
	end
end

--< player events

game.Players.PlayerAdded:connect(function(player)

local ready = false

	player.CharacterAdded:connect(function(char)
	local toolsDataStore = DataStore2("Tools_", player)
	local bp = player.Backpack
	local data = nil
	
	if ready == false then
		ready = true
		
		data = toolsDataStore:Get(nil)
		
		if data then
			setup(player, data)
			edit(player, data)
		end
	end	
	
	--< adjuster
	
	local count = 0
	
	local function adjust()
			
		local list = {}
		local toolsDataStore = DataStore2("Tools_", player)
		local equipped = char:FindFirstChildOfClass("Tool")
		if equipped then
			table.insert(list, equipped.Name)
			toolsDataStore:Set(list)
		end	
	
		local tools = bp:GetChildren()
		for i = 1, #tools do
			table.insert(list, tools[i].Name)
			toolsDataStore:Set(list)
		end
	
		if count ~= #list then
			edit(player, list)
			count = #list
		end
	end

		--< child events
	
	bp.ChildAdded:connect(adjust)	
	bp.ChildRemoved:connect(adjust)	
	
	char.ChildAdded:connect(function(child)
		if child.ClassName == "Tool" then
			adjust()
		end
	end)
	
	char.ChildRemoved:connect(function(child)
		if child.ClassName == "Tool" then
			adjust()
		end
	end)	
	end)
end)
2 Likes

I’m not sure if DS2 can save models/tools. What I do is have it save an inventory which has the name and other data saved as objects and when the player wants to equip it it gets the tool from serverstorage and has them equip it.

The data that represents the tool is sucessfully saved and loaded with the script that i have presented using DS2. The only problem is that the last tool always remains and i can´t figure out how to get rid of it.

  1. Can you give me the name of the last tool?
  2. Where is it not disappearing from? The list? The datastore?

1- It doesn´t really matter the name. Suppose i have Tool1 and Tool2. If i delete Tool2, the Tool1 will remain, and vice-versa.
2- Its not disappearing from the datastore. If i leave the game and come back again, 1 tool will always remain. If i add more tools, leave and come back again, the number of tools will be correct, the problem only happends when removing the tools until the last one.

When the player joins, can you unpack the value from the datastore and print it? Also when setting the datastore can you unpack that too and print it?
if you don’t know what unpacking is, here’s an example
print(unpack(workspace:GetChildren()))
The above should print all of the children in the workspace.

hmm, i will try that, let me see…

Yes, it prints the name of a tool

In this specific case the name printed was sword

Can you play around with adding, removing tools, and rejoining and keep the prints stored somewhere like a txt file?

Yes, i can do that. One moment plz.

Hi there, could you properly format your code to use a codeblock so we can read it better (more formatting details here)? If you want to remove the tool and save it when the player leaves, you should be using the PlayerRemoving event. Could you better explain what you want to happen and what really happens?

Hi Qxest, i have edited the code and included the codelock as requested, thanks for the orientation! I believe may not be using the PlayerRemoving event because of how the DataStore2 module works. What i want to happend is that when a tool is removed, it will not remain in the player´s backpack when i leave and rejoin the game. For example: If i have 3 tools on the players backpack: Tool1, Tool2 and Tool3. If i remove Tool3, leave and rejoin the game, Tool1 and Tool2 will be in the game. That is the expected behaviour. However, if i keep removing until the last one, the very last tool will always remain when i rejoin the game. In summary, i can´t get rid of the last tool.

What do you mean by this exactly? How are you removing the last tool? You do know if a tool is equipped it’s not in Backpack but in the player’s character in Workspace.

I mean completely removing from the players backpack, and also not present in the character as an equipped tool. As if the tool is on the player backpack and then i use Destroy() or ClearAllChildren() on the backpack.

Sorry, I may be a bit slow here to understand. Just so I can see what’s going on, can you confirm that the adjust function is being called by sticking a print statement right above it. If it is being printed as you remove the 3rd tool, there is a problem with how you’re saving your tools (your code is unnecessarily complex btw). You keep saying you’re removing the last tool but I don’t see where in your code you’re doing that. All I see is that you’re saving it every time you call adjust and use the same datastore over and over. You probably don’t even need to do this, just update the datastore when the player leaves rather than every time his or her tools update.

I am removing by other means, that are not on this code (i mean by another script). But i made a print() on the adjust function as you suggested. I can get the print at everytime i add or remove a tool, except when it´s the last tool…

Regarding the fact that the script do not save only when the player leaves, is an attempt to prevent data loss, as explained here How to use DataStore2 - Data Store caching and data loss prevention
I understand that this may be a controversial method, but i have decided to give it a try.

What’s this line supposed to do? You won’t get any data if it’s nil.

The nil is because the module that i am using allow the use of a default value, and if you don´t want to use any default value you set it to nil.