Tool Saving Problem

Hello. I’m making a game right now. Part of this game requires a tool shop and I want these tools to save. They currently save on leave, but not on death before leaving and rejoining. I followed a youtube tutorial to try to attempt this, and this is the script that I wrote:

local toolfolder = game:GetService("ServerStorage"):FindFirstChild("SaveTools")
local dss = game:GetService("DataStoreService")
local saveddata = dss:GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(player)
	local tooldata = saveddata:GetAsync(player.UserId)
	
	local backpack = player:WaitForChild("Backpack")
	local startergear = player:WaitForChild("StarterGear")
	
	if tooldata ~= nil then
		for i, v in pairs(tooldata) do
			if toolfolder:FindFirstChild(v) and backpack:FindFirstChild(v) == nil and startergear:FindFirstChild(v) == nil then
				toolfolder[v]:Clone().Parent = backpack
				toolfolder[v]:Clone().Parent = startergear
			end
		end
	end
	
	player.CharacterRemoving:Connect(function(char)
		char:WaitForChild("Humanoid"):UnequipTools()
	end)
end)

game.Players.PlayerRemoving:Connect(function(player)
	local tooltable = {}
	
	for i, v in pairs(player.Backpack:GetChildren()) do
		table.insert(tooltable, v.Name)
	end
	if tooltable ~= nil then
		saveddata:SetAsync(player.UserId,tooltable)
	end
end)

The tools save when you leave and rejoin just fine. They just don’t save when you die before leaving and rejoining. If you die right after buying a tool, you will lose it. Anybody know how to fix this? :slight_smile:

Some tools are given to you if you’re in the group or own a gamepass so a save tool on death script just duplicates those ones.

3 Likes

save after death or save after leave?

2 Likes

I kinda want both, but this was to make tools save on leave. I actually made them save on leave. They only save when you die after you have left and rejoined after buying the tool. If you buy the tool and then jump in the void, they don’t save. I’ll update the post to the updated script.

1 Like

i think its because youre saving from the backpack, try saving from startergear instead
also if you need a better script to save tools after death:
this prevents accidentally removing tools with the same name etc

-- Notice: When a player picks up a tool or you equip the character with a tool, it will not work until it is unequipped and it goes to the Backpack
-- Also if you're adding a tool to StarterPack after the game first started then you need to give it a UniqueID Attribute beforehand
-- a19_9

for _,tool in pairs(game:GetService('StarterPack'):GetChildren()) do
	if not tool:IsA('Tool') then continue end
	if not tool:GetAttribute('UniqueID') then
		tool:SetAttribute('UniqueID', game:GetService('HttpService'):GenerateGUID(false))
	end
end

game:GetService('Players').PlayerAdded:Connect(function(plr)
	plr.DescendantAdded:Connect(function(newTool)
		if newTool:IsA('Tool') and newTool.Parent == plr.Backpack then
			if newTool:GetAttribute("DontSaveOnDeath") then
				return
			end
			
			if not newTool:GetAttribute('UniqueID') then
				newTool:SetAttribute('UniqueID', game:GetService('HttpService'):GenerateGUID(false))
			end
			
			for _,existingTool in pairs(game:GetService('StarterPack'):GetChildren()) do
				if existingTool:IsA('Tool') then
					if existingTool:GetAttribute('UniqueID') == newTool:GetAttribute('UniqueID') then
						return
					end
				end
			end
			
			local newClone = nil
			for _,existingTool in pairs(plr.StarterGear:GetChildren()) do
				if existingTool:IsA('Tool') then
					if existingTool:GetAttribute('UniqueID') == newTool:GetAttribute('UniqueID') then
						newClone = existingTool
						break
					end
				end
			end
			if not newClone then
				newClone = newTool:Clone()
				newClone.Parent = plr.StarterGear
			end

			newTool.AncestryChanged:Connect(function()
				if not plr:FindFirstChild('Backpack') then return end
				if newTool.Parent ~= plr.Backpack and newTool.Parent ~= plr.Character then
					local hum = plr.Character:FindFirstChildOfClass('Humanoid')
					if hum then
						if hum.Health > 0 then
							newClone:Destroy()
						end
					end
				end
			end)
		end
	end)
end)
1 Like

