### Install LuaCSharp via NuGet CLI Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Use the .NET CLI to add the LuaCSharp package to your project. ```bash dotnet add package LuaCSharp ``` -------------------------------- ### Install Lua C# via NuGet Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/00-index.md Use the NuGet package manager to add the LuaCSharp library to your project. ```bash # NuGet dotnet add package LuaCSharp # Package Manager Install-Package LuaCSharp ``` -------------------------------- ### Default Platform Usage Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/07-modules-platform.md Examples demonstrating how to use the default LuaPlatform, which utilizes the real file system, console I/O, and system environment. ```APIDOC ### Default Platform ```csharp // Uses real file system, console I/O, system environment var state = LuaState.Create(); // Uses LuaPlatform.Default // Explicit var state = LuaState.Create(LuaPlatform.Default); ``` ``` -------------------------------- ### Create Default LuaState Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Creates a new Lua state with default platform configuration. This is the simplest way to get started with Lua execution. ```csharp var state = LuaState.Create(); var results = await state.DoStringAsync("return 1 + 1"); Console.WriteLine(results[0].Read()); // 2 ``` -------------------------------- ### Example of RunAsync() usage Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Demonstrates how to load a Lua function, push it onto the stack, and execute it using RunAsync(). Shows how to check the number of return values. ```csharp var closure = state.Load("return 1, 2, 3", "test"); state.Push(closure); var count = await state.RunAsync(closure); // 3 return values on stack ``` -------------------------------- ### Install LuaCSharp via Package Manager Console Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Use the Package Manager Console in Visual Studio to install the LuaCSharp package. ```powershell Install-Package LuaCSharp ``` -------------------------------- ### Example of ResumeAsync() usage Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Demonstrates resuming a coroutine by pushing values onto a LuaStack and then calling ResumeAsync(). Shows how to retrieve the number of yielded values. ```csharp var stack = new LuaStack(); stack.Push(1); var count = await coroutine.ResumeAsync(stack); ``` -------------------------------- ### Project Structure Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/11-best-practices.md Illustrates a typical project layout for a C# project integrating Lua scripts, separating Lua code into a dedicated directory. ```plaintext MyProject/ ├── lua/ │ ├── core/ │ │ ├── config.lua │ │ └── utils.lua │ ├── game/ │ │ ├── entities.lua │ │ └── systems.lua │ └── main.lua ├── src/ │ └── LuaIntegration.cs └── tests/ └── LuaTests.cs ``` -------------------------------- ### Complete Lua Standard Library Setup and Execution Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Sets up a Lua state, opens all standard libraries, executes a Lua script demonstrating various standard library functions (Math, String, Table, Basic), and retrieves the result. ```csharp using Lua; using Lua.Standard; var state = LuaState.Create(); // Open all standard libraries state.OpenStandardLibraries(); var result = await state.DoStringAsync(@" -- Math local x = math.sqrt(16) print('sqrt(16) = ' .. x) -- String local str = string.upper('hello') print('Upper: ' .. str) -- Table local t = {3, 1, 4, 1, 5} table.sort(t) print('Sorted: ' .. table.concat(t,',')) -- Basic print('Type of t: ' .. type(t)) return x "); Console.WriteLine($"Result: {result[0].Read()}"); ``` -------------------------------- ### Return() Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Returns no values from a Lua function. Use this for functions that perform an action but do not need to return any data. ```csharp return context.Return(); // void function ``` -------------------------------- ### Return(LuaValue) Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Returns a single value from a Lua function. This is the most common way to return a result. ```csharp return context.Return(42); ``` -------------------------------- ### Custom Lua Platform Setup Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/07-modules-platform.md Configures and creates a Lua state with a custom platform, utilizing a sandboxed file system and a restricted OS environment. This is ideal for secure, isolated Lua script execution. ```csharp var customPlatform = new LuaPlatform( FileSystem: new SandboxedFileSystem("./lua_scripts"), OsEnvironment: new RestrictedOsEnvironment(), StandardIO: new LoggingStandardIO(logger), TimeProvider: TimeProvider.System ); var state = LuaState.Create(customPlatform); ``` -------------------------------- ### Work with Lua Tables in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Provides examples for creating Lua tables in C#, populating them with key-value pairs and array elements, passing them to Lua, and receiving tables from Lua scripts. ```csharp // Create in C# var table = new LuaTable(); table["x"] = 10; table["y"] = 20; table[1] = "first"; table[2] = "second"; // Pass to Lua state.Environment["myTable"] = table; // Receive from Lua var results = await state.DoStringAsync("return {a=1, b=2, c=3}"); var received = results[0].Read(); var a = received["a"].Read(); ``` -------------------------------- ### Open Coroutine Library and Execute Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Opens the Coroutine library and demonstrates its usage by creating, resuming, and yielding coroutines in Lua. This example shows how to manage coroutine execution flow. ```csharp state.OpenCoroutineLibrary(); var result = await state.DoStringAsync(@" local co = coroutine.create(function() print('1') coroutine.yield() print('2') end) coroutine.resume(co) -- prints 1 coroutine.resume(co) -- prints 2"); ``` -------------------------------- ### Use Custom Module Loader Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/07-modules-platform.md Integrate a custom module loader by assigning it to the `state.ModuleLoader` property. This example demonstrates loading a 'helpers' module and using its function. ```csharp var loader = new CustomModuleLoader(); loader.AddModule("helpers", "local function add(a, b) return a + b end return add"); state.ModuleLoader = loader; var results = await state.DoStringAsync(@" local add = require 'helpers' return add(10, 20) "); Console.WriteLine(results[0].Read()); // 30 ``` -------------------------------- ### Lua Math Library Functions Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Shows how to use various math functions such as sqrt, max, and sin within a Lua script executed via C#. ```csharp state.OpenMathLibrary(); var result = await state.DoStringAsync(@" print(math.sqrt(16)) -- 4 print(math.max(1, 5, 3)) -- 5 print(math.sin(math.pi/2)) -- 1.0"); ``` -------------------------------- ### LuaValue Nil Handling Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/02-luavalue.md Provides examples of checking if a LuaValue is nil using its Type property or by comparing it with LuaValue.Nil. ```csharp if (value.Type == LuaValueType.Nil) { // Handle nil case } var isNil = value.Equals(LuaValue.Nil); ``` -------------------------------- ### Return(LuaValue, LuaValue) Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Returns two values from a Lua function. This overload is part of a set supporting up to three return values. ```csharp return context.Return(10, 20); ``` -------------------------------- ### Defining C# Functions for Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/00-index.md Example of creating a LuaFunction in C# that can be called from Lua, accepting arguments and returning values. ```csharp var func = new LuaFunction(async (ctx, ct) => { var arg = ctx.GetArgument(0); return ctx.Return(arg * 2); }); ``` -------------------------------- ### Unit Testing Lua Scripts with C# Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/11-best-practices.md Demonstrates a unit testing pattern for Lua scripts using C# and a testing framework, including setup, cleanup, and testing script logic. ```csharp [TestClass] public class LuaScriptTests { private LuaState state; [TestInitialize] public void Setup() { state = LuaState.Create(); state.OpenStandardLibraries(); } [TestCleanup] public void Cleanup() { state?.Dispose(); } [TestMethod] public async Task CalculateSum_ReturnsCorrectResult() { var result = await state.DoStringAsync(@" function sum(a, b) return a + b end return sum(10, 20) "); Assert.AreEqual(30, result[0].Read()); } [TestMethod] [ExpectedException(typeof(LuaRuntimeException))] public async Task DivideByZero_ThrowsError() { await state.DoStringAsync("return 1 / 0"); } } ``` -------------------------------- ### DirectoryModuleLoader Usage Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/07-modules-platform.md Loads modules from the file system using a specified directory. This example demonstrates setting the module loader and then requiring a module. ```csharp var loader = new DirectoryModuleLoader("modules"); state.ModuleLoader = loader; // Loads from modules/mymodule.lua var module = await state.DoStringAsync("return require 'mymodule'"); ``` -------------------------------- ### Configuring Lua Module Loading in Unity Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Set up Lua module loading using either the Resources or Addressables system. The Addressables option requires the Addressables package to be installed. ```csharp // Use Resources for module loading state.ModuleLoader = new ResourcesModuleLoader(); ``` ```csharp // Use Addressables for module loading (requires the Addressables package) state.ModuleLoader = new AddressablesModuleLoader(); ``` -------------------------------- ### Lua String Library Functions Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Illustrates the use of string manipulation functions like len, sub, upper, and gsub in Lua, executed through C#. ```csharp state.OpenStringLibrary(); var result = await state.DoStringAsync(@" print(string.len('hello')) -- 5 print(string.sub('hello', 1, 3)) -- hel print(string.upper('hello')) -- HELLO local s = string.gsub('aaa', 'a', 'b') print(s) -- bbb"); ``` -------------------------------- ### Implement Custom Lua Module Loader Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/07-modules-platform.md Implement the `ILuaModuleLoader` interface to define custom logic for loading Lua modules. This example uses a dictionary to store module content. ```csharp public class CustomModuleLoader : ILuaModuleLoader { private readonly Dictionary modules = new(); public bool Exists(string moduleName) { return modules.ContainsKey(moduleName); } public ValueTask LoadAsync( string moduleName, CancellationToken cancellationToken = default ) { if (modules.TryGetValue(moduleName, out var content)) { return new(new LuaModule(moduleName, content)); } throw new InvalidOperationException($"Module '{moduleName}' not found"); } public void AddModule(string name, string content) { modules[name] = content; } } ``` -------------------------------- ### Open Operating System Library and Execute Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Opens the OS library and executes Lua code to print the formatted date and get an environment variable. Ensure the OS library is opened before calling its functions. ```csharp state.OpenOperatingSystemLibrary(); var result = await state.DoStringAsync(@" print(os.date('%Y-%m-%d %H:%M:%S')) print(os.getenv('PATH'))"); ``` -------------------------------- ### Use Lua Metamethods with Custom Objects Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Demonstrate the usage of custom Lua metamethods defined in C#. This example shows arithmetic operations and string conversion for Vector3 objects in Lua. ```lua local v1 = Vector3.create(1, 1, 1) local v2 = Vector3.create(2, 2, 2) print(v1) -- <1, 1, 1> print(v2) -- <2, 2, 2> print(v1 + v2) -- <3, 3, 3> print(v1 - v2) -- <-1, -1, -1> ``` -------------------------------- ### ArrayLength Property Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Gets the logical length of the table's array component, which is the count of consecutive non-nil elements starting from index 1. ```APIDOC ## ArrayLength Property ### Description Gets the logical length of the table's array component (count of consecutive non-nil elements starting from index 1). ### Type `int` ### Access Read-only ### Example ```csharp var table = new LuaTable(); table[1] = 10; table[2] = 20; Console.WriteLine(table.ArrayLength); // 2 table[3] = null; // Create nil gap table[4] = 40; Console.WriteLine(table.ArrayLength); // 2 (stops at first nil) ``` ``` -------------------------------- ### Build Entire Solution Source: https://github.com/nuskey8/lua-csharp/blob/main/CLAUDE.md Use this command to build the entire .NET solution. ```bash dotnet build ``` -------------------------------- ### Lua Debug Hook Installation in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/11-best-practices.md Sets up a debug hook in Lua to trace execution, specifically capturing line execution events. This is useful for debugging and understanding script flow. ```csharp public class DebugTracer { private readonly LuaState state; public void Enable() { var hook = new LuaFunction(async (context, ct) => { var frame = context.State.GetCurrentFrame(); Console.WriteLine($"Executing: {frame.Function.Name}"); return context.Return(); }); state.SetHook(hook, "l", 0); // Line hook } public void Disable() { state.SetHook(null, "", 0); } } ``` -------------------------------- ### GetStatus Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Gets the current status of the thread or coroutine. ```APIDOC ## GetStatus() ### Description Gets the current status of the thread/coroutine. ### Method `LuaThreadStatus GetStatus()` ### Returns `LuaThreadStatus` — one of: Suspended, Normal, Running, Dead ### Example ```csharp if (coroutine.GetStatus() == LuaThreadStatus.Suspended) { await coroutine.ResumeAsync(stack); } ``` ``` -------------------------------- ### Setting Up Unity-Specific Platform Environment Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Initialize a LuaState with Unity-specific implementations for file system, OS environment, and standard I/O. This directs Lua's print to Unity's Debug.Log and handles os.exit by calling Application.Quit(). ```csharp var platform = new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new UnityApplicationOsEnvironment(), // OsEnvironment for Unity StandardIO: new UnityStandardIO(), // StandardIO for Unity TimeProvider: TimeProvider.System); var state = LuaState.Create(platform); ``` -------------------------------- ### Build Solution in Release Mode Source: https://github.com/nuskey8/lua-csharp/blob/main/CLAUDE.md Build the entire .NET solution in Release configuration for optimized output. ```bash dotnet build -c Release ``` -------------------------------- ### Table Operations Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/10-types-reference.md Asynchronous methods for getting and setting values in Lua tables. ```APIDOC ## GetTableAsync ### Description Asynchronously retrieves a value from a Lua table by key. ### Method `public static ValueTask GetTableAsync(this LuaState state, LuaValue table, LuaValue key, CancellationToken ct = default)` ## SetTableAsync ### Description Asynchronously sets a value in a Lua table by key. ### Method `public static ValueTask SetTableAsync(this LuaState state, LuaValue table, LuaValue key, LuaValue value, CancellationToken ct = default)` ``` -------------------------------- ### Create LuaState with Default Platform Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/07-modules-platform.md Shows how to create a LuaState using the default LuaPlatform, which utilizes the real file system, console I/O, and system environment. It also demonstrates explicit instantiation. ```csharp // Uses real file system, console I/O, system environment var state = LuaState.Create(); // Uses LuaPlatform.Default // Explicit var state = LuaState.Create(LuaPlatform.Default); ``` -------------------------------- ### Handle LuaRuntimeException Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/06-exceptions.md Example of catching a LuaRuntimeException when executing Lua code that has runtime errors. ```csharp try { await state.DoStringAsync(@" local t = {} local result = t + 5 -- Can't add table to number "); } catch (LuaRuntimeException ex) { Console.WriteLine($"Runtime error: {ex.Message}"); Console.WriteLine($"Error at: {ex.LuaTraceback}"); } ``` -------------------------------- ### Lua Table Storage Components Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md This example illustrates how Lua tables utilize both array and hash components for storage. Integer keys within a specific range are stored in the array component for O(1) access, while other keys are stored in the hash component. ```csharp var table = new LuaTable(); // This uses the array component (key = 1) table[1] = "first"; // This uses the hash component (key = "name") table["name"] = "Alice"; // This uses the hash component (large integer key) table[1000000] = "large"; ``` -------------------------------- ### Handle LuaCompileException Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/06-exceptions.md Example of catching a LuaCompileException when executing Lua code that has compilation errors. ```csharp try { await state.DoStringAsync(@" local function f() return x -- x is not in scope end "); } catch (LuaCompileException ex) { Console.WriteLine(ex.MainMessage); } ``` -------------------------------- ### Table Access Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Provides methods for getting and setting values within Lua tables from C#. ```APIDOC ## Table Access Operations ### Description Allows getting and setting values in Lua tables using C#. ### Methods - **`await state.GetTableAsync(table, key)`**: Retrieves the value associated with `key` from `table`. Can be used for `table[key]` or `table.x` if `key` is a string like "x". - **`await state.SetTableAsync(table, key, value)`**: Sets the value of `table[key]` to `value`. Can be used for `table[key] = value` or `table.x = value` if `key` is a string like "x". ``` -------------------------------- ### Basic Lua Script Execution in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/00-index.md Demonstrates creating a Lua state, opening standard libraries, executing a simple Lua script, and reading the result. Ensure to dispose of the Lua state when done. ```csharp using Lua; using Lua.Standard; // Create state var state = LuaState.Create(); state.OpenStandardLibraries(); // Execute script var results = await state.DoStringAsync("return 1 + 2"); Console.WriteLine(results[0].Read()); // 3 // Cleanup state.Dispose(); ``` -------------------------------- ### Build the Solution Source: https://github.com/nuskey8/lua-csharp/blob/main/CONTRIBUTING.md Use this command to build the entire Lua-CSharp solution in Release mode. ```sh dotnet build Lua.slnx -c Release ``` -------------------------------- ### HashMapCount Property Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Gets the number of key-value pairs currently stored in the hash component of the table. ```APIDOC ## HashMapCount Property ### Description Gets the number of key-value pairs in the hash component (excluding nil entries). ### Type `int` ### Access Read-only ### Example ```csharp // Assuming 'table' is a LuaTable instance Console.WriteLine(table.HashMapCount); ``` ``` -------------------------------- ### Create NuGet Package Source: https://github.com/nuskey8/lua-csharp/blob/main/CLAUDE.md Create a NuGet package for the project in Release mode. ```bash dotnet pack -c Release ``` -------------------------------- ### Metatable Property Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Gets or sets the metatable associated with the LuaTable, used for operator overloading and method lookup. ```APIDOC ## Metatable Property ### Description Gets or sets the metatable for operator overloading and method lookup. ### Type `LuaTable?` ### Access Read/Write ### Example ```csharp var metatable = new LuaTable(); metatable["__tostring"] = stringFunc; table.Metatable = metatable; ``` ``` -------------------------------- ### LuaState.Create() Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Creates a new Lua state with default platform configuration. This is the primary way to initialize a Lua environment. ```APIDOC ## LuaState.Create() ### Description Creates a new Lua state with default platform configuration. ### Method `public static LuaState Create()` ### Returns A new `LuaState` instance. ### Example ```csharp var state = LuaState.Create(); var results = await state.DoStringAsync("return 1 + 1"); Console.WriteLine(results[0].Read()); // 2 ``` ``` -------------------------------- ### HasArgument() Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Checks if an argument was provided and is not nil. This is useful for optional arguments or validating input before attempting retrieval. ```csharp var func = new LuaFunction(async (context, ct) => { if (context.HasArgument(0)) { var value = context.GetArgument(0); // Use value } else { // Use default } return context.Return(); }); ``` -------------------------------- ### Create LuaState with Default Platform Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Use this to create a LuaState instance with the default platform configuration. ```csharp var state = LuaState.Create(); // Uses default platform ``` -------------------------------- ### Read() Method Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/02-luavalue.md Reads a LuaValue as a specific C# type T. Throws an InvalidOperationException if conversion is not possible. ```csharp var value = await state.DoStringAsync("return 'hello'"); var str = value[0].Read(); // "hello" ``` -------------------------------- ### Async C# Function with await for Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Create an asynchronous C# function that can be awaited from Lua, using `Task.Delay` as an example. ```csharp var waitFunc = new LuaFunction("wait", async (context, ct) => { var seconds = context.GetArgument(0); await Task.Delay(TimeSpan.FromSeconds(seconds), ct); return context.Return($"Waited {seconds}s"); }); state.Environment["wait"] = waitFunc; await state.DoStringAsync(@" print('Starting...') wait(1.0) print('Done!') "); ``` -------------------------------- ### Build NuGet Package Project Source: https://github.com/nuskey8/lua-csharp/blob/main/CONTRIBUTING.md If you only need to build the NuGet package project, use this command. ```sh dotnet build src/Lua/Lua.csproj -c Release ``` -------------------------------- ### Open and Customize Package Table Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Opens the module library and demonstrates how to access and customize the 'package' table's search path. ```csharp state.OpenModuleLibrary(); var packageTable = state.Environment["package"].Read(); // Customize search path packageTable["path"] = "./lua_modules/?.lua;./lib/?.lua"; ``` -------------------------------- ### TryRead() Method Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/02-luavalue.md Attempts to read a LuaValue as a specific C# type T. Returns false if conversion is not possible. ```csharp var luaValue = 42.5; if (luaValue.TryRead(out var num)) { Console.WriteLine(num); // 42.5 } if (luaValue.TryRead(out var intVal)) { // Won't execute (42.5 is not an integer) } ``` -------------------------------- ### Write to a File using IO Library Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Shows how to open a file in write mode, write content to it, and close the file using the 'io' library. Both 'io' and 'basic' libraries need to be opened. ```csharp state.OpenIOLibrary(); state.OpenBasicLibrary(); var result = await state.DoStringAsync(@" local f = io.open('test.txt', 'w') f:write('Hello, ') f:write('world!') f:close()"); ``` -------------------------------- ### Create Basic C# Function for Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Define a C# function that can be called from Lua. This example shows a simple addition function. ```csharp var addFunc = new LuaFunction("add", async (context, ct) => { var a = context.GetArgument(0); var b = context.GetArgument(1); return context.Return(a + b); }); state.Environment["add"] = addFunc; var result = await state.DoStringAsync("return add(10, 20)"); Console.WriteLine(result[0].Read()); // 30 ``` -------------------------------- ### UnityStandardIO Implementation Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/09-unity-integration.md Implements standard I/O for Unity, routing print() output to Debug.Log instead of the console. ```csharp public class UnityStandardIO : ILuaStandardIO { public ILuaStream Input { get; } public ILuaStream Output { get; } public ILuaStream Error { get; } } ``` ```csharp var state = LuaState.Create(new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new UnityApplicationOsEnvironment(), StandardIO: new UnityStandardIO(), // Uses Debug.Log TimeProvider: TimeProvider.System )); // print() output goes to Debug.Log await state.DoStringAsync("print('Hello from Lua')"); ``` -------------------------------- ### Return(ReadOnlySpan) Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Returns multiple values as a span from a Lua function. Use this for returning an arbitrary number of results. ```csharp var results = new[] { (LuaValue)10, (LuaValue)20, (LuaValue)30 }; return context.Return(results); // 3 values ``` -------------------------------- ### Using Basic Library Functions in Lua-CSharp Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Demonstrates opening the basic library and executing Lua code that uses functions like assert, print, and type. Ensure the basic library is opened before executing Lua strings that rely on its functions. ```csharp state.OpenBasicLibrary(); var result = await state.DoStringAsync(@" assert(1 + 1 == 2, 'Math is broken') print('Hello, world!') print(type({})) -- table"); ``` -------------------------------- ### Debugging with Lua Traceback Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Shows how to use the debug.traceback function to get a stack trace in Lua. The debug library must be opened first. ```csharp state.OpenDebugLibrary(); var result = await state.DoStringAsync(@" local function test() error('test error') end print(debug.traceback())"); ``` -------------------------------- ### Initialize Lua State in Unity Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/09-unity-integration.md Sets up a Lua state with Unity-specific platform configurations, opens standard libraries, and configures a module loader for Unity's Resources folder. This script should be attached to a GameObject in your Unity scene. ```csharp using UnityEngine; using Lua; using Lua.Standard; using Lua.Unity; public class LuaManager : MonoBehaviour { private LuaState state; async void Start() { // Create Lua state with Unity platform var platform = new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new UnityApplicationOsEnvironment(), StandardIO: new UnityStandardIO(), TimeProvider: TimeProvider.System ); state = LuaState.Create(platform); // Load standard libraries state.OpenStandardLibraries(); // Set up module loader for Resources folder state.ModuleLoader = new ResourcesModuleLoader(); // Execute a Lua script asset var scriptAsset = Resources.Load("Scripts/game_logic"); var results = await state.DoStringAsync(scriptAsset.Text); Debug.Log($ ``` ```csharp void OnDestroy() { state?.Dispose(); } } ``` -------------------------------- ### GetArgument() Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Retrieves an argument by index with automatic type conversion. Use this when you need a specific type and want Lua to handle the conversion. ```csharp var func = new LuaFunction(async (context, ct) => { var arg0 = context.GetArgument(0); var arg1 = context.GetArgument(1); var arg2 = context.GetArgument(2); return context.Return(arg0 + 1); }); ``` -------------------------------- ### LuaValue Light Userdata Creation and Reading Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/02-luavalue.md Demonstrates creating a light userdata by wrapping a .NET object in a LuaValue and reading it back. ```csharp var obj = new MyClass(); LuaValue light = obj; // Light userdata var retrieved = light.Read(); ``` -------------------------------- ### Working with Lua Tables in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/00-index.md Demonstrates creating a LuaTable and assigning values using both string keys and integer indices. ```csharp var t = new LuaTable(); t["key"] = "value"; t[1] = "first"; ``` -------------------------------- ### Run Performance Benchmarks Source: https://github.com/nuskey8/lua-csharp/blob/main/CLAUDE.md Execute performance benchmarks in Release mode for the specified project. ```bash dotnet run -c Release --project sandbox/Benchmark/Benchmark.csproj ``` -------------------------------- ### this[LuaValue] Indexer Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Provides access to table values using a LuaValue key. Supports both getting and setting values, and handles array-like and dictionary-like access. ```APIDOC ## this[LuaValue key] Indexer ### Description Gets or sets a table value by key. Supports both numeric and non-numeric keys. ### Parameters - **key** (LuaValue) - The key to access ### Returns (get) The value at the key, or `LuaValue.Nil` if not present. ### Rules - Keys with `LuaValueType.Nil` throw an error. - Numeric keys are stored in the array component if they are positive integers within range. - Other keys are stored in the hash component. - Reading a non-existent key returns `LuaValue.Nil`. ### Example ```csharp var table = new LuaTable(); // Array access (1-indexed like Lua) table[1] = "first"; table[2] = "second"; Console.WriteLine(table[1].Read()); // "first" // String key access table["name"] = "Alice"; Console.WriteLine(table["name"].Read()); // "Alice" // Numeric key access table[10] = 100; Console.WriteLine(table[10].Read()); // 100 ``` ``` -------------------------------- ### LuaState.Create(LuaPlatform) Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Creates a new Lua state with a custom platform configuration, allowing for specific I/O and file system integrations. ```APIDOC ## LuaState.Create(LuaPlatform) ### Description Creates a new Lua state with a custom platform configuration. ### Method `public static LuaState Create(LuaPlatform platform)` ### Parameters #### Path Parameters - **platform** (LuaPlatform) - Required - Custom platform abstraction for file system, I/O, and OS operations ### Returns A new `LuaState` instance. ### Example ```csharp var platform = new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new SystemOsEnvironment(), StandardIO: new ConsoleStandardIO(), TimeProvider: TimeProvider.System ); var state = LuaState.Create(platform); ``` ``` -------------------------------- ### Run All Tests Source: https://github.com/nuskey8/lua-csharp/blob/main/CLAUDE.md Execute all unit tests in the project. ```bash dotnet test ``` -------------------------------- ### GetArgument(int) Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/04-luafunction.md Retrieves a raw LuaValue argument without type conversion. Use this when you need to inspect the type or value directly before conversion. ```csharp var luaValue = context.GetArgument(0); if (luaValue.Type == LuaValueType.String) { var str = luaValue.Read(); } ``` -------------------------------- ### Lua Integration - From Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Demonstrates how to create a LuaTable from a Lua script and access its elements in C#. ```APIDOC ## Lua Integration - From Lua ### Description Creates a table in Lua and retrieves it as a `LuaTable` object in C#. ### Lua Script Example ```lua local t = { a = 1, b = 2, c = 3 } return t ``` ### C# Code Example ```csharp // Assuming 'state' is an initialized Lua state var results = await state.DoStringAsync("return { a = 1, b = 2, c = 3 }"); var table = results[0].Read(); Console.WriteLine(table["a"].Read()); // 1 ``` ``` -------------------------------- ### Lua Table Operation Extension Methods Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/10-types-reference.md Methods for interacting with Lua tables, including getting and setting values by key. Ensure the provided LuaValue is a table. ```csharp public static ValueTask GetTableAsync(this LuaState state, LuaValue table, LuaValue key, CancellationToken ct = default) ``` ```csharp public static ValueTask SetTableAsync(this LuaState state, LuaValue table, LuaValue key, LuaValue value, CancellationToken ct = default) ``` -------------------------------- ### Load Configuration from Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Demonstrates how to define and load configuration values from a Lua script into a C# LuaTable. This is useful for externalizing application settings. ```csharp var config = new LuaTable(); state.Environment["config"] = config; await state.DoStringAsync(@" config.database = 'mydb' config.port = 5432 config.timeout = 30 "); var db = state.Environment["config"].Read(); ``` -------------------------------- ### Define C# Function for Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/00-index.md Create a C# function that can be called from Lua. Use LuaFunction constructor and context methods to get arguments and return values. ```csharp state.Environment["add"] = new LuaFunction(async (ctx, ct) => { var a = ctx.GetArgument(0); var b = ctx.GetArgument(1); return ctx.Return(a + b); }); ``` -------------------------------- ### Initialize LuaPlatform for Sandboxing Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Create a LuaPlatform instance to provide an abstracted environment for Lua execution, including file system, OS environment, I/O, and time. This is used for core Lua functions like require, print, dofile, and the os module. ```csharp var platform = new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new SystemOsEnvironment(), StandardIO: new ConsoleStandardIO(), TimeProvider: TimeProvider.System); var state = LuaState.Create(platform); ``` -------------------------------- ### Get LuaTable HashMap Count Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Returns the number of key-value pairs stored in the hash component of the LuaTable. This count excludes entries that have been explicitly set to nil. ```csharp public int HashMapCount { get; } ``` -------------------------------- ### Lua Integration - To Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Shows how to create a LuaTable in C# and expose it to a Lua environment, allowing Lua scripts to interact with it. ```APIDOC ## Lua Integration - To Lua ### Description Creates a `LuaTable` in C#, assigns it to the Lua environment, and then accesses its properties from a Lua script. ### C# Code Example ```csharp var table = new LuaTable(); table["x"] = 10; table["y"] = 20; state.Environment["myTable"] = table; ``` ### Lua Script Example (executed in C#) ```lua return myTable.x + myTable.y ``` ### C# Execution and Result ```csharp // Assuming 'state' is an initialized Lua state and 'myTable' is set as above var results = await state.DoStringAsync("return myTable.x + myTable.y"); Console.WriteLine(results[0].Read()); // 30 ``` ``` -------------------------------- ### Creating and Using LuaState Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/00-index.md Shows the basic instantiation of a LuaState for executing Lua code and its subsequent disposal. ```csharp var state = LuaState.Create(); var results = await state.DoStringAsync("return 'hello'"); state.Dispose(); ``` -------------------------------- ### AddressablesModuleLoader Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/09-unity-integration.md Loads Lua modules using Unity's Addressables system. This requires the Addressables package to be installed. Modules are loaded based on their assigned addresses or labels. ```APIDOC ## Class AddressablesModuleLoader ### Description Loads Lua modules using Unity's Addressables system. ### Methods #### `Exists(string moduleName)` Checks if a module exists. #### `LoadAsync(string moduleName, CancellationToken cancellationToken = default)` Asynchronously loads a Lua module. ### Usage ```csharp state.ModuleLoader = new AddressablesModuleLoader(); // Loads addressable asset with label or address 'lua/helpers' var results = await state.DoStringAsync("return require 'lua.helpers'"); ``` ### Setup 1. Create Lua assets with Addressables. 2. Assign addresses/labels matching module names. 3. Load via require. ``` -------------------------------- ### Create and Access Lua Tables in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Demonstrates creating Lua tables from strings and C# arrays, and accessing their elements using C# syntax. Lua arrays are 1-indexed. ```csharp var results = await state.DoStringAsync("return { a = 1, b = 2, c = 3 }"); var table1 = results[0].Read(); // 1 Console.WriteLine(table1["a"]); results = await state.DoStringAsync("return { 1, 2, 3 }"); var table2 = results[0].Read(); // 1 (Note: Lua arrays are 1-indexed) Console.WriteLine(table2[1]); ``` -------------------------------- ### Execute Lua Code from String or File Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Shows how to execute Lua code either directly from a C# string or by loading it from a .lua file. It also illustrates how to access specific return values. ```csharp // From string var results = await state.DoStringAsync("return 'hello'"); // From file var results = await state.DoFileAsync("script.lua"); // Get specific return value var firstResult = results[0].Read(); ``` -------------------------------- ### Set a Custom Lua Module Loader Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Implements and sets a custom `ILuaModuleLoader` to control how Lua modules are loaded. This example uses a dictionary to store module content. ```csharp public class SimpleModuleLoader : ILuaModuleLoader { private Dictionary modules = new(); public bool Exists(string moduleName) => modules.ContainsKey(moduleName); public ValueTask LoadAsync( string moduleName, CancellationToken ct = default ) { if (modules.TryGetValue(moduleName, out var content)) return new(new LuaModule(moduleName, content)); throw new InvalidOperationException($"Module {moduleName} not found"); } } var loader = new SimpleModuleLoader(); loader.modules["helpers"] = "return { utility = function() end }"; state.ModuleLoader = loader; ``` -------------------------------- ### Catch LuaParseException Example Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/06-exceptions.md Demonstrates how to catch a LuaParseException when executing Lua code that contains syntax errors. It prints the chunk name and line number where the error occurred. ```csharp try { await state.DoStringAsync("if true print('missing end')"); } catch (LuaParseException ex) { Console.WriteLine($"Parse error at {ex.ChunkName}:{ex.Position.Line}"); Console.WriteLine(ex.Message); // Output: Parse error at [string "..."]:1 // ... expected near 'print' } ``` -------------------------------- ### LuaValue Equality and Hashing Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/02-luavalue.md Illustrates how LuaValue instances are compared for equality, considering both value and reference equality for different types. ```csharp var a = new LuaValue(10); var b = new LuaValue(10); var c = a; // a == b is true (both are 10) // a == c is true (same reference for tables/functions) ``` -------------------------------- ### Run Simple Tests Source: https://github.com/nuskey8/lua-csharp/blob/main/CLAUDE.md Execute simple tests by running the specified project. Ensure your Lua script is written to 'sandbox/ConsoleApp1/test.lua'. ```bash dotnet run --project sandbox/ConsoleApp1/ConsoleApp1.csproj ``` -------------------------------- ### Run Tests with Detailed Output Source: https://github.com/nuskey8/lua-csharp/blob/main/CLAUDE.md Execute all unit tests and display detailed output using the console logger. ```bash dotnet test --logger "console;verbosity=detailed" ``` -------------------------------- ### Get LuaTable Array Length Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/03-luatable.md Retrieves the logical length of the array component of a LuaTable. This count stops at the first nil value encountered, even if subsequent elements are present. ```csharp public int ArrayLength { get; } ``` ```csharp var table = new LuaTable(); table[1] = 10; table[2] = 20; Console.WriteLine(table.ArrayLength); // 2 table[3] = null; // Create nil gap table[4] = 40; Console.WriteLine(table.ArrayLength); // 2 (stops at first nil) ``` -------------------------------- ### Create LuaState with Custom Platform Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Creates a new Lua state using a custom LuaPlatform configuration. This allows for fine-grained control over file system, I/O, and OS operations. ```csharp var platform = new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new SystemOsEnvironment(), StandardIO: new ConsoleStandardIO(), TimeProvider: TimeProvider.System ); var state = LuaState.Create(platform); ``` -------------------------------- ### Enable Debugging Hooks Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/00-index.md Enable debug hooks to trace Lua script execution. This example sets up a line hook to print the currently executing function's name. ```csharp var hook = new LuaFunction(async (ctx, ct) => { var frame = ctx.State.GetCurrentFrame(); Debug.WriteLine($"Executing {frame.Function.Name}"); return ctx.Return(); }); state.SetHook(hook, "l", 0); // Line hook ``` -------------------------------- ### Instance Member Generation in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/05-luaobject-codegen.md Illustrates exposing an instance C# method, which is called using Lua's ':' syntax. ```csharp [LuaMember("normalized")] public Vector3 Normalized() { // 'this' is implicit } ``` ```lua local v1 = Vector3.create(1, 2, 3) local v2 = v1:normalized() -- Called with : syntax ``` -------------------------------- ### UnityApplicationOsEnvironment Implementation Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/09-unity-integration.md Provides an OS environment implementation for Unity applications, handling environment variables, application exit, and current time. ```csharp public class UnityApplicationOsEnvironment : ILuaOsEnvironment { // Stores environment variables in a dictionary public string? GetEnvironmentVariable(string name) public void SetEnvironmentVariable(string name, string? value) public void Exit(int code) // Calls Application.Quit() public DateTime GetCurrentTime() } ``` ```csharp var platform = new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new UnityApplicationOsEnvironment(), StandardIO: new UnityStandardIO(), TimeProvider: TimeProvider.System ); var state = LuaState.Create(platform); ``` -------------------------------- ### Implement Lua Metamethods in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Define Lua metamethods for custom C# objects using the [LuaMetamethod] attribute. This example adds arithmetic and string conversion metamethods to the LuaVector3 class. ```cs [LuaObject] public partial class LuaVector3 { // The previous implementation is omitted [LuaMetamethod(LuaObjectMetamethod.Add)] public static LuaVector3 Add(LuaVector3 a, LuaVector3 b) { return new LuaVector3() { vector = a.vector + b.vector }; } [LuaMetamethod(LuaObjectMetamethod.Sub)] public static LuaVector3 Sub(LuaVector3 a, LuaVector3 b) { return new LuaVector3() { vector = a.vector - b.vector }; } [LuaMetamethod(LuaObjectMetamethod.ToString)] public override string ToString() { return vector.ToString(); } } ``` -------------------------------- ### LuaState.DoFileAsync() Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/01-luastate.md Loads and executes a Lua script from a specified file path. ```APIDOC ## LuaState.DoFileAsync() ### Description Loads and executes a Lua file. ### Method `public static ValueTask DoFileAsync(LuaState state, string path, CancellationToken cancellationToken = default)` ### Parameters #### Path Parameters - **state** (LuaState) - Required - The Lua state - **path** (string) - Required - File path to load - **cancellationToken** (CancellationToken) - Optional - Cancellation token ### Returns `ValueTask` — array of return values ### Throws - `IOException` — if file cannot be read - `LuaCompileException` — on parsing error - `LuaRuntimeException` — on script runtime error ### Example ```csharp var results = await state.DoFileAsync("script.lua"); foreach (var result in results) { Console.WriteLine(result); } ``` ``` -------------------------------- ### Create LuaState with Unity Platform Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/12-quick-reference.md Use this to create a LuaState instance specifically for the Unity environment, including Unity-specific components and a ResourcesModuleLoader. ```csharp using Lua.Unity; var platform = new LuaPlatform( FileSystem: new FileSystem(), OsEnvironment: new UnityApplicationOsEnvironment(), StandardIO: new UnityStandardIO(), TimeProvider: TimeProvider.System ); var state = LuaState.Create(platform); state.ModuleLoader = new ResourcesModuleLoader(); ``` -------------------------------- ### Open All Standard Libraries in Lua-CSharp Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/08-standard-libraries.md Use this method to load all standard Lua libraries into the Lua state. Ensure the `Lua.Standard` namespace is imported. ```csharp var state = LuaState.Create(); state.OpenStandardLibraries(); // Opens all libraries ``` -------------------------------- ### Layered Exception Handling in C# Source: https://github.com/nuskey8/lua-csharp/blob/main/_autodocs/11-best-practices.md Implement layered exception handling to catch errors at different levels based on responsibility. This example shows framework integration catching specific Lua exceptions. ```csharp public class ScriptService { private readonly LuaState state; private readonly ILogger logger; // Level 1: Framework integration public async ValueTask ExecuteUserScript(string code) { try { return await ExecuteInternal(code); } catch (LuaParseException ex) { logger.LogError(ex, "Invalid Lua syntax"); return ScriptResult.Failure($"Syntax error at line {ex.Position.Line}"); } catch (LuaCompileException ex) { logger.LogError(ex, "Script compilation failed"); return ScriptResult.Failure($"Compilation error: {ex.MainMessage}"); } catch (LuaRuntimeException ex) { logger.LogError(ex, "Script runtime error"); return ScriptResult.Failure($"Runtime error: {ex.ErrorObject}"); } catch (OperationCanceledException) { logger.LogWarning("Script execution cancelled"); return ScriptResult.Cancelled(); } } // Level 2: Core execution private async ValueTask ExecuteInternal(string code) { var results = await state.DoStringAsync(code); return ScriptResult.Success(results); } } public record ScriptResult { public bool IsSuccess { get; init; } public string? ErrorMessage { get; init; } public LuaValue[] Results { get; init; } public static ScriptResult Success(LuaValue[] results) => new() { IsSuccess = true, Results = results }; public static ScriptResult Failure(string message) => new() { IsSuccess = false, ErrorMessage = message }; public static ScriptResult Cancelled() => new() { IsSuccess = false, ErrorMessage = "Execution was cancelled" }; } ``` -------------------------------- ### Use Custom C# Objects in Lua Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Interact with C# custom objects from Lua scripts. This example demonstrates creating and manipulating Vector3 objects, including calling methods like 'normalized'. ```lua -- vector3_sample.lua local v1 = Vector3.create(1, 2, 3) -- 1 2 3 print(v1.x, v1.y, v1.z) local v2 = v1:normalized() -- 0.26726123690605164 0.5345224738121033 0.8017836809158325 print(v2.x, v2.y, v2.z) ``` -------------------------------- ### Loading and Executing Lua Assets in Unity Source: https://github.com/nuskey8/lua-csharp/blob/main/README.md Load a LuaAsset from Resources and execute its string content asynchronously. Ensure the LuaAsset is placed in a Resources folder. ```csharp var asset = Resources.Load("example"); await state.DoStringAsync(asset.Text, ct); ```