Docs/How plugins start and stop
Guide

How plugins start and stop

Every DominScript plugin has an init and a deinit hook. The init answers one question before a single statement runs: am I ready to work on this machine? This page shows what the host does with that answer, why a missing library stops a script at the start rather than in the middle, and how plugins pass data to each other without knowing each other.

Ready / Deinitsince plugin header revision 3applies to every plugin, official or yours

What happens at startup

When domin starts a script it first reads the plugin lines and loads each plugin. Right after loading one — before the script is bound, before main() — it calls the plugin’s Ready hook. The plugin answers with a constant, READY or NOT_READY, and may add a message.

domin script.domreads the plugin lines; then, before anything runs: 1 · loaddlopen / LoadLibrary 2 · Ready()the plugin's own check READY NOT_READY 3 · bindnames, types, verbs 4 · runmain() starts refused — nothing runsplugin 'X' is not ready: <the plugin's message>exit 1 · with --validate: a warning instead 5 · Deinit() at shutdown Either answer may carry a message: a READY plugin's noteis shown as a notice; an empty message means nothing to say.

Figure 1 — the five steps; a NOT_READY answer ends the run before step 3.

A NOT_READY answer is final: the host prints plugin 'Sdl2ImagePlugin' is not ready: followed by the plugin’s own message, and exits with status 1. No statement of the script has run, no file has been touched, nothing is half done. This is the point of the mechanism: a problem that can be found before running is found before running. The old behaviour — a plugin that loaded fine and failed on its first real call, possibly minutes into a run — is gone.

A plugin that has no Ready hook at all (one built against an older plugin header) is treated as not ready too; the message says to rebuild it.

Adapters: the library opens in Ready

Most plugins have nothing to check and simply answer READY. The ones that matter are the adapters — plugins that wrap a third-party library at run time: SDL2, SDL2_image, FFmpeg, OpenSSL, SQLite, the MariaDB and PostgreSQL clients, cJSON. Their Ready opens the library, keeps the handle, and answers accordingly.

adapter plugine.g. sdl2_image Ready() tries, in this order: 1 the runtime/ folder2 3rd_party/ (dev tree)3 the system library foundhandle kept · answer: READY library missinganswer: NOT_READY, message:"SDL2_image not found. Install it, or copy SDL2_image.dll into …\runtime" SDL2_image.dlllibSDL2_image-2.0.so.0 The constant decides whetherthe script starts; the messageis the instruction for theperson reading it.

Figure 2 — an adapter’s Ready: the runtime folder first, then the system; the message names the file and the folder.

The search order is the same for every adapter and is described on the Optional libraries page. What matters here: the message the person reads is written by the plugin at the moment it knows exactly what is missing, so it can say which file and which folder.

Constants and messages are independent

The constant decides; the text informs. A plugin may answer READY and still leave a note — the ffmpeg plugin does, when it was built without decoding support: the script runs, and the host shows plugin 'FfmpegPlugin': decoding is disabled in this build … as a notice. An empty message means nothing to say, and the host stays silent.

AnswerMessageWhat the host does
READYemptynothing; the script runs
READYtextshows it as a notice; the script runs
NOT_READYtextrefuses to start, quoting the text; exit 1
NOT_READYemptyrefuses to start: “the plugin gave no reason”

domin --validate runs the same check but reports a NOT_READY plugin as a warning, anchored at the plugin line, and still says Validation OK. A script can therefore be checked — and edited in VS Code with live diagnostics — on a machine that lacks the library it will run with elsewhere.

Shutdown and Deinit

At the end of a run — a normal return from main(), a runtime error, or a Stop from the debugger — the host calls each plugin’s Deinit hook, in load order, before unloading the library. The plugin closes what Ready opened and frees what it allocated. Deinit answers with a constant and an optional message in the same way: DEINIT_OK with an empty message is silence; a message is shown as a notice; anything other than OK is reported as a warning on stderr — the script’s exit code is not changed by it, because the script itself did not fail.

How plugins hand data to each other

One plugin per library is a rule with a consequence: a PNG decoded by sdl2image has to reach a texture owned by sdl2 or gl, and the two plugins must not know each other’s internals. DominScript’s answer is the one it gives everywhere: the blob is the interface. The decoder returns a pixel packet — a small fixed header (width, height, stride, format) followed by raw RGBA bytes — and anything that draws pixels accepts that packet.

sdl2image.LoadSDL2_image decodes image.Loadbuilt-in, no library pixel packet (blob)64-byte header:width, height, stridethen RGBA bytes sdl2.TextureFromPixels gl.UpdateTexture a file, a socket the script's own code

Figure 3 — producers on the left, consumers on the right, one packet format in the middle. No handles cross a plugin boundary.

The same packet can be written to a file, sent over a socket, inspected by the script with a struct over the header, or produced by your own code. A plugin you write joins either side of the picture by reading or writing the same bytes.

If you write a plugin

Two functions with fixed names, PluginReady(Message, Cap) and PluginDeinit(Message, Cap), defined before the export line; the export macro wires them, and a plugin without them does not compile. A plain plugin writes one line, DOMIN_PLUGIN_ALWAYS_READY(). An adapter opens its library in Ready with the shared loader and, when that fails, lets DominRtl_NotFound write the message; if the library has a purely software init of its own (IMG_Init, mysql_library_init), that runs in Ready too, and its counterpart in Deinit. Device- or session-level initialisation (an SDL subsystem, a GL context) is not Ready’s business: only the script knows whether it needs video, audio or both, so those come up at the first verb that asks for them. The Writing an adapter plugin page shows the whole file; plugins/adapter_skeleton in the tree is the pattern with every obligation numbered.