Let’s say I have a beat-'m-up game with many enemies. I have a metatable metaEnemy containing methods for enemy behavior. I also have different enemy types with their respective metatables that define their behavior, such as metaOrc for orc enemies and metaBat for bat enemies. Both metatables have their metatables set to metaEnemy to inherit generic enemy methods. So in code I have the following so far:
local metaEnemy = {}
metaEnemy.__index = metaEnemy
function metaEnemy:update(...) ... end -- etc.
local metaOrc = setmetatable({}, metaEnemy) -- inherit methods from metaEnemy
metaOrc.__index = metaOrc
function metaOrc:doExclusiveOrcThing(...) ... end -- and more methods etc.
local metaBat = setmetatable({}, metaEnemy)
metaBat.__index = metaBat
function metaBat:doExclusiveBatThing(...) ... end -- and more methods etc.
So if I were to create an orc, I would do:
local orc = setmetatable({orc_properties}, metaOrc)
I can then call methods on the orc
variable which will either reside in the orc table, the metaOrc table or the metaEnemy table.
Now I want to add a super-duper-cool feature to my game called ‘boss enemies’, which are regular enemies, but bigger and they have some exclusive ‘boss methods’.
If I were to create, for example, a boss orc enemy, I would want to construct an orc enemy that has its metatable set to metaOrc
to inherit the orc’s behavior. However, I would also want to inherit the generic boss methods which I may have defined in a bossMeta
metatable. I could make it so the bossMeta
metatable has its metatable set to metaOrc
, but then I wouldn’t be able to reuse it for bat boss enemies, or other types of boss enemies.
Alternatively I could create a seperate boss metatable for each enemy type, but then I would be repeating the same code over and over again for the different enemies.
Preferably I would like to have only one metatable for boss behavior, and depending on which enemy type it’s for, it would have its metatable set to the corresponding enemy’s metatable (so metaOrc or metaBat etc.). Is there a way to construct this ‘conditional inheritance’ in a clean manner?