Is there anything I need to change about this script before replacing my old script with it?

not at all, it works like that. but it doesnt save after leave just when the character dies. also it automatically removes the tool from starterpack if you remove it from the character/backpack from the server or it gets destroyed (prevents duplication)

so keep your current script to save after leave and save from StarterGear instead of backpack
let me know if you encounter any problems

2 Likes

Okay, so my problem before was that it wasn’t saving on death. Saving on rejoin worked perfectly. In this script and other scripts I’ve tried before, other items like gamepass items duplicate because it saves them but also gives them on respawn. I’m pretty sure my original script needs to be altered to do the same thing it does on player leave on player death.

1 Like

then you should add a boolean attribute “DontSaveOnDeath” on the gamepass tools, wait ill send the updated script

1 Like

i updated the script, also make sure the attribute is set to true

1 Like

Ok, they now save on death fine, but not on leave. Do I use my original script for that?

1 Like

yes, the script doesnt save to the datastore so use yours. heres how i save tools using the script i gave you (just an example cause i use ProfileService)

Saving:

	if plr:GetAttribute("LoadedTools") then
		profile.Data["Tools"] = {}
		for _,tool in pairs(plr.StarterGear:GetChildren()) do
			if tool:IsA('Tool') then
				table.insert(profile.Data["Tools"], tool.Name)
			end
		end
	end

Loading:

	for _,toolName in pairs(profile.Data['Tools']) do
		local inRS = ReplicatedStorage.Tools:FindFirstChild(toolName)
		if inRS then
			inRS:Clone().Parent = plr.Backpack
		end
	end
	plr:SetAttribute('LoadedTools', true)
1 Like

So I just put my original code in a different script with the same parent?

Edit: When I do this, random things get duplicated cause some parts of both scripts are doing the same thing

1 Like

wdym by same parent? just use it on the same place you did before

local toolfolder = game:GetService("ServerStorage"):FindFirstChild("SaveTools")
local dss = game:GetService("DataStoreService")
local saveddata = dss:GetDataStore("SaveData")

game.Players.PlayerAdded:Connect(function(player)
	local tooldata = saveddata:GetAsync(player.UserId)
	
	local backpack = player:WaitForChild("Backpack")
	local startergear = player:WaitForChild("StarterGear")
	
	if tooldata ~= nil then
		for i, v in pairs(tooldata) do
            local RSTool = toolfolder:FindFirstChild(v)
			if RSTool then
				toolfolder[v]:Clone().Parent = backpack
			end
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	local tooltable = {}
	
	for i, v in pairs(player.StarterGear:GetChildren()) do
-- preferable check if v is a tool
		table.insert(tooltable, v.Name)
	end
	if tooltable ~= nil then
		saveddata:SetAsync(player.UserId,tooltable)
	end
end)
1 Like

Yeah I know, but what do I do with your script that saves on death now? Where do I put it? Is it part of this script?

Btw, if it’s not obvious by now, I’m not rlly an experienced scripter lol. Sry for wasting your time

1 Like

the script can either be in workspace or ServerScriptService

1 Like

So the last script that you posted is the whole script? (as in do i still need the one before? if so, where do i put it)

1 Like

this script is yours but i slightly modified it, so make 2 scripts one with that and the other with the other script then put both on ServerScriptService (you can see it on the explorer)
also remove the scripts you already had for this

1 Like

Ok that was what I assumed. I’ll do that and get back to you with a result. thanks

1 Like

Okay, It works, but when you die holding the tool, you lose it. So you kinda solved my problem, but do you know any way to fix this?

that shouldnt happen, do you have any other scripts that work with startergear? also if you directly give the tool to the humanoid or he picks it up it wont save until it goes to the backpack (he unequips it)

1 Like