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 =>
{
var engineConfig = new LuaEngineConfig(
AppContext.BaseDirectory,
scriptsDirectory,
"SquidStd.Samples.ScriptingLua",
"1.0.0"
);
container.RegisterInstance(engineConfig);
container.RegisterStdService<IScriptEngineService, LuaScriptEngineService>();
container.RegisterGeneratedScriptModules();
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 = 1
3 + 4 = 7
result = hello from C# and lua
How it works
IScriptEngineService wraps a MoonSharp Script. Registering it with RegisterStdService lets the bootstrap
call its StartAsync during StartAsync, which wires 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.