Plugins#
A plugin configures one world. It registers components, queries, systems, resources, states, observers, and initial entities.
The application calls its entry plugin after engine subsystem installation and before startup phases:
local function install(exclusive app: tecs.application.Application): nil
spinPlugin(app.world, 1.5)
tecs.gfx.text.install(app.world)
end
-- A component's exported constructor returns this session.
local session = tecs.host.newSession({
window = {title = "My game", width = 1280, height = 720},
plugin = install,
})Capture the particular world, window, or input value a later system needs. Systems and observers provide the per-frame and per-event lifecycle.
One-time setup#
Declare component types at module scope. Build queries once in the plugin, then close over them from systems:
local function spinPlugin(exclusive world: tecs.ecs.World, speed: number): nil
local spinning = world:newQuery({
include = {tecs.ecs.Transform2D, tecs.gfx.Renderable2D},
exclude = {tecs.ecs.Disabled, tecs.ecs.Paused},
})
world:addSystem({
name = "game.Spin",
phase = tecs.ecs.phases.Update,
run = function(dt: number): nil
for archetype, count in spinning:iter() do
local transforms = assert(archetype:getMut(tecs.ecs.Transform2D))
unsafe do
for row = 1, count as integer do
transforms[row].rotation = transforms[row].rotation + speed * dt
end
end
end
end,
})
endNever construct a persistent query inside run; that rebuilds its match set every frame. Name every system that needs removal or useful debug output.
Composition and dependencies#
A plugin can call other installation functions:
local function gameplay(exclusive app: tecs.application.Application): nil
healthPlugin(app.world)
inventoryPlugin(app.world)
spinPlugin(app.world, 1.5)
endPass configuration through arguments or a closure. Keep configuration typed and immutable inside the installed systems. A plugin that depends on another should read its required resource during setup and fail immediately if absent.
Export component and event types beside the plugin function when other modules need them. Keep one purpose per plugin, then group related plugins with another plugin.