Understanding OOP

Tutorial on the basics of OOP.

by fhiwora

Author Avatar

What is OOP?

Object Oriented Programming (OOP) is a paradigm used to keep large projects organized, which is done using

objects. Whether you realized it or not, you've more than likely used objects in the past! Pretty much

everything in Roblox is an object, or better known to you as an "instance". Instances are just another word for objects in rbx.lua.

Let's look at a real world example, dogs for example. What do dogs do a lot? Bark. What are some attributes

to a dog? Their fur color, what breed they are, what size they are. What else is there about dogs? No dog

is like another dog!

Just from the example of a dog, you've learned three important parts about what makes up an object in coding.


That an object is unique from other objects.


What an object can do.


What an object looks like and/or what features it has.

In rbx.lua we use ModuleScripts to store stuff like classes, so make sure you use them when creating classes.

Getting down to work

When creating an object in another language you would usually create a class- a class is just a template

for creating an object -but in lua we do not have classes.

You may wonder how we would get around this to implement OOP into lua. Well that's easy! In lua

we have a feature called "metatables" and "metamethods" which allows coders of lua to implement new features

easily to the language. After all, lua is a language that's meant to be added onto.

A metatable is a table of functions that controls how a different table acts. And metamethods are functions

that are stored inside a metatable. To see a list of metamethods please see the metatables article on the

Roblox Wiki.

Now let's get down to setting up our class with metatables and metamethods.

local dog = {}
dog.__index = {}

so we first create a table called dog, then we set the .**index of that table back to that table. We can

do this because that table is empty so there's no harm in setting the __index to the same table.

.**index is a metamethod that is called whenever we add a new key to the table, so it will add that

function or variable automatically to any object we create.

Let's continue.

local dog = {}
dog.__index = {}

function dog.create(name, color, size, breed)

 local object = setmetatable({

  name = name,

  color = color,

  size = size,

  breed = breed

 }, dog)

 return object


return dog

What's been done now is that we made a "create" function to create a dog object. We also made a table that

contained the variables "name", "color", "size", and "breed". These variables' values are set according to the parameters in the function. The table's metatable is then set to the dog table that way it will be able to use any methods and variables we set to the dog table.

We return the object so we can have access to that object, it's properties, it's methods, and anything else

we add to it.

We also return the dog table so when we require the ModuleScript we can access everything inside from other

modules or scripts.

Adding behavior to our objects

Now that we have the very basis of our class setup, let's add some functionality to it!

local dog = {}
dog.__index = dog

function dog.create(name, color, size, breed)

 local object = setmetatable({

  name = name,
  color = color,

  size = size,

  breed = breed

 }, dog)

 return object


function dog:bark()

 print(self.name .. ": woof!")


return dog

So now you've probably noticed a few different fews. Instead of using a . operator for the bark function, we used the : operator.

We do this so we can use the "self" variable that allows us to access other methods

and variables that belong to that specific object, we'd also call that method with the : operator

and any other methods that use it. However, variables are accessed with the . operator.

So in this example, we use the self operator to access the name of the dog.

Using our class in another script

Since we can't use ModuleScripts in this Tutorial, we'll pretend we created that ModuleScript and that it is

stored in ReplicatedStorage and the name of the ModuleScript is "dog".

local replicatedStorage = game:GetService("ReplicatedStorage")
local dogClass = require(replicatedStorage.dog)

local rex = dogClass.create("Rex", "yellow", "medium", "Golden Retriever")
rex:bark() --prints "Rex: woof!"

local lola = dogClass.create("Lola", "brown", "small", "Apple Head Chihuahua")
lola:bark() --prints "Lola: woof1"

What we did here was get the ReplicatedStorage service, then we required the dog ModuleScript as the dogClass

variable. Then we created a dog object from the dog class named Rex under the rex variable,

and called the bark method on Rex. And finally, we then created another dog object from the dog class named

Lola under the lola variable and then called the bark method on Lola.

As you can see when we call the bark method on those two different objects, it prints two different strings:

"Rex: woof!" and "Lola: woof!".

Final notes

When requiring a ModuleScript do remember that it will take on the form of whatever type of script required it.

If a Script required it the ModuleScript would error if there was any LocalScript only code in there. And same

with LocalScripts, any code meant only for Scripts would error in a ModuleScript required by a LocalScript.

And if a ModuleScript was required by another ModuleScript and however far back it went on the require, it

would only be able to use the code meant for whichever type of Script required all those ModuleScripts.


-Create a cat class with name, color, breed, and size variables with a meow method -Make a base dog class that can be inherited by another class that is specific breed. (Don't worry if you can't

do this, inheritance is a bit hard to do for beginners of OOP, but you should be able to do this theoretically

even as a beginner.)

-Make a person class with a name, job, race, and hair color variables with speak, sleep, eat, and work methods

View in-game to comment, award, and more!