Introduction to OOP in Roblox Luau - Ep. 1

This coding solution will revolutionize the way you code and take your code to another level. Organized, fluid and modular code, easier to manage, extensible, feature-rich, bug-proof.

Introduction to OOP in Roblox Luau - Ep. 1

Introduction

We will dive into the fundamentals of Object-Oriented Programming (OOP) using Luau, Roblox's scripting language. In this advanced course, you'll learn how to achieve the power of OOP to create more organized, efficient, and scalable code for your games. This course will take you from understanding the core concepts of classes and objects to practical examples that will have you coding like a pro.

Table of Contents

  1. Understanding Object-Oriented Programming (OOP)
  2. Creating Your First Class using OOP
  3. Working with Objects
  4. Inheritance in Luau
  5. Polymorphism in Luau
  6. Conclusion

Understanding Object-Oriented Programming (OOP)

Object Oriented Programming (OOP) is a programming concept that is essential for effective game development in Roblox. We will explore key concepts such as classes, objects, inheritance, and polymorphism, and discuss their significance in creating organized and efficient code.

Key Concepts of OOP

Weapon Module Script
local Weapon = {}
Weapon.__index = Weapon  --> we refrence the table we want to pull the information from.


--// Create new class
function Weapon.new(name, damage)
    local self = setmetatable({}, Weapon)
    self.name = name
    self.damage = damage --> set the damage to 50
    return self
end

--// This method will attack the character dealing the set damage
function Weapon:attack(character)
  character.Health -= self.damage --> will deal 50 hp
end

--// Creating an object (instance) of the Weapon class (with damage = 50)
local sword = Weapon.new("Classic Sword", 50) 
  1. Classes
    • Think of a class as a blueprint for a house. It defines the structure and features of the house but is not the house itself. In programming, a class defines the properties (attributes) and behaviors (methods) of objects.
    • Example: A Weapon class might have attributes like damage and attackSpeed, and methods like attack().
  2. Objects
    • An object is an instance of a class, similar to how a specific house is built from a blueprint. Each object can have unique values for its attributes.
    • Example: If you create a Pet object named Cat it might have health = 100 and speed = 10.
  3. Inheritance
    • Inheritance allows one class to inherit properties and methods from another, promoting code reuse. It’s like a child inheriting traits from their parents.
    • Example: A Animal class could be a superclass, with Dog and Cat as subclasses that inherit common characteristics and behaviors.
  4. Polymorphism
    • Polymorphism enables different classes to be treated as instances of a common parent class. It allows methods to be defined in a way that they can be overridden or overloaded in subclasses.
    • Example: Both Dog and Cat classes might have an :speak() method, but each can implement it differently based on their unique behaviors or properties.

Why OOP Matters in Game Development?

According to a recent survey on the Roblox Dev Forum, 78% of top-performing games use OOP principles in their codebase. This isn't just a coincidence – OOP offers several advantages:

  • Improved code organization: Keep related functionality together
  • Easier maintenance: Change one class without breaking others
  • Code reusability: Use the same class across different projects
  • Scalability: Add new features without major refactoring

Technical Concepts Made Simple

  • Analogy: Imagine a video game as a city. Each building (class) has its own purpose and design, while the people (objects) living in those buildings have unique characteristics. Inheritance is like a family tree, where children (subclasses) inherit traits from their parents (superclass).

Pros and Cons of OOP

  • Pros:
    • Easier to manage and scale code.
    • Efficient collaboration among developers.
    • Improves code readability and organization.
  • Cons:
    • Can introduce complexity if not used properly.
    • May have a steeper learning curve for beginners.
    • May not always be the best solution for every problem, like for small and simple scripts.


Creating Your First Class using OOP

In this section, we'll explore how to build the blueprints for your game objects. We'll cover the basic class structure, constructor methods, instance methods, and static methods.

In Luau, we create classes using tables and metatables(regular Lua table that defines how certain operations on another table should behave) inside modules. Let's break down the process of creating a class in Luau:

Step 1: Basic Module Structure

Create a new module script in ServerScriptService and name it MyClass for example.

When first creating a module you should see something like this:

ModuleScript Module Script
local Module = {}

return Module

Let's rename these to MyClass:

MyClass Module Script
local MyClass = {}

return MyClass

Step 2: Setting up OOP Structure

Now this is an essential part, we index the MyClass table to itself using __index. What it will do is it will get called when you try to access a key that doesn't exist in a table. If the key is not found in the table and there's an __index metamethod, Lua will call this metamethod instead of returning nil .

MyClass Module Script
local MyClass = {} --> This is a table
MyClass.__index = MyClass --> all info will be pulled from this table.


return MyClass

Step 3: Class Creation

Next, we will create a constructor method that will serve as our new class. This method will return a new instance of the MyClass class.

MyClass Module Script
local MyClass = {} --> This is a table
MyClass.__index = MyClass --> all info will be pulled from this table.

//Creation of new class
function MyClass.new(name, type, properties)
    local self = setmetatable({}, MyClass) --> Create a new table and set its metatable to MyClass
    return self
end


return MyClass

Notice that I use self as a variable in the code. It’s not just any variable; it’s a special one! self is used inside methods of a class to refer to the specific object (or instance) that is calling the method. Think of it as a way for the object to talk about itself. (I will explain it in more detail later)

Now, you might wonder, "What are methods?" A method is simply a function that belongs to a class or an object. For example, you might have a function that looks like this: MyClass.Describe(). In contrast, a method looks like this: MyClass:Describe().

We will then create a table that contains the name and type variables. These variables are initialized with values based on the parameters passed to the function. The metatable of this table is set to MyClass, allowing it to access any methods and properties defined in the MyClass table:

MyClass Module Script
local MyClass = {} --> This is a table
MyClass.__index = MyClass --> all info will be pulled from this table.


function MyClass.new(name, type, properties)
    local self = setmetatable({}, MyClass) --> Create a new table and set its metatable to MyClass
    self.name = name --> Set the name property
    self.type = type --> Set the type property
    self.properties = properties --> Set the properties property (this will make sense later, trust me)
    return self
end


return MyClass

Step 4: Creating Method

Finally once the constructor method is in place, we can start creating custom methods like :Describe() . Notice again that the method uses : and not . this is because the colon syntax (or : if your prefer) automatically passes the instance (referred to as previously mentioned: self) as the first argument to the method. This allows the method to access properties and other methods of the instance directly. Here it is in place:

MyClass Module Script
local MyClass = {} --> This is a table
MyClass.__index = MyClass 


function MyClass.new(name, type, properties)
    local self = setmetatable({}, MyClass) 
    self.name = name
    self.type = type 
    self.properties = properties
    return self
end

function MyClass:Describe() --> We add a new method
    return "This is a " .. self.type .. " named " .. self.name
end

return MyClass

If you're still confused, then that is how the function looks like: myObject.Describe() and that is how the method looks like: MyClass:Describe().

Working with Objects