An in depth look at OOP - Roblox LUA

To begin, let us talk about what OOP is; Object-Oriented Programming is a form of programming in which objects are used instead of loose-leaf code. This programming form has many benefits, including making development easier to maintain and update, simulating real-world use, slightly higher memory but increased organization, reusability, and sustainability.

If you understand these concepts by heart, you will be able to find a job in the software development industry. Keep in mind OOP programming is not understood by some people thus knowledge on such a topic is exponentially useful long term.

There are four fundamental principles to follow in OOP, Encapsulation, Abstraction, Inheritance, and Polymorphism. These all play an essential role in making OOP a practical and useful form of development; hence why many big tech corporations use OOP in their development.

Before continuing, please note in OOP, functions are referred to as methods. Methods represent the transfer of messages/data or procedures associated with a class. Methods essentially are what a function does in an object/class. Also, note what a superclass is. A superclass is a class that will inherit from a class. For example, I have a CarSuperClass; this superclass contains all of the functions needed for every car in my game. Instead of assigning all of the variables and methods needed in each car class, I can inherit from the CarSuperClass.

Now let us take a more in-depth look to see what these four principles are.

Encapsulation is the idea that we can hide direct access to data by using a private key while using available methods. This principle is more used in C#, C++, Java, and Python; however, it is usable in Lua. An example in Roblox would be that I had a PlaneClass; only the pilot would have access to fly the plane in this class. Therefore, we give the pilot a key directly from the server to the pilot’s client so only the intended user can access data. The pilot can only call the fly function with his private key, leading to only Encapsulation.

Abstraction is the idea that we only want the user or client to see its functionality rather than its framework. This principle allows users to see what the code does instead of how the code works. For example, I have a PlayerData superclass; I have methods that deal directly with saving and loading player data in this class. When the player joins, the player object/instance will inherit from the new data object I have created. Furthermore, instead of having a script that indirectly deals with player data, the class now directly deals with player data.

Inheritance is one of OOP programming’s essential principles; this principle is the idea of the relationship between 2 or more classes. If I were to create a class that deals with player combat and then created a character class, I would inherit the player combat class inside the character class. By doing this, I no longer need to define the combat methods in the character class as I am inheriting all that the combat class methods. This inheritance shortens and organizes code and makes code easier to maintain and update in the long term.

Polymorphism is the idea an object can act or behave in many ways. The most common use we see in modern development is in Java; this occurs when a class references a variable that refers to a child class. An example of this would be to create a player data superclass that contained a method called SaveData. Then if I were to inherit this class in a character class, we would have an inheritance. Now the character class has the SaveData method. If I were to change this SaveData function to add health instead of saving data, polymorphism would be.

Now that we have the four fundamental principles in OOP, we need to learn how to achieve OOP in Lua. In Lua, to achieve OOP-like functionality, we use a unique table called a metatable. These tables give us the ability to create methods and classes that can follow the four principles.

Now, what is a metatable? Metatables are tables that allow us to change behavior. Metatables can define how Lua computes expression, as well as global functions. Even though each table in Lua has its metastable, we would still need to define and expand upon the table using setmetatable and using the given metamethods.

Lets start with the most simple form of metatables.

local Table = {} -- Here we can see a table that we just made. Now we need to add functionality to it.
--[[
To do this we need to use metamethods. There is a list of metamethods on the roblox WIKI; the metatable page lists all of their uses and how to use them.
]]

--Lets start with the first step. We will be using the .__index metamethod.
--[[This method allows us to check if the index is in the given table; if they are not, it will index itself. However, if there is no reference present, then it will return nil.]]

Table.__index = Table -- We refrence the table we want to pull the information from.

--[[
Now that we have setup the index function we can add methods to the table.
]]
--Lets start with our constructor.

function Table.New(Name, Shape, Size, Color)
 -- here we create our init method. This creates the class once called.
	return setmetatable({
		Name = Name;
		Shape = Shape;
		Color = Color;
		Size = Size;
	}, Table)
end

local Object = Table.New("Apple", "Square", "55", "Green")
local Red_Object = Table.New("Red Apple")
print(Object.Size) -- 55, here we can print out this objects properties by indexing them.
print(Red_Object.Name) -- Red_Object, we can make as many objects as we want; they will all have different data.

