Overview

Available in: Server & Client

This concept applies to both environments with behavior adapted for each side.

An Addon extends Owl itself, not a single game feature. Where a Service adds game logic (a shop, an inventory), an Addon hooks into the framework's own lifecycle every Service being registered, the framework starting, the framework shutting down regardless of which game you drop it into. Analytics, a debug overlay or a plugin that automatically wraps every Service's Client methods are all Addon territory.

Creating an Addon

An Addon is a plain table with a Name and a Hooks table, nothing more is required.

If you don't have the "Addons" folder in OwlKnit/Owl then just create it and put your addon module in :)

OwlKnit/Owl/Addons/EconomyAddon.lua
local Owl = require(ReplicatedStorage.OwlKnit.Owl)
local EconomyAddon = {}
 
EconomyAddon.Name = "EconomyAddon"
EconomyAddon.Version = "1.0.0"
EconomyAddon.Author = "Morax"
EconomyAddon.Description = ""
EconomyAddon.OwlVersion = ">=1.1.2"
EconomyAddon.Dependencies = {} -- > // No other addons required for works
EconomyAddon.OptionalDependencies = {"AnalyticsAddon"} -- > // Can depends of an another addon like "Analytics" but only if he existing, if not then he just ignores it
EconomyAddon.Hooks = {}
 
function EconomyAddon.Hooks.Init(self: typeof(EconomyAddon), owl: any)
end
 
function EconomyAddon.Hooks.OnFrameworkStarted(self: typeof(EconomyAddon))
	print(("[EconomyAddon] %s v%s by %s is live."):format(self.Name, self.Version, self.Author))
end
 
function EconomyAddon.Hooks.OnServiceRegisted(self: typeof(EconomyAddon))
end
 
Owl.RegisterAddon(EconomyAddon)
return EconomyAddon

self inside every hook is the Addon table itself the same one you defined, so self.Logger and self.Trove (covered in Addons - Hooks & API) are available from the very first hook that fires.

Registering

You don't need to start them in ServerScriptService/init.lua since if you put a moduleScripts in Owl/Addons, he are automatically registered.

Priority and Dependencies

Both work exactly like a Service's Dependencies, computed independently for the Addon graph:

local MyAddon = {
    Name = "MyAddon",
    Priority = 5,
    Dependencies = {}
    OptionalDependencies = { "DebugOverlay" }, -- > // included in ordering only if present
    Hooks = { --[[ ... ]] },
}

Dependencies/OptionalDependencies affect Init order the same topological sort used for Services, applied to the Addon graph on its own. Priority affects hook firing order for every hook after Init (OnServiceRegistered, OnFrameworkStarting, etc.) addons run lowest Priority first.

Priority sorts ascending (lowest first), the opposite convention from things like RateLimiter/ContextActionPriority where a higher number usually means "runs first." Worth double-checking if you're used to the other convention.

Where to go next

  • Addons - Hooks & API - every hook explained, the scoped AddonAPI passed to Init and looking up registered addons.
  • Dependencies - the same topological-sort mechanism, applied here to Addons instead of Services.