I decided to use OOP because I like how I can simply call functions on it, however, there are a lot of OOP objects now and I’m nervous about memory since they all have tons of functions, some of them only being used twice.
For example, I have a crop system in my game. I use OOP so I can call :Grow() and :Die() and whatnot on it. However, it’s gotten to the point where I have all these functions for one single OOP object:
:Grow()
:Die()
:SetOwner() --all crops are owned by different players
:Initiate() --spawns the crop as a physical object, does some other init stuff too.
:Sell() --sells crop for money
:Wrap() --when the players 'base' is saved, it saves all the crops on it. this 'wrap' function is serialization that's used when their data is being saved.
:Cleanup() --removes all traces of whatever impact it has on the game.
Now this is one crop. However, my game has thousands of random crops spawning throughout the world and they all use this base OOP structure. I’m nervous about memory and performance because I might even add more functions (methods) in the future.
Am I overreacting? Or does this seem like it would cause performance issues? If so, what other logic can I use to avoid OOP but still have these functions on hand?
When using metatables for OOP and ModuleScripts, only 1 version of that ModuleScript's return value is created. Every subsequent call to require on that script will return the exact same value.
This means that your metatable that holds the functions for your “class” implementation, will only exist once in memory because all “instances” of your class use the same metatable.
This is of course assuming multiple things about your OOP implementation, a typical example of which is below:
local MyClass = {}
MyClass.__index = MyClass -- Automatically redirect to this table.
function MyClass.new()
local instance = {} -- Preferably create keys with the dictionary literal syntax.
-- Do what you will with the instance before setting its metatable and returning it.
return setmetatable(x, MyClass)
end
function MyClass:DoSomething()
print("Something has been done!")
end
return MyClass
This is a very basic implementation of OOP in Lua(u). There are more fancy things you can do such as obscuring/locking the metatable using __metatable, but the main take-away is that the new function reuses the exact same MyClass table as the metatable for all returned instances of the class. This means that DoSomething only ever exists once in memory.
You’re overreacting. The function is shared by all of them, no matter how many there are. If you have 9 methods, then you have 9 methods in RAM. If you have 1000 Crop objects each with the same 9 methods, then you have 9 methods stored in RAM.
The RAM usage will obviously go up with more objects being created, but not because of the functions.
Wish I could mark both as the solution, thank you.
I was going to start creating local functions inside of OOP modules to compensate for memory usage which would’ve turned into a storm of type checking and other nasty issues.