Skip to content

Class (tm.class) ​

Context: shared (client and server).

A small class factory. Classes support default values, constructors, inheritance, and every instance gets get, set, printInfo, instanceOf, getClass and toTable.

lua
local MyClass = tm.class(defaults, constructor, parent)
ArgumentTypeDescription
defaultstable?Values every new instance starts with. Tables inside it are deep copied per instance, never shared.
constructorfun(obj, data, minimal)?Runs after defaults and data are applied.
parentclass?A class made by tm.class to extend.

Creating instances ​

lua
local Animal = tm.class(
    { name = 'Unknown', sound = 'silence', legs = 4 },
    function(obj, data, minimal)
        if not minimal then obj.greeting = ('Hi, I am %s'):format(obj.name) end
    end
)

local dog = Animal.new({ name = 'Rex', sound = 'Woof' })
print(dog.name, dog.greeting, dog.legs) -- Rex  Hi, I am Rex  4

Class.new(data, minimal) and Class:new(data, minimal) both work. data overrides defaults, minimal is handed to the constructors so they can skip expensive setup. The order is: defaults (root class first), then data, then constructors (root class first).

Inheritance and super ​

lua
local Dog = tm.class({ breed = 'Mixed' }, function(obj) obj.isGoodBoy = true end, Animal)
-- or: local Dog = Animal.extend({ breed = 'Mixed' }, constructor)

function Animal:speak() return self.sound end
function Dog:speak() return 'dog: ' .. Dog.super.speak(self) end
  • Defaults merge; the child's default wins over the parent's.
  • Constructors chain automatically, parent first, so a child never calls the parent constructor by hand.
  • Class.super is the parent class (nil for a root class). Call an overridden method with Class.super.method(self, ...).
  • Methods are added to the class table (function Animal:speak() end) and instances inherit them.

Instance methods ​

MethodDescription
obj:get(key)Reads a property. A dotted key ('address.city', 'items.2') walks nested tables and returns nil at the first missing level.
obj:set(key, value)When the instance or class defines onSet(self, key, value), the hook is called and owns the mutation (nothing is assigned). Without a hook the value is assigned, and a dotted key creates missing tables.
obj:printInfo()Prints ID: <id>, Name: <name>.
obj:instanceOf(Class)True for the class itself and any class that extends it.
obj:getClass()The class the instance was created from.
obj:toTable()A plain copy for saving or sending. Private fields and functions are left out.

Class functions ​

FunctionDescription
Class.new(data, minimal)Creates an instance.
Class.extend(defaults, constructor)Creates a subclass.
Class.isInstance(value)True when value is an instance of this class (or a subclass).
Class.superThe parent class.
tm.class.isClass(value)True for a class made by tm.class.
tm.class.instanceOf(value, Class)Safe form of obj:instanceOf that accepts any value.

Private fields ​

By convention a field whose name starts with _ is private to the class. It is a naming rule, not enforced by the language, but toTable never exposes private fields (nested ones included), so they do not leak into saved or sent data.