Now we know what a class looks like. However, how can we use the four principles that we mentioned earlier? Good question, ill show you.

This is an example of Encapsulation:

local Plane_Class = {} -- we init our table

Plane_Class.__index = Plane_Class -- we make the index

--[[
Note the usage of : instead of .  The key : is used when calling self or the object that the function is called from. The key . is used when init the class.
]]


function Plane_Class.New() -- we make our constructor to make the class
	return setmetatable({
	Key = "ABC_DE_ADF_A123";	
	},Plane_Class)
end


function Plane_Class:FlyPlane(PKey) -- make the fly method
	if self.Key == PKey then
		print("Take off vrrrr")
	end
end



local Plane = Plane_Class.New() -- create the plane object
Plane.__metatable = "Locked" -- here we lock the MT so it cannot be changed
Plane:FlyPlane(Plane.Key) -- we attempt to fly the plane, this will print Take off

This is an example of Abstraction:

local PlayerDataClass = {}

PlayerDataClass.__index = PlayerDataClass




function PlayerDataClass.New(P)
	return setmetatable({
	Player = P;	
	}, PlayerDataClass)
end


function PlayerDataClass:SaveData()
	print("Do stuff with data brrr")
end



function PlayerDataClass:LoadData()
	print("Do more stuff with data")
end


--Player joining

local Player_1 = PlayerDataClass.New("Jimbo_123xx")
local Player_2 = PlayerDataClass.New("Legendary_Foxx2015")
Player_1:SaveData() -- Save Data
Player_2:LoadData() -- Load data

This is an example of Inheritance :

local PlayerCombat = {}-- setup our inherit table
local CharClass = setmetatable(PlayerCombat, {}) -- setup our 2nd object to inherit with

CharClass.__index = CharClass -- index the new object we created so we can get all the functions

function PlayerCombat.New(Player) -- create new player combat constructor
    return setmetatable({
        Player = Player;	
    }, PlayerCombat)
end


function PlayerCombat:Fight() -- we  make a fight function that will be inherited
    print("Pow Pow")
end

function CharClass.Spawn() -- spawn function
    return setmetatable({
        CharHealth = 100;	
    }, CharClass)
end

function CharClass:Heal() -- heal function
    print("Heal stuff :D")
end


local CharClass = CharClass.Spawn() -- create a char class.
print(CharClass:Heal()) -- call the heal method
print(CharClass:Fight()) -- we call the inherited fight function


Polymorphism will not really have a needed use in Lua; It is good to know; however, I have never really had a reliable use. If you were to spend time learning C++ or Java, then this would be important. However, given the context of Lua and its limitations, there is no practical use.

Suppose you stayed till the end of this short tutorial on OOP, then congrats! You know everything you need to know for the first two years of a CS degree.

86 Likes

Very informative and enhanced my knowledge on the subject, good job!

3 Likes

This Section made understanding OOP a whole lot easier, thank you.

1 Like

You should mention that you shouldn’t use it when you don’t need it. You gave an example of player data but should you really be making a class to save data?

You also mentioned that OOP gives lower memory which is something I’m not sure I agree with if you do not give more context. OOP in most cases uses more memory.

Roblox isn’t that type where OOP determines success and you should use it when the situation meets it.

OOP isn’t something you should avoid but you shouldn’t take it to the next level and use it for everything you do.

If I’m incorrect, feel free to correct me. I only skimmed through your resource so I can’t say too much. Happy Monday

3 Likes

The player data class is ment to hold data, save data, and load data. This is how it works; I showed that exact example because that is the real life use of using such OOP scripting. I also ment that it uses memory differently than regular procedural programming. However with this higher memory usage the gain is more sustainable and functional code. I rewrote the sentence that you were referring too.

I personally use OOP for almost everything that can use OOP; this may cause slight memory jumps but overall it is more effective to have code that is organized and easy to read.

I would also like to note that using OOP is almost definitely more clean and easier to change than the alternative. One of the main reasons that big techs use it; ofc there are other reasons but those are the main ones.

This was ment to show what you can do with OOP and also to give examples that can be used in real life programming. However that requires some critical thinking skills. I’m not going to give code they can just copy like Devking and AlvinBlox as that’s not how people learn.

I hope this answered your questions.

5 Likes

I don’t mean to bump but this tutorial is outstanding! currently taking notes.

3 Likes