Extensions

Extensions observe a Component's lifecycle without touching the Component's own class, the tool for cross-cutting behavior (logging, analytics, debug tooling) that would otherwise mean copy-pasting the same print calls into every Component's Construct/Start/Destroy.

Available hooks (in execution order)

Hook Fires
Constructing Before Construct()
Constructed After Construct()
Starting Before Start()
Started After Start()
Stopping Before Destroy()
Stopped After Destroy()

Creating and attaching an extension

local Component = Owl.Util.Component
 
-- > // Create an extension
local LogExtension = Component.CreateExtension({
    Name = "Logger",
    Hooks = {
        Constructed = function(comp)
            print(("[LOG] %s, Construct done"):format(comp.Instance.Name))
        end,
 
        Stopped = function(comp)
            print(("[LOG] %s, Destroyed"):format(comp.Instance.Name))
        end,
    },
})
 
-- > // Attach it to a Component
local EnemyComponent = Component.new({
    Tag = "Enemy",
    Type = "Server",
    Extensions = { LogExtension },
})

The same extension can be attached to as many Component types as you want LogExtension above would work identically on an ItemComponent or a NPCComponent, since every hook receives the Component instance itself (comp) rather than assuming anything about which Component it's attached to.

An extension that throws inside a hook doesn't stop other extensions from running. The error is caught and shown as a warning instead, one misbehaving Logger extension can't take down whatever a Metrics extension attached to the same Component is doing.

Where to go next

  • Creating a Component - the Construct/Start/Destroy lifecycle these hooks wrap around.
  • API Reference - the full signature for Component.CreateExtension and every Component option.