# 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: ```nupp 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: ```nupp 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, }) end ``` Never 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: ```nupp local function gameplay(exclusive app: tecs.application.Application): nil healthPlugin(app.world) inventoryPlugin(app.world) spinPlugin(app.world, 1.5) end ``` Pass 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.