Extensions - tayjay/SCriPt GitHub Wiki

Extending SCriPt

SCriPt exposes most of LabAPI to Lua out of the box: every LabApi.Features.Wrappers type and every LabAPI/base-game enum is registered automatically at startup, and all LabAPI event categories are discovered dynamically. This page covers what to do when you need something that isn't exposed by default — another plugin's API, an extra game type, or shared logic between scripts.

There are four approaches, from simplest to most involved.

1. Run RemoteAdmin commands (no code)

The easiest way to interact with another plugin is to call the RemoteAdmin commands it already provides:

Server.RACommand("mycommand arg1 arg2")

These run as the server console, so they bypass most permission checks. Because of that, RACommand/RACommandAs require the full_access config option (see Dangerous).

2. Share Lua code with require

If you just want to reuse Lua logic across scripts (helper functions, shared tables, a small library), put a module in the Scripts/lib folder and require it. No C# needed. See the Libraries page for the full guide.

local util = require("util")   -- loads Scripts/lib/util.lua
util.greet(player)

3. Register extra CLR types from a global script

Scripts in Scripts/global can register additional CLR types so that later scripts can use them. This is handy for types SCriPt doesn't register automatically (deeper game types, or another plugin's classes).

-- Register a type so its members are usable in Lua.
-- Use an assembly-qualified name ("Namespace.Type, AssemblyName") so the type can be resolved.
SCriPt.RegisterType("PlayerRoles.PlayableScps.Scp173.Scp173Role, Assembly-CSharp")

-- Expose a type's STATIC members as a named global.
SCriPt.AddStaticGlobal("SomePlugin.Api.MyApi, SomePlugin", "MyApi")

Sandbox guard: while sandboxed (the default), RegisterType/AddStaticGlobal refuse to register core framework types — anything in System.*, mscorlib, Microsoft.*, or Mono.* — so scripts can't reach System.IO, reflection, process, or networking APIs. Enable full_access to lift this restriction (see Dangerous).

LabAPI extension methods

SCriPt also registers LabAPI's extension-method classes (PermissionsExtensions, RoleExtensions, LinqExtensions), so their helpers are available on the relevant types — for example permission checks (HasPermissions, HasAnyPermission) and role helpers (IsScp, IsNtf, GetFullName).

4. Connect your own plugin (for plugin developers)

If you maintain a C# LabAPI plugin, you can register your own types and globals directly so server owners can script against them.

  1. Reference SCriPt.LabAPI.dll in your project. (You do not need to reference MoonSharp — but you may if you want finer control with [MoonSharpUserData]/[MoonSharpHidden] attributes.)
  2. Give your plugin a LoadPriority lower than SCriPt's (which is High) but it will still run before scripts load — Medium or Low works well. This guarantees SCriPt.Instance exists and your types are registered before any script runs.
  3. In your plugin's Enable, register what you need:
using SCriPt.LabAPI;

// Register a type for use in Lua
SCriPt.RegisterType<MyCustomType>();
SCriPt.RegisterType(typeof(MyCustomType));

// Expose a class of static members as a named Lua global (e.g. "MyApi")
SCriPt.RegisterGlobal<MyApi>("MyApi");
SCriPt.RegisterGlobal("MyApi", typeof(MyApi));

A global class is just a class of public static members:

public class MyApi
{
    public static int SomeValue => MyPlugin.Singleton.Value;

    public static void DoSomething(string message)
    {
        // ...
    }
}

Scripts can then use it directly:

MyApi.DoSomething("hello from Lua")
print(MyApi.SomeValue)

By default all public members are exposed. If you want to hide specific members, add [MoonSharpHidden] to them (this requires referencing MoonSharp.Interpreter).

⚠️ **GitHub.com Fallback** ⚠️