Multiple metatables?

Let’s say I have a pet system, where all functions are thesame, except that each one has a special skill. What I want to achieve is to have a master metatable with all the common functions and a function that is added from an additional metatable containing all special effects.

Why not having all special effects in the master metatable?
Considering this on a wide scale of 1000+ pets, it would mean unnecessary data is being added and memory used for no purpose.

How would I be able to achieve this concept of having functions of multi metatables?

(Note thst I’m only using metatables to put functions inside of them)

You’ll probably have an own module script for each class. If you just want all petclasses to inherit the masterclass, you can set the masterclass as the metatable of those classes.

MasterClass module:

local masterClass = {}

masterClass.__index = masterClass

-- define functions

-- and then return the masterClass
return masterClass

A spesific pet class example

local masterClass = require(--[[the correct module]])

local cat = {}

cat.__index = cat

-- define functions

return setmetatable(cat, masterClass)
4 Likes

Using OOP for this is IMO totally misguided, but here’s how I’d do it anyway:

Welp, someone was a lot faster than me xD What I’m suggesting is pretty much the same, but maybe it’s still helpful?


function newClass(superClass)
	local Class = setmetatable({}, {__index = superClass or baseClass})
	Class.InstanceMT = {__index = Class}

	function Class.New(...)
		local self = setmetatable({}, Class.InstanceMT)
		if self.Initialize then
			self:Initialize(...)
		end
		return self
	end

	return Class
end

--PetClass definition
local PetClass = newClass()

function PetClass.New()
	error("Tried to instantiate abstract class PetClass")
end

function PetClass:DoSpecialAbility(...)
	assert(self.SpecialAbility ~= nil, "PetClass:DoSpecialAbility called on instance without SpecialAbility.")
	self:SpecialAbility(...)
end

--CatClass definition
local CatClass = newClass(PetClass)

function CatClass:SpecialAbility(...)
	print("Meow! Scritch! 🐱‍👤")
end

local cat = CatClass.New()
cat:DoSpecialAbility()

local generic_pet = PetClass.New()
generic_pet:DoSpecialAbility()
1 Like

This is pretty much all I needed that or in setting the metatable.

setmetatable({}, {__index = superClass or baseClass})

Also, it’s supposed to be possible to have the superclass implemented within, correct?

PetSpecial = { Cat = {}} --Each pet specials are here under the pet name
function PetSpecial.Cat:Meow(...)
	print("Meow! Scritch! 🐱‍👤")
End

Class = {} --Master Class
function Class.New(Name)
	local Pet = setmetatable({}, {__index = PetSpecial[Name] or baseClass})
	return Pet
end

local JustSomeCat = Class.New("Cat")

Also, are there any restrictions/disadvantages for this?
In case you don’t really get what I’m trying to achieve, its adding extra functions, or overwriting existing ones in the masterclass for specific pets, while others always stick to the player. I dont want to just add a value that checks if this mob is special or not as it would be alot of checks to do that for all mob types. Overwriting such as having a specifc flow for a special pet, such as move to enemy if nearby else stick to player. And adding extra ones such as for a mob boss, I want to have a specific animation for bosses when they’re low or an extra hard mode if its health is low.

This probably took you quite some time to write down and so is reading this, I appreciate it!

1 Like