Help I wanna Place Tools in a Specific Slot in The Players Backpack

I Have This Script That Overhauls The Default Roblox Backpack, Design to Fit for a FPS game i making
but i’m pretty stumped as to why it randomized the players Inventory
and i wanna fix this randomized Tool Slots

i have 2 scripts that’s Reasonable For The players Backpack thing

This Server script Saves The Players Tool After Death

local Players = game:GetService("Players")

Players.PlayerAdded:connect(function(Player)

	Player.CharacterAdded:connect(function(Character)
		local Backpack = Player.Backpack
		local Humanoid = Character:WaitForChild("Humanoid")

		Humanoid.Died:connect(function()

			--< setup (porential) equipped tool for save
			Humanoid:UnequipTools()

			--< clear old tool save	
			local StarterGearGetChildren = Player.StarterGear:GetChildren()
			for Tools = 1, #StarterGearGetChildren do
				StarterGearGetChildren[Tools]:Destroy()
			end		

			--< save new tools
			local Backpack = Player.Backpack
			local BackpackGetChildren = Backpack:GetChildren()
			for SavedTools = 1, #BackpackGetChildren do
				BackpackGetChildren[SavedTools].Parent = Player.StarterGear
			end
		end)
	end)
end)

And This Localscript is responsible for The overhaul Backpack

wait()
local Teams = game:GetService("Teams")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Weapons = ReplicatedStorage:FindFirstChild("Weapons")
local Primary = Weapons:FindFirstChild("Primary") -- Folders Full of tools
local Secondary = Weapons:FindFirstChild("Secondary") -- Folders Full of tools
local Special = Weapons:FindFirstChild("Special") -- Folders Full of tools
local RoundValue = ReplicatedStorage:FindFirstChild("RoundValue")
local RunService = game:GetService("RunService")
local Inventory = {}
local CurrentToolSlot = 1
local CurrentTool = nil
local FPS_INVENTORY = script.Parent
local Backpack = LocalPlayer:WaitForChild("Backpack")
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()

if LocalPlayer.Team == Teams:FindFirstChild("Main menu") then
	game.StarterGui:SetCoreGuiEnabled("Backpack", false)
elseif LocalPlayer.Team == Teams:FindFirstChild("ingame") then
	if UserInputService.TouchEnabled then
		FPS_INVENTORY.Parent.Enabled = false
		if not game:GetService("StarterGui"):GetCoreGuiEnabled("Backpack") then
			game:GetService("StarterGui"):SetCoreGuiEnabled("Backpack", true)
		end
	elseif UserInputService.KeyboardEnabled then
		if FPS_INVENTORY.Parent.Enabled == false then
			FPS_INVENTORY.Parent.Enabled = true
		end
		game.StarterGui:SetCoreGuiEnabled("Backpack", false)
	elseif RoundValue.Value <= 5 then
		game.StarterGui:SetCoreGuiEnabled("Backpack", false)
	else
		FPS_INVENTORY.Parent.Enabled = false
		if not game:GetService("StarterGui"):GetCoreGuiEnabled("Backpack") then
			game:GetService("StarterGui"):SetCoreGuiEnabled("Backpack", true)
		end
	end
end

local tooltable = {} -- make a clone tool table

task.wait(0.1)

local keys = {
	One = 1,
	Two = 2,
	Three = 3,
	Four = 4,
	Five = 5,
	Six = 6,
	Seven = 7,
	Eight = 8,
	Nine = 9,
	Zero = 10,
}

local GetMouse = LocalPlayer:GetMouse()


local timeUntilInvis = 0

function ToolRemoved(tl)
	if tl:IsDescendantOf(Backpack) then
		return false
	end

	if tl:IsDescendantOf(Character) then
		return false
	end

	return true
end

function AssignTool(tool)
	if tool:IsA("Tool") and not table.find(Inventory, tool) then
		table.insert(Inventory, tool)
		local frame = FPS_INVENTORY:FindFirstChild(tool.Name)
		if not frame then
			frame = script:WaitForChild("item"):Clone()
			if Primary:FindFirstChild(tool.Name) then
				frame.Name = 1
			elseif Secondary:FindFirstChild(tool.Name) then
				frame.Name = 2
			elseif Special:FindFirstChild(tool.Name) then
				frame.Name = 3
			end
			frame.Parent = FPS_INVENTORY
		end
		frame.ToolObject.Value = tool
		frame.ToolName.Text = tool.Name
		frame.ImageButton.Image = tool.TextureId

		timeUntilInvis = 0
		SetAllSlotNumbers()
	end
end

for _, frame in pairs(FPS_INVENTORY:GetChildren()) do
	if frame:IsA("Frame") then
		local toolName = frame.Name
		local toolExists = false
		for _, tool in pairs(Inventory) do
			if tool.Name == toolName then
				toolExists = true
				break
			end
		end
		if not toolExists then
			frame:Destroy()
		end
	end
end

function SetAllSlotNumbers() -- Update slot numbers
	if #Inventory == 0 then 
		return 
	end

	for _, tool in pairs(Inventory) do
		local frame = GetItemFrameByReference(tool)
		frame.NumberSlot.Text = "["..table.find(Inventory, tool).."]"
	end
end

function GetItemFrameByReference(t) -- Get item frame by a tool
	for _, v in pairs(FPS_INVENTORY:GetChildren()) do
		if v:FindFirstChild("ToolObject") then
			if v.ToolObject.Value == t  then
				return v
			end
		end
	end

	return nil
