Scripting with Lua
Embed a Lua engine in your host, expose C# values to scripts, and read results back.
What you'll build
A console host that registers the IScriptEngineService (SquidStd.Scripting.Lua) through the SquidStd
bootstrap, runs a small Lua script, and prints values evaluated by the engine.
Prerequisites
- .NET 10 SDK
dotnet add package SquidStd.Scripting.Luadotnet add package SquidStd.Services.Coredotnet add package SquidStd.Generators
Steps
1. Register the Lua engine
The engine needs a LuaEngineConfig (it watches a scripts directory) and is started by the bootstrap as a
SquidStd service. The DirectoriesConfig it depends on is already registered by the core services. The generated
script-module registration call adds any [RegisterScriptModule] modules before startup.
var scriptsDirectory = Path.Combine(AppContext.BaseDirectory, "scripts");
Directory.CreateDirectory(scriptsDirectory);
bootstrap.ConfigureServices(
container =>
{
container.RegisterCoreServices();
var engineConfig = new LuaEngineConfig(
AppContext.BaseDirectory,
scriptsDirectory,
"SquidStd.Samples.ScriptingLua",
"1.0.0"
);
container.RegisterLuaEngine(engineConfig);
container.RegisterGeneratedScriptModules();
container.RegisterScriptModule<LogModule>();
container.RegisterLuaEvents();
return container;
}
);
2. Run a script and read results
RegisterGlobal exposes a C# value under an exact name, ExecuteScript runs Lua code, and
ExecuteFunction evaluates an expression and returns a ScriptResult whose Data holds the value.
var engine = bootstrap.Resolve<IScriptEngineService>();
var stats = ((LuaScriptEngineService)engine).GetStats();
engine.RegisterGlobal("greeting", "hello from C#");
engine.ExecuteScript("result = greeting .. ' and lua'");
var sum = engine.ExecuteFunction("3 + 4");
var message = engine.ExecuteFunction("result");
Console.WriteLine($"lua modules = {stats.ModuleCount}");
Console.WriteLine($"3 + 4 = {sum.Data}");
Console.WriteLine($"result = {message.Data}");
3. Define a generated module
[RegisterScriptModule] opts the type into source generation. [ScriptModule("sample")] is still the runtime Lua
metadata used as the module name.
[RegisterScriptModule, ScriptModule("sample")]
internal sealed class SampleLuaModule { }
Run it
dotnet run --project samples/SquidStd.Samples.ScriptingLua
Prints:
lua modules = 3
3 + 4 = 7
result = hello from C# and lua
How it works
IScriptEngineService wraps a MoonSharp Script. RegisterLuaEngine registers the LuaEngineConfig instance
and the engine as the standard script engine service in one call, so the bootstrap calls its StartAsync
during StartAsync, wiring up modules, constants, and a file watcher over the configured scripts directory.
Globals you register become Lua variables, and ExecuteFunction evaluates a return <expression> and
surfaces the value through ScriptResult.Data.