Introduction
Lua scripting for Unity, .NET and Mono, with calls in both directions between
Lua and C#. xLua-NG is an independent, community-maintained fork of
Tencent/xLua; it is not affiliated with or
endorsed by Tencent. It keeps the XLua namespace and the bridge API, and
modernises the rest: current Lua versions, a Roslyn source generator instead
of the code generation menu, presets that leave out what a project does not
use, a sandbox for untrusted scripts, and regression tests for its changes.
Work in progress. APIs, presets and native exports still change, and nothing is published: no release, no prebuilt plugins, no UPM package in a registry. Build from source to try it. Open work is in ROADMAP.md.
What is different from xLua
Section titled “What is different from xLua”- Lua 5.5.1 by default, with Lua 5.4.9, 5.3.6 and LuaJIT 2.1 as build options (upstream ships Lua 5.3.5). 64-bit integers stay lossless on Lua 5.3 and later.
- Source-generated bindings. A Roslyn source generator writes the
bindings while Unity compiles the scripts; there is no generation step and
no generated folder. Upstream’s XLua > Generate Code menu and its
templates are removed.
GEN_CODE_MINIMIZEselects the generator’s smaller wrappers. See Configuration. - Configuration with attributes, on types or at assembly level for types you do not own. XLua > Migrate Configuration to Attributes converts upstream’s static configuration lists once (Converting configuration lists).
- Presets (
legacy,minimal,core) and a build option for every optional part, so a project pays in size only for what it uses (below). LuaScript(preview): a separate API for scripts you do not trust, such as mods or downloaded rules. It has memory, instruction and time limits and no bridge to C#: scripts reach only the functions you register (LuaScript).- Assembly definitions by default: xLua compiles into
XLua.CoreandXLua, so asmdefs of your own can use it. XLua > Project Layout > Use Assembly-CSharp (no asmdefs) goes back to upstream’s layout. - A UPM package built from the repository (preview, below).
- Bridge fixes and opt-in hardening. Upstream bugs fixed in this fork are listed with their issues in UPSTREAM.md, and every change in behaviour is in MIGRATING.md. The Editor and Development Builds check that a userdata is one of xLua’s before using it as a C# object (bridge checks), and scripting defines add more, such as locked metatables (opt-in bridge hardening).
- Tests. Managed bridge suites in every binding mode, native checks, sanitizers, fuzzing, Lua’s and LuaJIT’s own test suites, a Unity editor suite and player smoke tests (Test/README.md).
Kept from upstream: calling C# from Lua and Lua from C# (delegates,
interfaces, LuaTable, LuaFunction), hotfix of instrumented C# methods
(Hotfix guide), passing configured structs
without allocations (GC optimization), and running
in the Editor without generated bindings through reflection and
Reflection.Emit.
Supported versions and platforms
Section titled “Supported versions and platforms”| Supported | Notes | |
|---|---|---|
| Lua | 5.5.1 (default), 5.4.9, 5.3.6, LuaJIT 2.1 | LuaScript needs Lua 5.4 or 5.5; WebGL builds Lua 5.5.1 only. Which version to use |
| Unity | 2021.3 LTS to 6000.6 | Editor tests run locally on macOS arm64; the hosted matrix (unity-matrix.yml) has not run yet. Details in Test/README.md and ROADMAP.md |
| Scripting backends | IL2CPP and Mono | IL2CPP players need the source generator for [CSharpCallLua] delegates and interfaces |
| Outside Unity | .NET and Mono applications | General/README.md |
Each platform needs a native library built from this repository (build/README.md). What has run so far:
| Platform | Native library | Run in a Unity player |
|---|---|---|
| Android | armeabi-v7a, arm64-v8a, x86, x86_64; API 23 and later | IL2CPP players on an emulator (16 KB pages) and on a phone |
| iOS | arm64 device and simulator libraries; iOS 15.0 and later | IL2CPP players in the iOS Simulator; not yet on an iPhone |
| macOS | universal bundle and arm64 dylib; macOS 12.0 and later | Editor, and Mono players (arm64 and universal) |
| Windows | x64, x86, ARM64 | not yet; the x64 and ARM64 libraries pass the native checks in CI |
| Linux | x64 | not yet; the managed and native test suites run on Linux |
| WebGL | compiled by Unity from the sources, Lua 5.5.1 | a Unity 6000.6 player in headless Chrome |
| OpenHarmony | built with the OpenHarmony SDK | not yet; a static smoke test runs on x86_64 and arm64-v8a |
The UWP and Nintendo Switch build scripts come from upstream and are not verified by this fork.
Presets
Section titled “Presets”A preset is a set of C# scripting defines and native build options (presets.md, sizes in SIZE.md).
| Preset | Select it with | What you get |
|---|---|---|
legacy (default) |
nothing | Upstream’s feature set and behaviour |
minimal |
the define XLUA_PRESET_MINIMAL and a native library built with XLUA_PRESET=minimal |
The bridge without rarely used parts (StreamingAssets loader, SignatureLoader, template, LuaSocket, io, most of os, C module loading) and with the bridge hardening checks on |
core |
the define XLUA_CORE_ONLY and a native library built with XLUA_PRESET=core |
LuaScript only, without the C# bridge (preview) |
How to switch, and what each define changes, is in MIGRATING.md.
Quick start
Section titled “Quick start”1. Build the native library
Section titled “1. Build the native library”The repository ships no binaries. Build the library for each target with the
scripts in build/ (the tools are pinned in mise.toml; see
build/README.md for Android, iOS, Windows, Linux and the
build options). For the Editor on a Mac:
XLUA_BUILD_ROOT=../xlua-build build/make_osx_lua55.sh # Plugins/xlua.bundleXLUA_BUILD_ROOT=../xlua-build build/make_osx_silicon_lua55.sh # Plugins/arm64/libxlua.dylibThese write plugin_lua55/Plugins/... under XLUA_BUILD_ROOT. A
native-build.yml run also uploads the libraries as artifacts. WebGL has no
prebuilt library: Unity compiles the C sources into the player
(Unity WebGL).
2. Add xLua to a Unity project
Section titled “2. Add xLua to a Unity project”Copy Assets/XLua (at least Core and Src) and Assets/Plugins from this
repository into your project’s Assets folder, then copy the built
Plugins folder over Assets/Plugins. The committed .meta files carry
the plugins’ import settings. The examples and the
tutorial are learning material; leave them out of a
production project.
Scripts without an asmdef see xLua as before. An asmdef of yours that uses
xLua adds XLua and XLua.Core to its references; see
MIGRATING.md
for the layout and the way back to Assembly-CSharp.
3. Install the source generator
Section titled “3. Install the source generator”Build it with the .NET SDK pinned in mise.toml and install it
next to the XLua asmdef:
python3 Tools/build_source_generator.py --output ../xlua-sourcegen \ --install <project>/Assets/XLua/Src/AnalyzersThen configure the types Lua uses with attributes
(Configuration). Without the generator,
xLua binds every type through reflection, and an IL2CPP player cannot turn
Lua functions into [CSharpCallLua] delegates.
As a UPM package (preview)
Section titled “As a UPM package (preview)”The package com.xlua-ng.xlua (Unity 2021.3 or later) holds the C#, the
source generator, the Lua 5.5.1 native plugins of Android, iOS, macOS,
Windows and Linux, the WebGL sources, the guides, and the examples and
tutorial as samples. No version has been released yet; once one is, install
it one of these ways:
-
Tarball: download
com.xlua-ng.xlua-<version>.tgzfrom the releases (check it againstSHA256SUMS.txt), then in Window > Package Manager press “+”, choose “Add package from tarball…” and pick the file. Keep the file in the project, for example inPackages/, since the manifest points at it. -
Git URL: “+” > “Add package from git URL…” with
https://github.com/emindeniz99/xlua-ng.git#upm/v<version>for one version, or#upmfor the newest. Theupmbranch is created with the first release that publishes it (release.md). -
From source: build the plugins (step 1) and the package yourself:
Terminal window python3 Tools/make_upm_package.py --output ../xlua-package \--plugins ../xlua-build/plugin_lua55 --source-gen ../xlua-sourcegen \--tarball ../com.xlua-ng.xlua-0.0.1-dev.tgzand add the
.tgzwith “Add package from tarball…”, or the folder’spackage.jsonwith “Add package from disk…”. The version comes fromVERSION.
Remove a copied Assets/XLua and the xLua libraries in Assets/Plugins
first: the package has the same assemblies and GUIDs as the Assets layout,
and two copies conflict (MIGRATING.md).
Projects that use hotfix also need the injector in their Tools/ folder:
extract xlua-tools_<tag>.tgz from the same release into the project folder.
The samples import into Assets/Samples/xLua-NG/<version>/ and use uGUI.
Run Lua from C#
Section titled “Run Lua from C#”using UnityEngine;using XLua;
[CSharpCallLua]public delegate double LuaMax(double a, double b);
public class HelloLua : MonoBehaviour{ LuaEnv luaEnv; LuaMax max;
void Start() { luaEnv = new LuaEnv(); luaEnv.DoString("CS.UnityEngine.Debug.Log('hello from Lua')");
max = luaEnv.Global.GetInPath<LuaMax>("math.max"); Debug.Log(max(32, 12)); // 32 }
void OnDestroy() { max = null; // release delegates bound to Lua before disposing luaEnv.Dispose(); }}Each LuaEnv owns a Lua state. Keep one for the game’s lifetime rather than
creating one per call. A LuaEnv is not a sandbox: its scripts can reach C#
(Security and sandboxing). The
tutorial continues from here.
Run a script you do not trust
Section titled “Run a script you do not trust”LuaScript needs the scripting define XLUA_LUASCRIPT and a native library
built with XLUA_LUASCRIPT=ON, or the core preset for a project without the
C# bridge (setting up):
using System;using XLua;
public static class RewardRules{ public static long Reward() { using (var lua = new LuaScript(new LuaOptions { MemoryLimit = 4 << 20, // bytes InstructionLimit = 10000000, // VM instructions per call TimeLimit = TimeSpan.FromMilliseconds(50), // wall clock per call })) { lua.Register<long, long>("playerLevel", id => 12); // the only C# the script can reach lua.Load("function reward(id) return playerLevel(id) * 10 end", "rules"); return lua.Call<long>("reward", 7); // 120 } }}A script that exceeds a limit throws a LuaLimitException; a script error
throws a LuaException with the Lua traceback.
Migrating from Tencent/xLua
Section titled “Migrating from Tencent/xLua”MIGRATING.md lists every behaviour change against upstream and what to do once: install the source generator, convert the configuration lists, delete the output of Generate Code, and check the asmdef references. UPSTREAM.md tracks the upstream issues and their status here.
Documentation
Section titled “Documentation”The guides are on the documentation website, built from the Markdown in this repository (index).
- Tutorial, Configuration, API reference, FAQ
- Loading Lua sources: Resources, StreamingAssets, downloads, AssetBundles, Addressables
- LuaScript, Security and sandboxing, Hotfix guide, Examples
- Native builds, test suites, CI without a release
- Decisions in docs/design, research behind them in docs/research, measurements in SIZE.md
English is the only maintained documentation language. Tencent’s original documentation and the Chinese sources before the cleanup remain available for reference.
Contributing
Section titled “Contributing”Read CONTRIBUTING.md (and AGENTS.md for the design rules, commit format and test requirements). Contributions from developers of all nationalities are welcome; English is preferred for issues and pull requests. Report problems in the issue tracker with the Unity version, Lua version, preset, platform, scripting backend and a reproducer. For upstream community information, see Tencent/xLua; this fork is developed independently.
Security
Section titled “Security”Report vulnerabilities privately, as described in SECURITY.md.
License and attribution
Section titled “License and attribution”xLua-NG is released under the MIT license and derives from Tencent/xLua. The original Tencent copyright and MIT license notices are preserved in LICENSE.TXT. Embedded runtimes and native dependencies keep their own license notices (DEPENDENCIES.md).
The logo used in the documentation (Assets/XLua/Doc/logo.png and the website)
is Tencent’s original xLua artwork, kept from the upstream project.
