How would OOP I implement into game logic?

So I’ve recently been learning OOP, and I understand the basics of it. However I’m unsure on how I would apply it to an inventory system, while having a list of valid items that can exist, preventing items that don’t exist within the game’s assets to be made? How could I apply it to an effect system with predefined functions and particle effects? I’ve tried to research on how OOP would be applied physically and I’ve only seen tutorials showing what OOP can do but not how to do aside from showing basic OOP knowledge such as printing values and not applying them to a genuine system. So I’ve been unsure on how I would go about to applying it to a game’s logic.

The object-oriented inventory systems I’ve written typically served as container objects that I can populate with item objects. These objects then contain an item id and quantity, along with any other attributes unique to that stack of item, and then those can be read and written by game logic. I think I might need more details on your situation in order to give better insight though

Example ContainerSlot object
--// A slot object stored in container objects
local ContainerSlot = {}
ContainerSlot.__index = ContainerSlot

function ContainerSlot.new(itemId : string, quantity : number)
	local self = setmetatable({}, ContainerSlot)
	
	--// Ideally you'd store item properties like display names, descriptions, or rarities-
	--// defined in another module by the item id
	self._itemId = itemId 
	self._slotQuantity = quantity

	return self
end; export type ContainerSlot = typeof(ContainerSlot.new()) 
--// ^ this is just for lazy typechecking/autocomplete within OOP methods
--// you don't need to keep the type definitions or define the methods with dot syntax like I do

function ContainerSlot.getItemId(self : ContainerSlot) : string
	return self._itemId
end

function ContainerSlot.setQuantity(self : ContainerSlot, newQuantity : number) : ()
	self._slotQuantity = newQuantity
end

function ContainerSlot.incrementQuantity(self : ContainerSlot, increment : number) : ()
	self._slotQuantity += increment
end

return ContainerSlot
Example Container object
local Container = {}
Container.__index = Container

function Container.new()
	local self = setmetatable({}, Container)
	
	self._slots = {}
	
	return self
end; export type Container = typeof(Container.new())

--// Used for reading container contents, use the set or add methods below for writing
function Container.getAllContents(self : Container) : {ContainerSlot}
	local allContents = {}
	for slotNum, slotContents in self._slots do
		allContents[slotNum] = slotContents
	end
	
	return allContents
end

function Container.getContentsInSlot(self : Container, slotNum : number) : ContainerSlot
	return self._slots[slotNum]
end

function Container.setContentsInSlot(self : Container, slotNum : number, newSlotContents : ContainerSlot)
	self._slots[slotNum] = newSlotContents
end

function Container.addContents(self : Container, slotContents : ContainerSlot)
	self:setContentsInSlot(#self._slots + 1, slotContents)
end

return Container
Example code using the above objects
local playerInventory = Container.new()
local newItems = {
	ContainerSlot.new("item", 1),
	ContainerSlot.new("another_item", 5),
}

for _, newContents in newItems do
	playerInventory:addContents(newContents)
end

print(playerInventory:getAllContents())
3 Likes

I see now. Would you say it’s better optimized utilizing OOP with ItemIDs or using a basic inventory system with a module script with basic functions instead? Or is it all really just preference?

If you mean optimization in regards to performance, I wouldn’t say it’s something to worry about in this context. For simplicity, I wouldn’t recommend a wholly OOP approach like my examples show if you want your inventory accessible across the server and client and would instead recommend a modular approach using instances.

It is possible to handle replication yourself using remotes or something like loleris’ Replica module, but to me it’s an extra step that can be skipped without much consequence by just utilizing Instance replication. sleitnick made a good video about the OOP replication conundrum, it’s a good watch

So for the modular approach I recommend, I forked an old system I wrote for an RPG project I was working on and trimmed it down to its essentials. I wouldn’t say it’s complete, but it served my needs pretty well. It client side of it is missing because it’s mostly just UI code, but since it’s all instances, you can just listen to the container folders and value instances for any changes
forked inventory.rbxl (77.7 KB)
The code may be tricky to understand at a glance, so if you have any questions feel free to ask

1 Like

Ok thank you for the help out! I’ve been trying to learn on when using OOP would be good, I’ve initially wanting to use instance based modular system instead since it’s more accessible, and preferably easier to make. However was unsure if it was better to use OOP or an instance based system and if it would be better optimized using OOP instead of instances.

Thanks alot again for explaining it to me!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.