How plugins run
Plugins are loaded when Nari starts, and users can turn them on and off at any time without restarting.
Turning on
Section titled “Turning on”When a plugin is turned on:
main.luaruns from top to bottom. This is where you register providers, connect events and so on.- If a song is loaded, the
trackandstateevents fire with it right away, so a plugin turned on in the middle of a song still sees it. - If a screen is open, the
pageevent fires for it. readyfires once Nari finished starting, or right away if it already did.
main.lua runs on Godot’s main thread, the one that draws the screen. Don’t block it: use callbacks for anything
slow, or move heavy work to a background thread.
Turning off
Section titled “Turning off”When a plugin is turned off, uninstalled or updated:
disablefires.- Nari cleans up after the plugin:
- lyrics providers, music providers, sound effects, visualizers, settings, Home entries and Now Playing tabs it added are removed
- every signal connection made from Lua is disconnected
- every node the plugin created is freed
- its background threads are stopped, even if they are stuck in a loop
- pending
nari.httpcallbacks are dropped
Safe mode
Section titled “Safe mode”If Nari closes unexpectedly three times in a row within 30 seconds of starting, the next session starts in safe mode with no plugins loaded. Users can still turn plugins on and off; the change applies from the next session, and F5 in developer mode leaves safe mode.
Limits
Section titled “Limits”- Code that runs on the main thread for more than 3 seconds without returning stops the plugin. See Debugging.
- Each Lua state (
main.luaand every thread) can use up to 128 MB of memory. os.exit()raises an error instead of closing Nari.- Threads can’t touch Godot. Send a message to
main.luawhen something needs to change on screen. - Messages to
main.luawait while Android keeps the app in the background, and arrive when it comes back. - Values are copied between Lua and Godot. Godot’s typed arrays (
Array[String]…) come back as plain arrays. - Global Godot enums (
HORIZONTAL_ALIGNMENT_CENTER…) aren’t exposed. Use their numbers (HORIZONTAL_ALIGNMENT_CENTERis1).