Need feedback for a custom inventory im making

I’m writing this to get some feedback from people to see on what can be improved, here is the code, it currently works only on pc, has no proper inventory other than the toolbar and only has 9 slots instead of 10, that’s all.

Here’s the code:

-- // Variables \\ --
local Gui = script.Parent
local NumSlots = Gui.Holder:GetChildren()

local Players = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local StarerGui = game:GetService("StarterGui")

local Player = Players.LocalPlayer

local Backpack = Player.Backpack
local Character = Player.Character or Player.CharacterAdded:Wait()

local Booleans = {
	ShowInventory = false
}

local KeyboardNumKeys = {Enum.KeyCode.One, Enum.KeyCode.Two, Enum.KeyCode.Three, Enum.KeyCode.Four, Enum.KeyCode.Six, Enum.KeyCode.Seven, Enum.KeyCode.Eight, Enum.KeyCode.Nine}
local Slots = {
	[1] = {Equipped = false, Tool = nil, KeyBoardNum = "One"},
	[2] = {Equipped = false, Tool = nil, KeyBoardNum = "Two"},
	[3] = {Equipped = false, Tool = nil, KeyBoardNum = "Three"},
	[4] = {Equipped = false, Tool = nil, KeyBoardNum = "Four"},
	[5] = {Equipped = false, Tool = nil, KeyBoardNum = "Five"},
	[6] = {Equipped = false, Tool = nil, KeyBoardNum = "Six"},
	[7] = {Equipped = false, Tool = nil, KeyBoardNum = "Seven"},
	[8] = {Equipped = false, Tool = nil, KeyBoardNum = "Eight"},
	[9] = {Equipped = false, Tool = nil, KeyBoardNum = "Nine"}
}

local CurrentTool = nil

-- // Functions \\ --
local function DisableDefaultInventory()
	StarerGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
end

local function GetNextAvailableSlot()
	for i = 1, #NumSlots do
		if Slots[i].Equipped == false then
			return i
		end
	end
end

local function ChangeSlotState(State, Slot: Frame)
	if State == "Active" then
		Slot.BackgroundTransparency = 0
		Slot.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	elseif State == "Idle" then
		Slot.BackgroundTransparency = 0
		Slot.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	elseif State == "Innactive" then
		Slot.BackgroundTransparency = 0.5
		Slot.BackgroundColor3 = Color3.fromRGB(56, 56, 56)
	end
end

local function ShowInnactiveSlots(Enabled)
	for _, v in ipairs(NumSlots) do
		if v:IsA("Frame") and v:GetAttribute("State") == "Innactive" then
			v.Visible = Enabled
		end
	end
end

local function EnableInventory(InputName, InputState)
	if InputName == "EnableInventory" and InputState == Enum.UserInputState.Begin then
		if not Booleans.ShowInventory then
			ShowInnactiveSlots(true)
			Booleans.ShowInventory = true
		else
			ShowInnactiveSlots(false)
			Booleans.ShowInventory = false
		end
	end
end

local function BindKeyboardNumKeys(InputName, InputState, InputObject)
	if InputName == "BindKeyboardNumKeys" and InputState == Enum.UserInputState.Begin then
		for i, v in ipairs(Slots) do
			if InputObject.KeyCode == Enum.KeyCode[v.KeyBoardNum] then
				local AvailableSlot = GetNextAvailableSlot()
				print(AvailableSlot)
				break
			end
		end
	end
end

local function BindMouseButton()
	for _, v in ipairs(NumSlots) do
		if v:IsA("Frame") then
			local Button = v:FindFirstChild("TextButton")
			
			if Button then
				local SlotName = string.sub(v.Name, 2, 2)
				local IntName = tonumber(SlotName)
				
				Button.MouseButton1Click:Connect(function()
					for i, v in ipairs(Slots) do
						if IntName == i then
							local AvailableSlot = GetNextAvailableSlot()
							print(AvailableSlot)
							break
						end
					end
				end)
			end
		end
	end
end

local function ListenForBackpackItems(Item)
	if Item:IsA("Tool") then
		
	end
end

local function ListenForCharacterItems(Item)
	if Item:IsA("Tool") then
		
	end
end

-- // Connections \\ --
DisableDefaultInventory()
ContextActionService:BindAction("EnableInventory", EnableInventory, false, Enum.KeyCode.Backquote)
ContextActionService:BindAction("BindKeyboardNumKeys", BindKeyboardNumKeys, false, table.unpack(KeyboardNumKeys))
BindMouseButton()
Backpack.ChildAdded:Connect(ListenForBackpackItems)
Character.ChildAdded:Connect(ListenForCharacterItems)
4 Likes

You could use OOP to handle the inventory and the slots, there would be an InventoryManager that would handle Slots and UI, with the Slot also being a class of its own. You may want to look into the possibility of having the ability to rebind keys to the slots instead of having hardcoded KeyboardNumKeys. I also believe that once your character respawns, your character variable will be pointing to nil, so you should handle that. Also in BindMouseButtons, I would avoid having to use string.sub or tonumber to handle the state of the slot.

2 Likes

Hey there. You’ve got a solid start for creating an inventory system ngl, and potentially expanding it to a far more advanced version if you’d like to and if thats in ur plans ofc. Structure is clean and easy to read, and the fact that you’re using ContextActionService rather than UserInputService is a good habit :+1:. However, I’d fix that StarerGui before it develops to a real pain. Your GetNextAvailableSlot() function is returning the first unequipped slot rather than the first empty one, which might cause problems once the player starts assigning their toosl, instead of if Equipped == false it’s make more sense directly checking Tool == nil. Also, Enum.Keyboard.Five is skipped in ur binds xd, asides from that tho great code

Are you sure? Cus I’ve heard in the IAS announcement that ContextActionService will be sunsetted (basically deprecated) in the future (Although I’m not sure the entire devforum is aware of this).

  • Is Roblox sunsetting CAS?
    • Yes, we plan to sunset CAS in the future. Sunsetting means that your existing code will continue to work, but we will not make any changes to functionality, effectively deprecating the API for future use. All functionality that CAS supports will be supported by IAS before we sunset it. If you use CAS, we highly recommend migrating to IAS.

So just in case… you should use either UserInputService or its instance-based cousin, InputActionService.

2 Likes