Can you create actual classes and how?

Yeah true what is true OOP and false OOP if it does the same thing why should we consider them differently ?

Doing :

ClassTable = {
    new = function(self,x,y)
        local object = setmetatable({},{__index = self})
        object.x = x
        object.y = 2 * x
        return object

newObject = ClassTable:new(2)

is essentially the same thing as doing :

class myClass():
    def __init__(self,x,y):
         self.x = x
         self.y = 2 * x
myClassObject = myClass(2)

I wouldn’t put a difference on them, what I’m referring to is saying Lua doesn’t have classes while saying Python and/or JS do; all 3 have support for it. OOP is the broader scope of the subject. If you can have a mutable state that can be used by functions, you ideally have OOP. I’m debating against what was mentioned here Lua supposedly can’t have classes while Python can.

1 Like

Oh okay I (think I) get it, you mean that everything that could be used as OOP is OOP

Okay, in a way, but again I wasn’t referring to OOP in general. OOP is very broad and can be applied almost anywhere; this just dragged on and away from what I was first discussing, which was:

Although lua does have built-in classes. It just doesn’t let you create classes.

Actually I kinda don’t get it are metatables classes ?

Metatables aren’t really classes, they’re a way that you can create custom classes.

Take a look at this article:

If you want an example of how metamethods can be used to “create” classes, I used it in my party system. Here’s the constructor for a “Party object”

	local self 			= setmetatable({}, {
		__index = party,
		__tostring = function(self)
			return self.leader.Name .. "'s Party. Members: " .. self:GetMemberCount()
	self.leader 		= player
	self.members 		= {[player] = true}
	AddParty(self) -- adds this party to a collection of parties so we can loop through them or something
	return self

So first of all, all tables can have metatables.

Metatables are tables of customized methods which control what should happen when you try an unknown operation on the table.
For example: table + 1 invokes the __add method in its metatable, and table() invokes the __call method.

For classes, whenever you index a table via table[index] or table.index, you invoke the __index method. If the value assigned to this method is a table, then that table is indexed if the original table does not have it.

This is incorrect. Only tables explicitly given a metatable via setmetatable have a metatable.


Metatables are basically classes right or are they an interpreted way to do it ?

Does it necessarily have to be a class? You could always use Tags via CollectionService instead.

They are an interpreted way to do it, pretty much, yeah.

There are several equivalent ways of emulating OOP in lua. Metatables are the correct way, this is the alternative:

Functions are equivalent to objects as you can return other functions from them (the technical term is a “closure”, read the Wikipedia article if you want to know more.) These are in some ways stronger than metatables because they allow you to have private properties and methods, but tend to be slower because Lua is optimized for metatables. Take the following constructor as an example

function Thing(prop1, prop2)
    local self
    local function PrivateMethod1(a)
        prop1 = prop1 + a
        return prop1
    self = {
        publicprop3 = 0,
        PublicMethod1 = function(b)
            self.publicprop3 = self.publicprop3 + 1
            return prop2 + PrivateMethod1(b)
    return self

For usage:

local thing = Thing(2,3)
thing.publicprop3 = 5

If you need to extend a “class” I suggest you wrap and delegate instead (this applies to metatable based oop as well). Extension is unnecessary in a duck typed language like lua.


Although it does effectively the same thing it’s three time longer than using metatables or python ‘Classes’
It’s not quite equivalent but more an attempt of copying classes properties.

Lua is not an OOP language and doesn’t have classes or inheritance. The Roblox platform is what makes the environment OOP. The workflow can be achieved in any language given you implement it yourself and with metatables you can get pretty close syntax wise as well. For further reading: PIL-16

That depends on what is being done. CollectionService is not necessarily an appropriate alternative for classes, depending on what it is you’re trying to accomplish.

(I went with a Wikipedia link that I thought was relevant because it seems to be a common location to go to. Feel free to look up resources or reading material on classes on the Internet that aren’t Wikipedia - perhaps directly on sites for coding languages instead.)

1 Like

No. Metatables themselves aren’t classes; they’re useful when it comes to object-oriented programming because of the __index metamethod, which allows for inheritance. Using a prototype-based approach (wherein classes don’t exist; everything is an object, and prototype objects act as the blueprint/template for other objects), the system usually falls along the lines of:

Code-wise, this would look something like:

-- Object
local Object = {}
function Object:new()
    local o = {}
    local mt = {__index = self}
    setmetatable(o, mt)
    return o

-- Object > Animal
local Animal = Object:new()
Animal.X = 0
function Animal:Walk(distance)
    self.X = self.X + distance

-- Object > Animal > Dog
local Dog = Animal:new()
function Dog:Bark()
    print("You hear a 'woof' from " .. self.X .. " studs away.")

-- example:
local dog1 = Dog:new()
local dog2 = Dog:new()

dog1:Bark() --> You hear a 'woof' from 10 studs away.

dog2:Bark() --> You hear a 'woof' from 0 studs away.

Although this approach does not provide real privacy, it is commonly seen as the simplest and most lightweight method; I personally prefer it.


Yes, that’s true metatable aren’t class although they are similar.

They are not; they just provide extra functionality to data. There’s really no such thing as a ‘metatable’ either - they’re just a table that has been assigned the metatable of some datum through setmetatable.