LuLua · Lesson 6 of 8

OOP & Metatables

Lua doesn't have classes — it has metatables, hooks that change how tables behave. Every Lua OOP system (including Roblox's) is built from this one mechanism.

A metatable customizes what happens on events like 'key not found' (__index) or 'table + table' (__add). The classic class pattern: put methods on a prototype table, and point instances' __index at it — missing lookups fall through to the prototype.

Lua
local Player = {}
Player.__index = Player

function Player.new(name, hp)
  local self = setmetatable({}, Player)
  self.name = name
  self.hp = hp
  return self
end

-- Colon DEFINES a method with an implicit 'self' parameter:
function Player:takeDamage(amount)
  self.hp = self.hp - amount
  if self.hp <= 0 then
    print(self.name .. " is down!")
  end
end

function Player:heal(amount)
  self.hp = math.min(100, self.hp + amount)
end

local hero = Player.new("Ada", 100)
hero:takeDamage(30)      -- colon CALLS passing hero as self
print(hero.hp)           -- 70
Lua
-- Operator overloading via metamethods:
local Vec = {}
Vec.__index = Vec

function Vec.new(x, y)
  return setmetatable({ x = x, y = y }, Vec)
end

Vec.__add = function (a, b)
  return Vec.new(a.x + b.x, a.y + b.y)
end

Vec.__tostring = function (v)
  return "(" .. v.x .. ", " .. v.y .. ")"
end

local pos = Vec.new(1, 2) + Vec.new(3, 4)
print(pos)               -- (4, 6)
◆ Note
Roblox's Luau and most game engines use exactly this pattern (or wrap it). When Roblox docs say 'object-oriented programming', this __index trick is what's underneath.