There are definitely times when it's useful to pair a table with some functions, particularly in game dev. When that situation arises, I try to keep it as flat as possible. I don't bother with encapsulation or any of that OOP nonsense (I solve the problem of shared state by doing a
kind of high-level segregation in the form of modules, putting globals in a module, putting global functions in a module, etc. like, i'm not a crazy person, I just don't think segregating all state is the answer to the problem of shared state). Instead, I just fill a table with some functions, then code something to copy the table including those functions. Naming is just an initial capital, and I keep it to one word if possible. __index does the rest, and instantiation/construction is done by copying the table.
Here's the implementation I'm using in my current project. Note that I don't have any tables anywhere that go more than one level deep, so infinite recursion of copy isn't necessary.
Code: Select all
Entity = require "classes.Entity"
resources = require "modules.resources"
local tools = {
CopyTable = function(table)
local new_table = {}
for k, v in pairs(table) do
if type(v) == 'function' then
new_table[k] = tools.CloneFunction(v)
elseif type(v) == 'table' then
local sub_table = {}
for i,j in pairs(v) do
sub_table[i] = j
end
new_table[k] = sub_table
else
new_table[k] = v
end
end
setmetatable(new_table, table)
new_table.__index = table
return new_table
end,
CloneFunction = function(f)
local dumped = string.dump(f)
local cloned = loadstring(dumped)
local i = 1
while true do
local name = debug.getupvalue(f, i)
if not name then
break
end
debug.upvaluejoin(cloned, i, f, i)
i = i + 1
end
return cloned
end
The way it works in actual practice is, I prepare a file where I keep all my mob data, and in there I call something like,
Code: Select all
slime = CopyTable(Entity)
...
set a bunch of attributes for slimes
...
fire_slime = CopyTable(slime)
And so on. Then in my actual spawning functions, I'm just calling other functions I've written that make reference to and create copies (instances, if you like) of these mob archetypes.