Skip to content

Install and manage plugins

A plugin adds code to your server: new services, commands, Lua modules or settings. The server loads the plugins it finds under <root>/plugins/ once, at start. This page is for the person who runs a shard and wants to add, update or remove one. To try one step by step, follow Your first plugin. To write one, read Writing a plugin.

The community plugins live in moongate/moongate-plugins. Each release there carries one .nupkg package, the plugin’s own page and the Moongate version it was built for.

Plugin What it does
Moongate.Plugins.OpenAi NPC dialogues answered by OpenAI from a Lua module; off until you enable it and give it a key
Moongate.Plugins.Notifications Tells the staff outside the game, from Lua with notify.send or from a plugin: Discord, a webhook or the log; off until you enable it and add a channel
Moongate.Plugins.Notifications.Telegram Adds a telegram channel to the one above, which it needs installed first
Moongate.Plugins.Notifications.Smtp Adds an smtp channel (e-mail) to the one above, which it needs installed first, version 0.2.0 or later

A plugin is built for one exact version of Moongate. The server refuses a bundle built for another, and mgctl refuses it earlier, with a clearer message. After you update the server, install the build of each plugin made for the new version.

  1. Trust the source. A plugin runs inside the server process with all its permissions: it can read the databases, the accounts and the files of the root. Install one only from an author you trust, and compare the SHA-256 mgctl prints with the one the release page shows next to the asset.
  2. Stop the server. It reads plugins/ at start only: files replaced under a running server can fail to copy (Windows locks the DLLs) and take effect only at the next start.
  3. Check the version. mgctl --version and the “Built for Moongate” note of the plugin’s release must be the same.
  4. Back up the databases if the plugin ships SQL migrations: they only go forward.
Terminal window
mgctl plugin install Moongate.Plugins.OpenAi --root-directory /srv/moongate
mgctl plugin install https://codeberg.org/moongate/moongate-plugins/releases/download/Moongate.Plugins.OpenAi-v0.2.1/Moongate.Plugins.OpenAi.0.2.1.nupkg --root-directory /srv/moongate
mgctl plugin install ./Moongate.Plugins.OpenAi.0.2.1.nupkg --root-directory /srv/moongate

The command takes a plugin id, an https address or a file, checks the package, shows its id, version and SHA-256, and asks Install it? [y/N]; --yes answers for you in a script. The checks and the guards it makes are listed in Install a plugin package. The result is <root>/plugins/<PackageId>/.

With an id, mgctl looks the plugin up in the community repository and installs the newest build made for the version of Moongate you run: you do not need the address of the release.

A plugin you wrote, or one from an author you trust, can live in a repository of its own. Attach the package (dotnet pack names it <PackageId>.<version>.nupkg) to a release on Codeberg or GitHub, or keep the packages in a folder, and point mgctl at it:

Terminal window
mgctl plugin install MyPlugin --repo myuser/my-plugins --root-directory /srv/moongate
mgctl plugin install MyPlugin --repo ./my-packages --version 1.2.0 --root-directory /srv/moongate

A repository may hold many plugins and many versions: mgctl picks the newest build made for your Moongate, or says which versions exist. For a private repository put a token in CODEBERG_TOKEN (GITHUB_TOKEN on GitHub). The rules are in Install by id from a repository.

mgctl plugin comes with the releases after 0.16.0. With 0.16.0, extract the plugin/ folder of the .nupkg (it is a zip file) into <root>/plugins/<PackageId>/ by hand: the folder must hold <PackageId>.dll and <PackageId>.deps.json.

The image holds mgctl beside the server and keeps the root in the /data volume. Stop the container, run the command against the volume, start the container again:

Terminal window
docker stop moongate # the name of your container
docker run --rm --entrypoint /app/mgctl \
--mount type=volume,source=moongate-data,target=/data \
docker.io/tgiachi/moongate:latest \
plugin install https://codeberg.org/moongate/moongate-plugins/releases/download/Moongate.Plugins.OpenAi-v0.2.1/Moongate.Plugins.OpenAi.0.2.1.nupkg \
--root-directory /data --yes
docker start moongate

Use the image of the same version as the container: mgctl checks the plugin against its own version.

  1. Configure it. A plugin’s settings are a table of config/moongate.toml. The plugin appends its table with the defaults at its first start, usually switched off: start once, stop, edit it, start again. Read the plugin’s own page (plugins/<PackageId>/README.md in its repository) for the keys, and set what it needs. Keep a secret such as an API key in an environment variable, not in the file. See Plugin sections.
  2. Apply its SQL, if it ships any: mgctl migrate apply --target world, or let the server do it with persistence.auto_apply_migrations; the SQL of the bundles under plugins/ is included. See Persistence migrations.
  3. Start the server and read the log: Loaded N disk plugins counts them and one Disk plugin <id>: <name> <version> - <description> line for each names them; Plugin '<id>' registered follows as each one starts.
Terminal window
mgctl plugin list --root-directory /srv/moongate
Plugin Version Built for Origin
Moongate.Plugins.OpenAi 0.2.1 0.17.0 package

Origin is package for what mgctl installed and by hand for a bundle copied there, whose version is read from its assembly.

Install the newer package over the older one with the same command. The old bundle is replaced only once the new one is in place; the settings in config/moongate.toml stay. Read the plugin’s release notes for settings that changed, then start the server.

Terminal window
mgctl plugin remove Moongate.Plugins.OpenAi --root-directory /srv/moongate

This deletes <root>/plugins/<PackageId>/. Two things stay on purpose, and are yours to clean if you want them gone:

  • the plugin’s table in config/moongate.toml, which the server ignores while the plugin is not installed;
  • the plugin’s database tables, because migrations only go forward.

A bundle that cannot load refuses the start with a message naming it. The common causes:

Message or symptom Cause and fix
The plugin entry assembly is missing. The folder’s name and its DLL’s name differ; the DLL must be <folder>.dll. Reinstall with mgctl
Failed to load plugin bundle with an inner exception about an assembly or its version The plugin was built for another Moongate version, or lost a file: install the build made for yours
Plugin '<id>' failed during registration. The plugin’s own start threw, often an invalid value in its table of config/moongate.toml; the inner exception says which
A folder of plugins/ that is not a plugin Remove it: the loader treats every folder of plugins/, except one whose name starts with a dot, as a bundle

The full list is in Errors that refuse the start. To get back to a working server, mgctl plugin remove <id> the plugin and start again.

Made with ❤️ by Tom

Buy me a coffee