When is the best time to use metatables and what can they be applied to?

I’ve been a scripter for around 8 months now and im now trying to transfer my knowledge of classes from python to LUA. I understand how to use and create these metatables but not when to apply them to a game. What can you use metatables for?

boooooost?!?!?!??!!?!??!?!?!?!

1 Like

To clarify, metatables and classes are two separate things. The most commonly used aspect of metatables are for object orientated programming. Here’s an example of a simple object called TestClass which utilizes the __index metamethod:

local TestClass = {}
TestClass.__index = TestClass

function TestClass.new(name)
	local self = setmetatable({}, TestClass)
	
    self.Name = name

	self:_Init()
	
	return self
end

----------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------- PUBLIC METHODS -------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------

function TestClass:CheckName()
    return self.Name == "Test"
end

----------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------- PRIVATE METHODS -------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------

function TestClass:_Init()
	-- empty
end

return TestClass
local TestClass = require("testclass path")

local new_object = TestClass.new("Test")
print(new_object:CheckName()) --> true

local new_object2 = TestClass.new("Other Name")
print(new_object2:CheckName()) --> false

There are a few other metamethods available for use but most of the time they are rarely used when programming (at least I never really see a use for them).

1 Like

im aware of what OOP is but im trying to find ways to use it in game

Just so you don’t get confused, metatables are not classes, they are sorta like macros that can be built into the backend of a table to preform functions on the table.

With regards to OOP, for me, I use it everywhere in my games. A simple yet great example is a player data system. It can be annoying when you have a character spawn in and there’s a bunch of info you want to store for them while they are in a game. Something simple that you could do is this:

local PlayerData = {}
PlayerData.__index = PlayerData

function PlayerData.new(player)
	local self = setmetatable({}, PlayerData)
	
	self.Player = player
	
	self._Data = { -- this would save to the datastore when they leave
		Level = 1;
		XP = 0;
		Gold = 0;
	}
	
	self:_Init()
	
	return self
end

----------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------- PUBLIC METHODS -------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------

function PlayerData:GiveGold(amount)
	self._Data.Gold += amount
end

function PlayerData:GiveXP(amount)
	self._Data.XP += amount
	
	if self._Data.XP > self._Data.Level * 7 then
		self._Data.Level += 1
		self._Data.XP -= self._Data.Level * 7
	end
end

----------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------- PRIVATE METHODS -------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------

function PlayerData:_CharacterAdded(character)
	-- do whatever you want to the player whenever it gets added
end

function PlayerData:_Init()
	self.Player.CharacterAdded:Connect(function(character)
		self:_CharacterAdded(character)
	end)
end

return PlayerData

This is a really rough example of what you could do with objects but the idea is there.

If your functions are starting to look like this:

local function foo(data1, data2, data3, data4, data5, data6, someNumberInput)

Where data 1-6 is repeated for multiple functions then OOP is a potential solution so that you can avoid repetition.

Ive had this scenario for a 3d triangle terrain terrain generator where data1 was a 3d grid table.

In @Kurookku example it would be the player data table as its used within 2 functions.

is all of that in a module script or something?
also whats the need for the underscores for _Data

Underscores are just for naming convention used to tell the programmer that “hey this is special” or “hey this shouldn’t really be touched because it’s for internal use”

Biggest example is with metamethods; their names all start with two underscores because they aren’t supposed to be used as regular keys in a dictionary

1 Like