OOP constructor in lua

I am making a custom BackpackGui instead of the default roblox one using OOP. Can you review my code to see if this is how you do a constructor in OOP?

ModuleScript:

local BackpackGui = {}

BackpackGui.__index = BackpackGui
--Static fields
BackpackGui.equipped = 0.2
BackpackGui.unequipped = 0.7
BackpackGui.iconSize = {x = 60, y = 60}
BackpackGui.iconBorder = {x = 15, y = 5} 


--constructor
function BackpackGui.new(player)
	local O = {}
	--Instance fields
	O.inputKeys = {["One"] = {txt = "1"},["Two"] = {txt = "2"},["Three"] = {txt = "3"},}
	O.inputOrder = {O.inputKeys["One"],O.inputKeys["Two"],O.inputKeys["Three"],}
	
	O.toShow = #O.inputOrder
	BackpackGui.totalX = (O.toShow*BackpackGui.iconSize.x)+((O.toShow+1)*BackpackGui.iconBorder.x)
	BackpackGui.totalY = BackpackGui.iconSize.y+(2*BackpackGui.iconBorder.y)
	--Now creates a a container for all the slots
	O.container = Instance.new("Frame")
	O.container.Position = UDim2.new(0.5, -(BackpackGui.totalX/2), 1, -(BackpackGui.totalY+(BackpackGui.iconBorder.y*2)))
	O.container.Size = UDim2.new(0, BackpackGui.totalX, 0, BackpackGui.totalY)
	O.container.Parent = player.PlayerGui
	--now creates the slots and place them inside the container
	for i = 1, #O.inputOrder do
		local value = O.inputOrder[i]		
		O.template = Instance.new("Frame")
		O.template.Name = value["txt"]
		O.Size = UDim2.new(0, BackpackGui.iconSize.x, 0, BackpackGui.iconSize.y)
		O.Position = UDim2.new(0, (i-1)*(BackpackGui.iconSize.x)+(BackpackGui.iconBorder.x*i), 0, BackpackGui.iconBorder.y)
		O.template.Parent = player.PlayerGui.container
		
		O.imageLabel = Instance.new("ImageLabel")
		O.imageLabel.Size = UDim2(1,0,1,0)
		O.imageLabel.Position = UDim2(0,0,0,0)
		O.imageLabel.Parent = player.PlayerGui.container
		
		O.textLabel = Instance.new("TextLabel")
		O.textLabel.Size = UDim2(0.4, 0, 0.4, 0)
		O.textLabel.Position = UDim2(0.2 ,0, 0.6, 0)
		O.textLabel.Parent = player.PlayerGui.container
	end
	setmetatable(O, BackpackGui)
end
2 Likes

It looks good to me. I come from Java so doing things like this makes so much more sense for me.

1 Like

Actually you might need to index them to keep up with the instances. Like backpack[player] or something.

1 Like

What do you mean by that ?? lan laeb abl baleb ale

Your constructor should return O. Also, if inputKeys and inputOrder are static, you should move them to an external variable or to BackpackGui.

4 Likes

They are not static, they are like the Model in MVP design pattern. Each BackpackGui need its own storage or else everybody would have the same exact storage.

I would say there is too much going on in the constructor. Move the code out into its own functions to help with the readability.

I am not too sure on why you have inputKeys and inputOrder can you not just use one nested array?

Is there any need to store O.toShow = #O.inputOrder. Would creating a function to get the value help?

You have also missed some of the .new after UDim2.

You may need to use WaitForChild for the playergui and container.

As a general rule I try not to create gui elements in code as it can be hard to maintain over time.

1 Like

The convention is usually to use “self” for the name of the table variable rather than O but functionally that doesn’t matter.

Given you are constructing GUIs, would it not be more beneficial to do this client side (and would therefore be seperate anyway)?

1 Like

Do you mean to move the moduleScript to the ClientSide and have a local script call it?

Not sure on your structure. PlayerScripts is usually the location for client side only stuff so yeah. There are some pretty cool inheritance tricks you can do from ReplicatedStorage with server/client versions if you wanted some sort of backpack knowledge on the server.

1 Like