Lua Inheritance Tutorial – Complete Guide

As game developers and coding enthusiasts, we often explore different programming languages and concepts that can enhance our skills and projects. One such concept in Lua, a lightweight and efficient scripting language widely used in game development, is ‘Inheritance’. Today, we delve deep into understanding Lua inheritance, illuminating its functions and increasing your knowledge of this valuable aspect of Lua. The journey will be both enlightening and fruitful, especially if you’re keen on mastering game development.

What is Lua Inheritance?

In simple terms, Inheritance is a principle in Object-Oriented Programming (OOP) that allows us to define a new class with techniques of an existing class. In Lua, which is not inherently an OOP language, we implement inheritance through ‘metatables’ and their ‘metatable events.’

Why is Lua Inheritance Important?

Learning about Lua inheritance is key for two reasons:

  • It aids in creating more structured and organized code, thus improving its readability and maintainability.
  • Inheritance in Lua provides us with a way to emulate object-oriented programming, enabling us to create ‘classes’ and ‘objects’ that are common in other OOP-based languages like C++ or Python.

As we step forward into the tutorial, we will learn about Lua inheritance through interesting code examples crafted around game mechanics. Let’s power up!

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Basics of Lua Inheritance

Let’s start our coding journey with understanding how to create basic tables in Lua.

-- Starting with a simple table
hero = {}
hero.abilities = "Super Strength"

-- Accessing Table Properties
print(hero.abilities)

Before we move to inheritance, it’s crucial to comprehend metatables. Metatables allow us to define the behaviour of a table for certain operations such as addition, subtraction, and others. This concept is vital for implementing inheritance in Lua.

-- Creating a Metatable
metaTable = {}
myTable = {}
setmetatable(myTable, metaTable)
print(getmetatable(myTable))

Now, let’s proceed to implement inheritance using metatables. We’ll create an ‘Enemy’ class and then extend it to a ‘Boss’ class using inheritance.

-- Defining the Base Class (Enemy)
Enemy = {health = 100, damage = 10}

-- Defining the Derived Class (Boss)
Boss = {}
setmetatable(Boss, {__index = Enemy})
print(Boss.health)

Through inheritance, the Boss class now has the properties of a Enemy class. This prevents redundant code and promotes code reuse, a significant advantage of object-oriented programming.

Advancing with Lua Inheritance

As we move further, let’s explore how to override properties and methods using Lua inheritance. This is another vital concept for game developers.

-- Defining Base Class (Enemy)
Enemy = {
    health = 100,
    damage = 10,
    setAttributes = function(self, health, damage)
        self.health = health or self.health
        self.damage = damage or self.damage
    end
}

-- Defining Derived Class (Boss)
Boss = {
    setAttributes = function(self, health, damage)
        Enemy.setAttributes(self, health or 1000, damage or 100)
    end
}

setmetatable(Boss, {__index = Enemy})

-- Now, let's create an object for Boss
boss1 = Boss
boss1:setAttributes()
print(boss1.health)

In the above code, we have overridden the ‘setAttributes’ function in the Boss class which is originally defined in the Enemy class. Overriding allows a derived class to provide a specific implementation of a function that is already offered by its base class. This is a fundamental concept in Lua inheritance and OOP in general.

Deep Dive into Lua Inheritance

Now, you’re familiar with the basics of Lua Inheritance and also how to override methods in a derived class. Let’s dive deeper and understand how to add new methods to derived classes and call parent class methods.

-- Defining Base Class (Enemy)
Enemy = {
    health = 100,
    damage = 10,
    setAttributes = function(self, health, damage)
        self.health = health or self.health
        self.damage = damage or self.damage
    end,
    attack = function(self)
        return self.damage
    end
}

-- Defining Derived Class (Boss)
Boss = {
    setAttributes = function(self, health, damage)
        Enemy.setAttributes(self, health or 1000, damage or 100)
    end,
    superAttack = function(self)
        return self.damage * 2
    end
}

setmetatable(Boss, {__index = Enemy})

-- Now, let's create an object for Boss
boss1 = Boss
boss1:setAttributes()
print(boss1:superAttack())

In the derived Boss class, we added the ‘superAttack’ method, which is unique to bosses. It is important to note that classes in Lua are very fluid and we can add or override functions as we need them for our game mechanics.

Let’s move on to another significant concept – calling base class methods from the derived class methods using ‘self’.

-- Redefining the Boss SuperAttack
Boss.superAttack = function(self)
    -- Here, we are linking back to the Enemy class attack method
    return self:attack() * 2
end

By including ‘self’ in the function, we’re able to call upon methods from the base class. This enables more dynamic interactions and lets us link relationships between different game entities.

Lastly, let’s dig into ‘multiple inheritance’, where a class can inherit from more than one base classes. Lua handles multiple inheritance via a special function called ‘multiIndex’ which we structure inside a metatable.

-- Creating base classes
class1 = {attribute1 = "Value-1"}
class2 = {attribute2 = "Value-2"}

-- Implementing multiple inheritance
multiIndex = function(table, key)
    local value = class1[key] or class2[key]
    return value
end

-- Creating derived class
derivedClass = setmetatable({}, {__index = multiIndex})

-- Testing derived class
print(derivedClass.attribute1)
print(derivedClass.attribute2)

We’ve successfully implemented multiple inheritance in Lua! The ‘multiIndex’ function enables our derived class to inherit attributes from more than one base classes.

