Metatables don’t have anything to do with the colon method. OO basically means an object (table) not only stores data but methods (functions defined in objects) too, there is no need of metatables.
Even if there are metatables implemented, the colon method has nothing to do. Perhaps, what you are referring to instead, is the self argument, that might be used mostly with metatables (still doesn’t have to do anything with them).
You can recreate the traditional “Roblox OOP” without metatables:
local function new()
local self = {}
self.Name = "MichaelMyers"
local secret = "eat burgers"
function self:SaySecret()
print("I really want to", secret)
end
return self
end
Really simple example that I used, a good guide can be found here, too. You can search about entity-component systems (data oriented) if you wanna stop depending on OO.
If you have read the guide and you are still not convinced, remember that metatables act like “hooks”. An example of this is the metamethod __index returning a table, which means you would technically be indexing twice, when you could just do it once.