Can you create actual classes and how?

Metatable are pretty similar to classes I do think they are often use for the same thing in the same way it isn’t just sugar code.

How are metatables similar to classes?

As I just stated they are used in a very similar way to do the same thing.

I don’t see how they are. Classes act as a template/blueprint for the creation of objects. Metatables provide data with additional behaviour. Please explain your thoughts.

Metatables are more like Objects I do agree although I still think they can have Methods and Data and you can use them as a template to create multiple of them.

Metatables are neither objects or classes. It wouldn’t make sense for metatables to store methods or data in the same way that an object would; they exist only to provide metadata about data and change its behaviour. I don’t see how metatables can be used as a template, either.

A thing that store methods and data is basically an object or oop related

50 char

Metatables aren’t designed to hold methods or general data. Let’s take this to PMs.

If you want to have a kind of class-based workflow, you can have a Lua equivalent of a constructor, using the .new special method. This method is (by convention) used as a constructor. You may know it from calls such as

local frame =,0,0)

Here’s an example of how these are generally programmed:

  local self = setmetatable({}, MyClass)
  self.value = init
  return self

The return self line is the line which gives this constructor-like behaviour, as it returns an instance of that table and its methods. So, essentially, it returns an instance of the module. So, you can then use that object to access methods and fields as though you’re referencing an object.

self is a constructor method or setmetatable is ?..
or are both ?

Neither are a constructor on their own. The self keyword is simply a short way of a module referring to itself. For example:

local myClass = {}

local countOfCats = 0

function setCats(self, number)
    self.coundOfCats = number

The self property just allows the module to refer to itself. In returning it, you give the invoking script access to that too. This is why, for example, you can see the X value of a CFrame from the script which created it, but only after you created it with

self is not a keyword, though it is highlighted at such. It takes advantage of the colon sugar syntax.

Remember that this code:

function name:key(a, b)


Is sugar syntax for this code:

function name.key(self, a, b)


And that this code:

name:key(1, 2)

Is sugar syntax for this code:

name.key(name, 1, 2)

You can pass anything in.

name.key(something, 1, 2) -- something will be the self implicit argument

self is an implicit parameter.


A combination of newproxy and metatables is what I used to make “Classes” although they most likely would not satisfy the need of this post.