Bind to close help v2

This saves when i leave without equipping a tool and while its equipped, if i shutdown unequipped it saves as well but when the tool is equipped it wont save. I dont get why its not saving.
The script:

local dss = game:GetService("DataStoreService")
local toolsDS = dss:GetDataStore("ToolsDD3")
local toolsFolder = game.ServerStorage.ShopItems
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local toolsOwned = {}

game.Players.PlayerAdded:Connect(function(plr)

	local toolsSaved = toolsDS:GetAsync(plr.UserId .. "-tools") or {}

	for i, toolSaved in pairs(toolsSaved) do
		if toolsFolder:FindFirstChild(toolSaved) then 

			toolsFolder[toolSaved]:Clone().Parent = plr.Backpack
			toolsFolder[toolSaved]:Clone().Parent = plr.StarterGear 
		end
	end

	plr.CharacterRemoving:Connect(function(char)

		char.Humanoid:UnequipTools()
	end)
end)

game.Players.PlayerRemoving:Connect(function(plr)

	for i, toolInBackpack in pairs(plr.Backpack:GetChildren()) do
		table.insert(toolsOwned, toolInBackpack.Name)
	end

	local success, errormsg = pcall(function()
		toolsDS:SetAsync(plr.UserId .. "-tools", toolsOwned)


	end)
	if errormsg then warn(errormsg) end
end)


game:BindToClose(function()
	if RunService:IsStudio() then
		return
	end

	local players = Players:GetPlayers()
	for _, player in pairs(players) do
		local userId = player.UserId
		local data = toolsOwned[userId]
		if data then
			local success, result = pcall(function()
				toolsDS:SetAsync(userId, data)
			end)
			if not success then
				warn(result)
			end    
		end
	end
end)
1 Like

I didn’t read the entire script but I noticed that you are using pairs() for array iteration, you should use ipairs() instead. Am I right?

1 Like

Not calling you wrong, but, I use in pairs() all the time, and it works fine, but also I use that when I am using :GetChildren() or :GetDecendents() or for tables that I make using {}, I’ve never heard of ipairs()

1 Like

Equipped tools aren’t in the backpack. They get parented to the players character. So when you’re saving the tools you have to either do Humanoid:Unequiptools() or check the actual players character for a tool:

Character:FindFirstChildWhichIsA("Tool")

Also @loading you are correct. It’s better practice to use ipairs for arrays and pairs for dictionarys. It’s more of a micro optimization though.

Pairs and ipairs both work with arrays but you can’t use ipairs on a dictionary.

Could u tell me how i should include that in my script? Bc i dont get it

So this script saves if i shutdown but if they leave it wont save. It saves the old data somehow.

local dss = game:GetService("DataStoreService")
local toolsDS = dss:GetDataStore("IIIII")
local toolsFolder = game.ServerStorage.ShopItems

game.Players.PlayerAdded:Connect(function(plr)

    local toolsSaved = toolsDS:GetAsync(plr.UserId .. "-tools") or {}

    for i, toolSaved in pairs(toolsSaved) do
        if toolsFolder:FindFirstChild(toolSaved) then 

            toolsFolder[toolSaved]:Clone().Parent = plr.Backpack
            toolsFolder[toolSaved]:Clone().Parent = plr.StarterGear 
        end
    end

    plr.CharacterRemoving:Connect(function(char)

        char.Humanoid:UnequipTools()
    end)
end)

game.Players.PlayerRemoving:Connect(function(plr)
    local toolsOwned = {}

    for i, toolInBackpack in ipairs(plr.Backpack:GetChildren()) do
        table.insert(toolsOwned, toolInBackpack.Name)
    end

    for i,v in ipairs(plr.Character:GetChildren()) do
        if v:IsA("Tool") then
            table.insert(toolsOwned, v.Name)
        end
    end

    local success, errormsg = pcall(function()
        toolsDS:SetAsync(plr.UserId .. "-tools", toolsOwned)
    end)
            if errormsg then warn(errormsg)
    end
end)

I added this part

for i,v in ipairs(plr.Character:GetChildren()) do
        if v:IsA("Tool") then
            table.insert(toolsOwned, v.Name)
        end
    end

There’s a big difference between pairs() and ipairs()
ipairs() is for iterating between array elements such as :GetChildren() or :GetDescendants() return values and here’s its syntax:

for index, value in ipairs(ARRAY) do
    -- code
end

pairs() is for iterating between dictionary key-value elements and here’s its syntax:

for key, value in pairs(DICTIONARY) do
    -- code
end

Example:

local goodsCost = {
    ["Samsung Galaxy Note 7"] = 489.00;
    ["Nokia 3310"] = 39.99;
    ["Arduino Uno R3"] = 26.99
}

for key, value in pairs(goodsCost) do
    print(key.." costs "value"$")
end

Beacuse, the tool is in player’s Character when it’s held. You should get it by plr.Character:FindFirstChildWhichIsA("Tool")

Oh, I see, thanks for the information! Learn something new every time I look on the forum.