A .NET/C# implementation of the Lua 5.4.8 virtual machine and runtime, enabling Lua scripting to be embedded in .NET applications.
- Full Lua 5.4.8 VM execution engine
- Load and execute Lua source files or precompiled bytecode
- Compile Lua source to bytecode via a native compiler bridge (
luac1.dll) - Stack-based C API similar to the reference Lua C API
- Standard library support:
print,math.random,os.clock,io.write,table.new - Extensible module loader system (
FileModuleLoader,CompositeModuleLoader) - Metatable support for all value types
- Debug hook support (line, count, call, return hooks)
- High-performance internals: struct-based
LuaValuetagged union, unsafe optimizations, aggressive inlining
- .NET 10.0 SDK or later
- Windows (required for
luac1.dllnative compiler bridge) - CMake (optional, to rebuild the native
luac1.dllfrom source)
luacs/
├── Lua/ # Main C# library project
│ ├── Compiler/ # Binary bytecode load/dump (ProtoIO)
│ ├── Runtime/ # VM execution engine (LuaVM, ExecutionContext, Proto, OpCode)
│ ├── CodeAnalysis/ # Source code analysis utilities
│ ├── Internal/ # Internal helpers (collections, binary I/O, hashing)
│ ├── Loaders/ # Module loaders (FileModuleLoader, CompositeModuleLoader)
│ ├── Std/ # Standard library (print, math, os, io, table)
│ ├── LuaGlobalState.cs # Top-level state: environment, registry, loaded modules
│ ├── LuaState.cs # Per-thread state: value stack, call stack, C API
│ ├── LuaValue.cs # Tagged union struct for all Lua values
│ ├── LuaTable.cs # Lua table implementation (array + hash)
│ ├── ExternalCompiler.cs # P/Invoke bridge to native luac1.dll
│ └── Lua.csproj
├── lua-5.4.8/ # Native Lua C source and CMake build
└── luacs.sln # Visual Studio solution
dotnet build Lua/Lua.csprojThe repository includes a prebuilt lua-5.4.8/build/Debug/luac1.dll. To rebuild it from source using CMake:
cd lua-5.4.8
cmake -B build
cmake --build buildusing Lua;
var state = new LuaGlobalState();
state.OpenLibs(); // registers print, math, os, io, table
LuaState L = state.MainThread;
L.LoadSourceFile("script.lua"); // compiles and loads the script
LuaVM.Execute(L, 0, 0); // call with 0 args, discard resultsusing Lua;
var state = new LuaGlobalState();
state.OpenLibs();
LuaState L = state.MainThread;
byte[] bytecode = File.ReadAllBytes("script.luac");
L.LoadBinary(bytecode, "script");
LuaVM.Execute(L, 0, 0);using Lua;
byte[] bytecode = ExternalCompiler.Compile(@"
print('Hello from Lua!')
local x = 10 + 20
print(x)
");Register a C# delegate as a Lua global:
using Lua;
var state = new LuaGlobalState();
state.OpenLibs();
// Register a custom function
state.Environment["greet"] = new LuaCFunction(L =>
{
string name = L.GetValue(1).ToString();
Console.WriteLine($"Hello, {name}!");
return 0; // number of return values pushed
});
LuaState L = state.MainThread;
L.LoadSourceFile("script.lua"); // script can call greet("World")
LuaVM.Execute(L, 0, 0);LuaState exposes a stack-based API similar to the Lua C API:
L.PushValue(new LuaValue(42)); // push integer
L.PushValue(new LuaValue(3.14)); // push float
L.PushValue(new LuaValue("hello")); // push string
L.PushValue(new LuaValue(true)); // push boolean
L.PushValue(LuaValue.Nil); // push nil
L.PushValue(new LuaValue(new LuaTable())); // push table
int top = L.GetTop(); // number of values on the stack
LuaValue v = L.GetValue(1); // get value at index 1 (1-based)
L.Pop(1); // pop one valueBy default, LuaGlobalState uses FileModuleLoader to load .lua files by name. You can replace it with a custom loader:
state.ModuleLoader = new CompositeModuleLoader(
new FileModuleLoader(),
myCustomLoader
);The following standard library functions are registered by state.OpenLibs():
| Name | Description |
|---|---|
print(...) |
Print values to stdout, separated by spaces |
io.write(...) |
Write values to stdout without a newline |
math.random([m[, n]]) |
Generate random numbers |
os.clock() |
Return process runtime in seconds |
table.new([asize[, dsize]]) |
Create a table with pre-allocated capacity |
LuaValue is a struct that holds one of the following Lua value types:
LuaValueType |
Description |
|---|---|
Nil |
The nil value |
Boolean |
true or false |
Integer |
64-bit signed integer (long) |
Float |
64-bit float (double) |
String |
Immutable string |
Table |
Lua table (LuaTable) |
Function |
Lua closure or C# delegate |
UserData |
Custom .NET object implementing ILuaUserData |
Thread |
Lua coroutine (not yet fully implemented) |
The Lua virtual machine and standard library are based on Lua 5.4.8, which is licensed under the MIT License.
Copyright © 1994–2025 Lua.org, PUC-Rio.