With these lessons, you have taken your Lua programming skills to an advanced level. These concepts of inheritance are crucial for game developers and will surely enhance your game mechanics and code structuring abilities.

Diving Into Polymorphism in Lua Inheritance

Another fundamental concept in object-oriented programming and a cornerstone of Lua inheritance is polymorphism. A poly-morphic object can take many forms, enabling us to make our code able to handle objects as if they belong to a high-level class. For instance, if ‘Boss’ and ‘Enemy’ both have a function ‘attack()’, we can invoke it on an array of different enemies without knowing their exact class.

-- Defining Base Class (Enemy)
Enemy = {
    health = 100,
    damage = 10,
    attack = function(self)
        return self.damage
    end
}

-- Defining Derived Class (Boss)
Boss = {
    health = 1000,
    damage = 50,
    attack = function(self)
        return self.damage * 2
    end
}
setmetatable(Boss, {__index = Enemy})

-- Creating enemies list
enemies = {Enemy, Boss}

-- Attacking the Player
for i, enemy in ipairs(enemies) do
    print(enemy:attack())
end

This way, you can manage different types of enemies and bosses in your game code without separating cases for each type. This use of polymorphism enhances the efficiency and readability of your Lua game code significantly.

Implementing Constructors in Lua Inheritance

Let’s now discuss constructors – special methods in classes that help in creating and initializing objects. Lua does not have built-in constructors, but we can emulate them using a function that returns a table.

-- Defining Base Class (Enemy)
Enemy = {}
Enemy.__index = Enemy

-- Defining constructor function
Enemy.new = function(self)
    local newEnemy = {}
    setmetatable(newEnemy, Enemy)
    return newEnemy
end

-- Setting attributes
Enemy.setAttributes = function(self, health, damage)
    self.health = health
    self.damage = damage
end

-- Defining Derived Class (Boss)
Boss = {}
setmetatable(Boss, {__index = Enemy})

-- Overriding constructor
Boss.new = function(self)
    local newBoss = Enemy:new()
    setmetatable(newBoss, Boss)
    return newBoss
end

-- Creating a Boss Object
boss1 = Boss:new()
boss1:setAttributes(1000, 100)

print(boss1.health, boss1.damage)

We just explored constructors in Lua and how to override them in derived classes. Constructors and their specific use in inheritance is a cornerstone when it comes to creating different game entities in your Lua script.

Let’s continue expanding our knowledge on Lua inheritance, touching on ‘private’ and ‘public’ attributes.

-- Defining a Class with Private Attributes
MyClass = {}
MyClass.__index = MyClass

-- Class constructor
function MyClass.new()
    local self = setmetatable({}, MyClass)
    self._privateAttribute = 0 -- underscore before variable name signifies private attribute
    return self
end

-- Accessing the private attribute indirectly using public method
function MyClass:getPrivateAttr()
    return self._privateAttribute
end

-- Creating an Object
myObject = MyClass.new()
print(myObject:getPrivateAttr())

Private attributes in a class can only be accessed indirectly using public methods. Adopting this mechanism in your Lua script not only enhances the security of data but also improves the readability of your code by separating internal details from exposed interfaces.

Accessing Parent Classes in Lua Inheritance

Finally, let’s explore an advanced concept of explicitly calling a function from a parent class while in a derived class.

-- Base Class (Enemy)
Enemy = {
    attack = function(self)
        return "Enemy Attack"
    end
}

-- Derived Class (Boss)
Boss = {
    attack = function(self)
        return "Boss Attack, "..Enemy.attack(self)
    end
}

setmetatable(Boss, {__index = Enemy})

-- Testing
print(Boss:attack())

With this, we have mastered a notable range of concepts related to Lua inheritance. These concepts lay the foundation of structuring your game logic and can significantly enhance the sophistication and organization of your code.

Continue Your Learning Journey

Armed with a robust understanding of Lua inheritance, the journey doesn’t stop here. At Zenva, we offer a wide number of courses ranging from beginner to professional levels in programming, game development, and artificial intelligence. With more than 250 supported courses available, you can unlock new skills, create exciting games, and earn relevant certificates for your career progression.

If you’re particularly interested in bridging your knowledge of Lua into creating impressive, interactive games, we recommend diving into our Roblox Game Development Mini-Degree. This comprehensive suite of courses teaches game creation using Roblox Studio and Lua. Covering genres from obstacle courses to melee combat games, this program equips you with real-time skills like developing multiplayer functionality and creating leaderboards. Our experienced instructors ensure you receive high-quality instruction, guiding you to build a professional portfolio and gain in-demand skills for the game industry.

Explore our wide collection of Roblox courses and find the right fit for your aspiration and skill level. At Zenva, we believe in empowering you to go from beginner to professional, one concept at a time.

Conclusion

Exploring Lua inheritance and its many facets undeniably puts a lot more power in your coding toolset. Incorporating these concepts into your gaming projects can enable more efficient and sophisticated game design. Whether it’s structuring your game logic, managing game entities, or developing challenging game mechanics, mastering Lua inheritance is a significant stepping stone in your journey as a game developer.

We invite you to continue this exciting journey of learning, creating, and mastering game development with our comprehensive Roblox Game Development Mini-Degree. Let’s continue to unlock new achievements, create exciting experiences, and most importantly, keep coding!

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.