end


function HighlightEquipped() -- Highlight frame that contains a tool which is currently equipped
	for i, v in pairs(FPS_INVENTORY:GetChildren()) do
		if v:FindFirstChild("ToolObject") then
			if v.ToolObject.Value == CurrentTool then
				v.BackgroundColor3 = Color3.fromRGB(188, 182, 152)
			else
				v.BackgroundColor3 = Color3.fromRGB(39, 36, 34)
			end
		end
	end
end


for i, v in pairs(Backpack:GetChildren()) do
	if v:IsA("Tool") then
		if i == 1 then
			CurrentTool = v
			v.Parent = Character
		end
		AssignTool(v)
	end
end

for _, tool in pairs(Inventory) do
	local frame = GetItemFrameByReference(tool)
	if frame then
		if frame.Name == "1" then
			tool.Parent = Character
			CurrentTool = tool
			HighlightEquipped()
		end
	end
end


function UnequipGears()
	for i, tool in pairs(Character:GetChildren()) do
		if tool:IsA("Tool") then
			tool.Parent = Backpack
		end
	end
end

function EquipGear(n)
	if not Inventory[n] or #Inventory <= 1 then return end

	UnequipGears()
	Inventory[n].Parent = Character
	CurrentTool = Inventory[n]

	HighlightEquipped()
end

function onObjRemove(t) -- Check if a tool was removed from the player completely
	if t:IsA("Tool") then
		local frame = GetItemFrameByReference(t)
		if ToolRemoved(t) and frame then
			table.remove(Inventory, table.find(Inventory, t))
			frame:Destroy()
			SetAllSlotNumbers()
			timeUntilInvis = 0
		end
	end
end
function onObjAdded(t) -- Check if the tool is new
	if t:IsA("Tool") then
		if not table.find(Inventory, t) then
			AssignTool(t)
			if t.Parent == Character then
				CurrentTool = t
				HighlightEquipped()
			end
			SetAllSlotNumbers()
		end
	end
end

Character.ChildRemoved:Connect(onObjRemove)
Backpack.ChildRemoved:Connect(onObjRemove)

Character.ChildAdded:Connect(onObjAdded)
Backpack.ChildAdded:Connect(onObjAdded)



UserInputService.InputBegan:Connect(function(i, p)
	if p then return end

	if keys[i.KeyCode.Name] then
		timeUntilInvis = 0
		EquipGear(keys[i.KeyCode.Name])
		CurrentToolSlot = keys[i.KeyCode.Name]
	end
end)

GetMouse.WheelForward:Connect(function()
	timeUntilInvis = 0
	local thing = CurrentToolSlot + 1
	if Inventory[thing] then
		EquipGear(thing)
		CurrentToolSlot = thing
	else
		CurrentToolSlot = 1
		EquipGear(1)
	end
end)

GetMouse.WheelBackward:Connect(function()
	timeUntilInvis = 0
	local thing = CurrentToolSlot - 1
	if Inventory[thing] then
		EquipGear(thing)
		CurrentToolSlot = thing
	else
		CurrentToolSlot = #Inventory
		EquipGear(#Inventory)
	end
end)

while task.wait(0.05) do

	if LocalPlayer.Team == Teams:FindFirstChild("Main menu") then
		game.StarterGui:SetCoreGuiEnabled("Backpack", false)
	elseif LocalPlayer.Team == Teams:FindFirstChild("ingame") then
		if UserInputService.TouchEnabled then
			FPS_INVENTORY.Parent.Enabled = false
			if not game:GetService("StarterGui"):GetCoreGuiEnabled("Backpack") then
				game:GetService("StarterGui"):SetCoreGuiEnabled("Backpack", true)
			end
		elseif UserInputService.KeyboardEnabled then
			if FPS_INVENTORY.Parent.Enabled == false then
				FPS_INVENTORY.Parent.Enabled = true
			end
			game.StarterGui:SetCoreGuiEnabled("Backpack", false)
		elseif RoundValue.Value <= 5 then
			game.StarterGui:SetCoreGuiEnabled("Backpack", false)
		else
			FPS_INVENTORY.Parent.Enabled = false
			if not game:GetService("StarterGui"):GetCoreGuiEnabled("Backpack") then
				game:GetService("StarterGui"):SetCoreGuiEnabled("Backpack", true)
			end
		end
	end


	if UserInputService.TouchEnabled == false then

		timeUntilInvis += 0.025

		if timeUntilInvis >= 1 then
			FPS_INVENTORY.Visible = false
		else
			FPS_INVENTORY.Visible = true
		end
	else
		FPS_INVENTORY.Visible = false
	end

end

this is the model of it
HUD.rbxm (13.5 KB)

1 Like

Use LayoutOrder if you are using UIListLayout.
LayoutOrder is property of any visisble UI element which dictates layout order in list elements.
If you are not using UIListLayout(which I’d recommend because it does alot of the scaling work for you) then you might have to do some additional sorting.

1 Like

im not talking about the Ui , i’m talking about the script how it randomizes the inventory slots every time you reset.

1 Like

The “issue” is the use of pairs, it gets children in somwhat random order, therefore what you can do is
Request tools, put them in array, sort the array in any order by the name of the tools, or any other.

Edit: What I meant is :GetChildren(). That is the issue.
Please elaborate further if this is not what you wanted

2 Likes