CSharpScriptLoader is a TShock v6 plugin that loads small C# scripts from disk as if they were normal TShock plugins.
Drop a .cs file into tshock/csharp-scripts, run /csreload, and the plugin compiles it with Roslyn, loads the resulting assembly, creates every TerrariaPlugin class it finds, and calls Initialize().
Credits: @isawicca
Sometimes you want a tiny server-side plugin without creating a full project, building locally, copying DLLs, and restarting everything. This loader gives you a quick script workflow for admin tools, small command plugins, tests, and one-off server logic.
A script is still real C# running inside your server. Only let trusted admins write scripts.
Build the project against your TShock folder:
dotnet publish -c Release /p:TShockPath="/path/to/tshock" -o publishCopy these release files into ServerPlugins:
CSharpScriptLoader.dll
CSharpScriptLoader.deps.json
Microsoft.CodeAnalysis.dll
Microsoft.CodeAnalysis.CSharp.dll
Then start the server once. A config file is created at:
tshock/CSharpScriptLoader.json
Put scripts here:
tshock/csharp-scripts
Reload scripts from the server console or in-game:
/csreload
List loaded scripts:
/cslist
A script should be one complete .cs file with one or more classes that inherit TerrariaPlugin.
using System;
using System.Collections.Generic;
using Terraria;
using TerrariaApi.Server;
using TShockAPI;
namespace MyScripts;
[ApiVersion(2, 1)]
public sealed class HelloScript : TerrariaPlugin
{
public override string Name => "HelloScript";
public override string Author => "Me";
public override string Description => "Simple command script.";
public override Version Version => new(1, 0, 0, 0);
private readonly List<Command> _commands = new();
public HelloScript(Main game) : base(game)
{
}
public override void Initialize()
{
var command = new Command(HandleHello, "hello");
_commands.Add(command);
Commands.ChatCommands.Add(command);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
foreach (var command in _commands)
Commands.ChatCommands.Remove(command);
_commands.Clear();
}
base.Dispose(disposing);
}
private void HandleHello(CommandArgs args)
{
args.Player.SendSuccessMessage("Hello from a script.");
}
}The loader compiles scripts against the live server environment instead of only a tiny fixed DLL list.
By default it uses loaded TShock/Terraria assemblies, scans common folders, and allows known dependencies like Newtonsoft.Json.dll when available. You can add your own DLLs in CSharpScriptLoader.json:
{
"ReferenceAssemblies": [
"ServerPlugins/MyLibrary.dll",
"lib/SomeDependency.dll"
],
"ReferenceSearchDirectories": [
".",
"ServerPlugins",
"lib",
"libs"
]
}The loader avoids referencing old generated script assemblies, because that can create duplicate script-local types during reloads.
Optional AI commands are available but disabled by default.
Enable them in tshock/CSharpScriptLoader.json:
{
"EnableLlmCommands": true,
"ModelStudioBaseUrl": "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
"ModelStudioModel": "qwen3.6-plus",
"ModelStudioApiKeyEnvironmentVariable": "DASHSCOPE_API_KEY"
}Then set your API key in the environment and restart the server:
export DASHSCOPE_API_KEY="sk-your-key"Generate a script:
/csmake MyScript.cs create a command /hug <player> that broadcasts a hug message
Fix an existing script:
/csfix MyScript.cs fix the compile errors and keep the current behavior
Generated code is validated with the same script compiler before it is written. If it does not compile after repair attempts, the original file is left alone.
| Command | Permission | What it does |
|---|---|---|
/csreload |
csloader.reload |
Recompile and reload all scripts. |
/cslist |
csloader.list |
Show loaded script plugins. |
/csmake name.cs <prompt> |
csloader.llm |
Generate a script with Model Studio. |
/csfix name.cs <prompt> |
csloader.llm |
Repair a script with Model Studio. |
Unload safety depends on the script. If a script registers commands, hooks, timers, or static state, it must clean them up in Dispose(bool disposing).
This is a developer tool, not a sandbox. Scripts can do anything a compiled TShock plugin can do.