Build a plugin.
Client plugins are in-process C# components. They can read game state, replace behavior, patch engine methods and draw their own interface. This is more than a workshop mod, and it starts with a normal .NET project.
What a plugin is
SE Launcher loads plugins next to the game, not inside the game's mod sandbox. A plugin can use internal and private APIs, patch methods with Harmony, hook engine systems and render through Dear ImGui. That power is why the project asks for public source and a review before a plugin reaches the official PluginHub.
You will need C# experience and an IDE that can load a .NET project. If you are new to C#, start with the Microsoft C# documentation.
Set up
Install the templates
Install the official template package from the project's NuGet feed. The template adds a Space Engineers plugin project to your IDE's new-project menu.
dotnet new install CringePlugins.Templates --nuget-source https://ng.zznty.net/v3/index.jsonCreate a project from the template, then start a debug session. The template is set up so the game launches under the debugger with the plugin loaded. In Visual Studio and VS Code that is usually F5; in Rider, Shift + F9 for debug or Shift + F10 for run.
Local plugins
For quick iteration, a plugin can be loaded from the launcher's local plugin folder. Local plugins show up in the in-game plugin list as local, and the context menu can reload one without restarting the game. On Windows the folder is %APPDATA%\CringeLauncher\plugins.
Lifecycle
The base interface is VRage.Plugins.IPlugin. The launcher creates the plugin, calls Init, then Update on the game loop, and finally Dispose.
using VRage.Plugins;
public class Plugin : IPlugin
{
public void Init(object gameInstance)
{
}
public void Update()
{
}
public void Dispose()
{
}
}If your plugin needs dependency injection, implement IPluginWithServices instead. It gives you an IPluginContext with the plugin metadata and the loaded plugin map, and lets you register services during plugin setup.
Configuration
Use the launcher's config handler instead of inventing another settings file. It stores one JSON document per config ID, validates values against a generated schema, and broadcasts changes to every consumer that registered the same config.
public class Config
{
public string UserName { get; set; } = "John";
}
public void Init(object gameInstance)
{
var handler = MySandboxGame.Services.GetRequiredService<ConfigHandler>();
using var config = handler.RegisterConfig<Config>("test");
Log.Info("Hello, {UserName}", config.Value.UserName);
}- The config class must be public, have a parameterless constructor, and use public getters and setters.
- RegisterConfig<T>(id) returns a disposable reference.
- Assigning a new instance to .Value persists it and notifies other consumers. Mutating a property alone does not.
- Dispose the reference when the plugin no longer needs it.
UI with ImGui
Dear ImGui is the preferred UI system and what the launcher itself uses. Implement IRenderComponent and register it with the render handler. The launcher calls OnFrame() while it composes the frame.
using CringePlugins.Abstractions;
using ImGuiNET;
public class TestRenderComponent : IRenderComponent
{
public void OnFrame()
{
if (ImGui.Begin("Test Window"))
{
ImGui.Button("Test");
ImGui.End();
}
}
}
public void Init(object gameInstance)
{
RenderHandler.Current.RegisterComponent(new TestRenderComponent());
}ImGui gives you docking, floating viewports, tables and the usual immediate-mode widgets. For exploration, call ImGui.ShowDemoWindow() once; it exposes the full widget set with live examples.
Other UI systems are available when the job calls for them: the native VRage sandbox GUI (MyGuiScreenBase), EmptyKeys MVVM-XAML, and Windows Forms or WPF for external windows. They require more setup and are not the recommended path for an in-game panel.
Patching game code
Harmony is part of the launcher environment. Use it for runtime patches and give every plugin a unique Harmony ID so two plugins do not fight over the same patch slot. Patches coexist unless they try to replace the same behavior outright.
using HarmonyLib;
using NLog;
using Sandbox.Game.World;
[HarmonyPatch(typeof(MySession), nameof(MySession.SaveEnded))]
public static class SavePatch
{
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
public static void Prefix()
{
Log.Info("Hello world!");
}
}Apply the assembly's patches during plugin initialization:
public void Init(object gameInstance)
{
new Harmony("TestPlugin").PatchAll(typeof(Plugin).Assembly);
}Read the Harmony documentation before replacing a method. Prefixes and postfixes are usually enough; transpilers are harder to keep compatible across game updates.
Build and publish
Plugins are distributed as NuGet packages. Client plugins use the CringePlugin package type; dedicated plugins use CringePluginDedicated and are only loaded in --dedicated mode.
There are two supported routes:
- Official PluginHub — the recommended route for public plugins. The launcher's built-in browser can see the package, and users get launcher-managed updates. Submissions are reviewed and must follow the publishing guidelines.
- Your own NuGet source — add a source and package entry to the launcher's packages.json. You control distribution and updates, and you are responsible for hosting, versioning and compatibility.
The official guidelines and the current submission rules live on the wiki. The short version follows.
Publishing rules
- Public, human-readable source code hosted on GitHub. No obfuscated or minified source.
- Reasonable performance. A rendering plugin may cost more, but it must be justified by what it does.
- Do not modify, restrict or extend the APIs available to in-game mods and scripts.
- Touch only the files your plugin needs. Never modify core game files, mod assets or unrelated data.
- No multiplayer gameplay advantages: no extended ore detectors, mass inventory automation or automatic jump-drive chains.
- No loader modifications, external executables, process control or auto-update logic.
- Native libraries must be open source or from a trusted signed source, and distributed through NuGet.
- Comply with the Keen Software House EULA.
Questions about a submission, a compatibility problem or an API that is not documented yet? Ask in the Discord server. The wiki has the longer guides on decompiling the game, the config system, ImGui and Harmony.