An SCP: Secret Laboratory server runs plugins through LabAPI, Northwood's official framework, which ships inside every server build. EXILED, the larger community framework, is now itself a LabAPI plugin, so a modern server can run native LabAPI plugins and EXILED plugins side by side. Plugins are .dll files dropped into per-port or global folders in the server's app data, each one writes a YAML config on first start, and permissions for plugin commands come from a permissions.yml keyed by your Remote Admin group names. Almost every plugin problem is one of four things: the plugin was built for a different game or framework version, it is in the wrong folder, its YAML did not parse, or the permission group name does not match a Remote Admin group exactly. This guide goes through each of them in the order you will meet them.
For the server itself - LocalAdmin, config_gameplay.txt, Remote Admin roles and verification - see the SCP: Secret Laboratory server guide. This post starts where that one stops.
How LabAPI and EXILED fit together#
LabAPI is the base layer. Its folders sit under the game's app data directory - ~/.config/SCP Secret Laboratory/ on Linux, %AppData%\SCP Secret Laboratory\ on Windows - in a LabAPI folder with plugins, dependencies and configs beneath it. By default it loads from a global folder and from a folder named after the server's port, so one machine can run several servers with different plugin sets.
EXILED sits on top. Its loader is a LabAPI plugin, and once loaded it reads its own tree, an EXILED folder in the same app data root. That layering has one consequence worth remembering: when a game update bumps LabAPI's major version, the whole EXILED stack waits on an EXILED update, not just one plugin.
Which to choose is mostly decided by the plugins you want. A plugin built for LabAPI goes in LabAPI's folders; a plugin built for EXILED needs EXILED installed and goes in EXILED's folders. A plugin page that says neither is probably out of date - older plugins targeted the retired NWAPI, and those do not load on current builds.
Folders and files, side by side#
| Purpose | LabAPI | EXILED |
|---|---|---|
| Plugin DLLs | LabAPI/plugins/global/ or LabAPI/plugins/<port>/ | EXILED/Plugins/ |
| Shared libraries | LabAPI/dependencies/global/ or <port>/ | EXILED/Plugins/dependencies/ |
| Plugin configs | LabAPI/configs/<port>/<PluginName>/ | EXILED/Configs/Plugins/<prefix>/<port>.yml |
| Translations | Plugin-specific | EXILED/Configs/Translations/<prefix>/<port>.yml |
| Permissions | LabAPI/configs/permissions.yml | EXILED/Configs/permissions.yml |
| Remote Admin log | - | EXILED/<port>-RemoteAdminLog.txt |
Two notes on that table. LabAPI also writes a properties.yml beside each plugin's config, holding IsEnabled and an UnsupportedLoading override, which is how you switch one plugin off without deleting it. And EXILED's config layout depends on its loader's ConfigType setting: the current default is Separated, one file per plugin per port as shown above, while Default puts every plugin into a single EXILED/Configs/<port>-config.yml with a matching <port>-translations.yml. The console command econfig merge and econfig split convert between the two. Older guides assume the single-file layout; if you cannot find a config where a guide says it is, this is why.
Installing EXILED#
EXILED is installed with its own installer, Exiled.Installer-Linux or Exiled.Installer-Win.exe, which downloads a release from GitHub and unpacks it into the right places:
$ ./Exiled.Installer-Linux --path /home/container \ --appdata /home/container/.config --exiled /home/container/.config| Option | What it does |
|---|---|
--path | The SCP:SL server folder |
--appdata | Forces the app data root. Needed in containers where the process runs as a different user |
--exiled | Where the EXILED folder goes |
--target-version | Installs a specific release instead of the latest |
--get-versions | Lists available releases |
--pre-releases | Allows pre-release builds |
--appdata is the option that matters on hosted servers. The server reads the app data folder of the user it runs as; if the installer writes somewhere else, EXILED is installed and never loads. If the console shows no EXILED banner on start, check that the paths the installer printed match where the server keeps its config folder.
The loader has its own settings, kept in LabAPI's configs folder under the loader's plugin name. Three of them deserve a decision rather than a default:
| Key | Default | Recommendation |
|---|---|---|
EnableAutoUpdates | true | Turn off on a live server. Update deliberately, not mid-week |
ShouldLoadOutdatedPlugins | true | Fine while it works; the first suspect when something breaks |
ShouldLoadOutdatedExiled | false | Leave it |
Automatic updates are convenient on a test server and a liability on a busy one. An EXILED release that lands while plugins are still built against the previous one is exactly how a server breaks with nobody having touched it.
Installing and configuring a plugin#
The procedure is the same for both frameworks:
- Check the plugin's page for the framework and the game version it was built against. If either does not match, stop.
- Stop the server.
- Put the DLL in the plugin folder and any listed dependencies in the dependencies folder. Global folders apply to every port; port folders only to that server.
- Start the server once. The plugin writes its default config.
- Stop it, edit the config, start again - or edit and use a reload command.
A typical EXILED plugin config is plain YAML with two keys every plugin has, is_enabled and debug, followed by its own options:
is_enabled: truedebug: false# Message shown to a player on joinwelcome_message: 'Welcome to the Site-02 night shift'broadcast_duration: 6allowed_roles:- ClassD- ScientistYAML is unforgiving in specific ways. Indentation is spaces, never tabs. A value containing a colon, a hash or a leading special character needs quotes, and EXILED writes strings single-quoted by default, so keep that style. Lists are a dash and a space at the start of the line at the right depth. When a file does not parse, the plugin either loads with defaults or does not load at all, and the error is in the console at start - game server config file formats covers the YAML traps in more detail.
LabAPI plugin configs work the same way under LabAPI/configs/<port>/<PluginName>/, usually as config.yml, with field names chosen by the plugin's author.
Reloading without a restart
Restarting mid-round kicks everyone, so both frameworks can reload from the server console or Remote Admin:
| Command | Effect |
|---|---|
labapi reload configs | Reloads configs for all LabAPI plugins. Short form lab r c |
reload configs | Reloads EXILED plugin configs |
reload translations | Reloads EXILED translations |
reload permissions | Reloads EXILED permissions.yml |
reload plugins | Reloads EXILED plugins. Use with care |
reload gameplay / reload remoteadmin | Reloads the game's own config files |
pluginmanager show | Lists EXILED plugins and their state |
pluginmanager enable / disable | Switches an EXILED plugin on or off |
Config reloads are safe for settings a plugin reads when it needs them. Settings read once at start - a list of custom roles, a database connection - may still need a restart. When a reload seems to do nothing, restart between rounds before assuming the setting is broken.
Permissions for plugin commands#
Remote Admin permissions decide what the game's own commands allow. Plugin commands check a second layer: framework permissions, which are strings such as myplugin.kick granted to groups.
EXILED's permissions.yml is keyed by Remote Admin group name, plus a special user group for everybody without one:
user: default: true inheritance: [] permissions: []moderator: inheritance: [] permissions: - adminplugin.kick - adminplugin.muteadmin: inheritance: - moderator permissions: - adminplugin.*owner: inheritance: [] permissions: - .*The rules that trip people up:
- Group names must exactly match the role names in `config_remoteadmin.txt`. A group that matches nothing is ignored with a warning in the console, which scrolls past at start.
- Every group needs both `inheritance` and `permissions`, even if empty. Leaving one out makes the whole file fail to parse, not just that group.
- `default: true` marks the group used for players with no Remote Admin role. Exactly one group should have it.
- Wildcards.
adminplugin.*grants everything under that prefix;.*grants everything, and belongs only on the owner group. - Inheritance is one-way.
admininheritingmoderatorgets moderator's permissions, not the other way round.
After editing, run reload permissions or the permissions command's own reload. LabAPI's equivalent is LabAPI/configs/permissions.yml, also keyed by Remote Admin group name, with a default group for everyone else; labapi permissions shows what you hold. Grant plugin permissions as narrowly as Remote Admin roles - a moderator with .* is an owner in everything but name. Subusers and least privilege makes the same argument for panel access.
Choosing plugins#
The official plugin directory, which LocalAdmin's p commands can install from, is the safest source. Beyond that, plugins come from GitHub releases. Some categories and what to watch in each:
| Category | Examples | Watch for |
|---|---|---|
| Moderation and bans | CedMod, AdminTools | Web panels need outbound access and their own accounts |
| Custom roles and items | UncomplicatedCustomRoles, EXILED's own CustomRoles and CustomItems | Balance, and configs that are long and fragile |
| Statistics and Discord | SCPStats | API keys, privacy of player data |
| Round and respawn tweaks | Respawn timers, team balance | Interaction with other gameplay plugins |
| Fun and event plugins | Event modes, cosmetic effects | Usually the first to break after an update |
EXILED installs Exiled.CustomItems, Exiled.CustomRoles, Exiled.Events and Exiled.Permissions as part of itself. Other plugins that depend on them do not need them installed separately.
Fewer is better. Every gameplay plugin is another hook into the same events, and two plugins changing the same thing - spawn waves, role assignment, item pickup - interact in ways neither author tested. Add plugins one at a time and play a round between additions.
Any plugin runs with the server's full permissions and sees every player connection. Download from the author's repository or the official directory, never from a reupload in a Discord channel. Malicious plugins and mods covers what a hostile one can do, and keeping a modded server clean the routine that keeps you out of trouble.
Surviving game updates#
SCP: Secret Laboratory ships updates regularly, and a server that updates automatically on restart will pick them up before plugin authors have. The pattern is familiar: the server starts, the log fills with MissingMethodException or a refusal to load a plugin built against a different major version, and half your features are gone.
A routine that works:
- Know what you run. Keep a list of plugins with versions and source links, next to your config backups.
- Pin before patch day. When Northwood announces an update, decide whether you will run it immediately. A server can sit on the previous build for a few days while plugins catch up, as long as clients can still connect - for a major update they cannot, and you update regardless.
- Update frameworks first, then plugins. LabAPI comes with the game; then EXILED; then each plugin built for the new version.
- Leave unsupported loading off. LabAPI's
LoadUnsupportedPluginsdefaults tofalseso a plugin built for a different major version is refused rather than loaded. A plugin that loads and misbehaves mid-round is worse than one that does not load. - Test before the busy hours. A second server on another port with the same plugins is cheap - running a test server beside production explains how to keep one honest.
On RE:NODE the SCP:SL server's console is LocalAdmin's console with command history, so reload configs and pluginmanager show are typed where you read the output. The plugin and config folders are reachable in the file manager and over SFTP, and a backup slot taken before every update is the fastest way back to a working set - restoring is one button. The Schedules tab can run a daily restart at a quiet hour, which is also a natural moment to take updates deliberately rather than whenever the server happens to restart. What to do when a mod update breaks has the recovery order.
Performance#
Plugins, not players, are what make an SCP:SL server slow. The server targets a fixed tick rate, and every handler on a busy event - player movement, damage, item pickup - runs inside it. EXILED's tps command shows the current rate from the console. If it drops with plugins installed and not without, disable plugins one by one with pluginmanager disable between rounds until it recovers. A single plugin doing a database call on every damage event can halve the tick rate on a full server. What tick rate actually means explains what players feel when it drops.
Troubleshooting#
No EXILED banner on start. The loader is not in LabAPI/plugins/global/ or the port folder, or EXILED was installed into a different app data folder from the one the server reads. Re-run the installer with --appdata pointing at the right root.
A plugin is listed but nothing happens. is_enabled is false, its properties.yml disables it, or a dependency is missing - the console says which at load.
`MissingMethodException` after an update. The plugin was built against the previous game or framework version. Update or remove it.
Plugin commands say you lack permission. The group name in permissions.yml does not match the Remote Admin role name, or the file failed to parse because a group lacks inheritance or permissions.
Config changes revert. The YAML did not parse and defaults were regenerated. Validate the file, restore your copy, and check the console after the next start.
Config is not where the guide says. The guide assumes EXILED's single-file layout. Look under EXILED/Configs/Plugins/ or run econfig merge.
FAQ#
Do I need EXILED to run plugins?
No. LabAPI is built into the server and runs LabAPI plugins with nothing extra installed. You need EXILED only for plugins written for EXILED, which is still a large share of what is available.
Can LabAPI and EXILED plugins run at the same time?
Yes. EXILED's loader is itself a LabAPI plugin, so both kinds load together. The cost is an extra layer that has to be updated when LabAPI's major version changes.
Where do plugin configs go on a server with several ports?
LabAPI keeps configs in LabAPI/configs/<port>/, and EXILED's separated layout writes one file per port inside each plugin's config folder. Plugins in a global folder load for every port but still get per-port configs.
Why does my permission group not work?
The group name must match a role in config_remoteadmin.txt exactly, and every group needs both inheritance and permissions lines. One malformed group stops the whole file loading.
Should I let EXILED update itself?
Not on a live server. Automatic updates can install a new EXILED before your plugins support it. Update on purpose, after checking each plugin, with a backup taken first.
How do I reload a plugin config without restarting?
Use reload configs for EXILED or labapi reload configs for LabAPI, from the server console or Remote Admin. Settings that a plugin only reads at start still need a restart.




Comments
Completely anonymous: no account, no email, no cookie. We store the name you type, the text and the time - nothing else. Links are limited and markup is not rendered.