Jul 5, 2026
Recently I tried integrating UnLua into a UE 5.8 project. The difficult part was not really “how to use UnLua”, but rather how to make the older UnLua source compile cleanly under UE 5.8. This note records the whole setup process: why I wanted to use UnLua, what changed in UE 5.8, and what a workable configuration looks like in practice.
This article is based on Tencent UnLua:
https://github.com/Tencent/UnLua
It is not an official UE 5.8 release note. It is just a practical compatibility record from one integration attempt.
UnLua connects Lua scripts to Unreal Engine, allowing part of the game logic to be separated from C++ or Blueprints and organized in a scripting layer.
The most direct benefit is iteration speed. C is suitable for core systems, performance-sensitive code, low-level frameworks, and engine extensions. But if every gameplay flow, UI behavior, quest script, and trigger is written in C, even tiny changes can involve compilation, hot reload, or restarting the editor. Lua files are plain text, easy to edit, easy to organize, and much lighter for frequently changing logic.
Another important value of UnLua is that it can work with UE’s object system. Lua code can access reflection objects such as UObject, UClass, UFunction, and UProperty, and it can bind to Blueprint classes. This makes it possible to keep a fairly clear division of responsibility:
If a project later needs hot update support, Lua is also a natural candidate. Hot update is still a complete system involving resource management, versioning, download verification, and fallback logic, but script-level logic is much easier to load and replace at runtime than C++ modules.
There is also a very practical point now: Lua files are text, which makes them friendlier to agents and AI-assisted development. Compared with directly modifying Blueprint assets, generating, reviewing, and rolling back Lua logic is much lighter.
The official UnLua source is not directly prepared for UE 5.8. UE 5.8 changes parts of the build toolchain and engine APIs. If an older plugin source is copied into a project as-is, a common result is this dialog when opening the project:
Missing Modules: UnLua, UnLuaEditor
This does not mean the project itself is broken. It means the .uproject has enabled UnLua, but UE cannot find plugin DLLs that match the current engine version. Usually the plugin has not been compiled yet, or it was compiled for another UE version.
During this UE 5.8 adaptation, the main issues I ran into were:
UE 5.8 uses a newer build toolchain.
In my local test, UE 5.8 used its bundled .NET 10 SDK, the VS2022 MSVC toolchain, and the Windows SDK. Some helper projects in older UnLua code still assumed older frameworks such as net6.0, older enums, or older APIs.
The UHT plugin API changed.
UnLua’s default parameter collector depends on the UHT export flow. In UE 5.8, it needs to iterate modules and packages through Session.Modules; the old style does not compile directly.
UE object field lists use TObjectPtr more broadly.
In UE 5.8, fields such as UStruct::Children and UField::Next are already TObjectPtr<UField>. Old code that manipulates them as UField** will hit type mismatches.
Delegate APIs need adjustment.
Multicast delegate calls need to adapt to the newer ProcessDelegate<UObject>(Params) style.
Metadata APIs changed.
UMetaData::CopyMetadata should be replaced with FMetaData::CopyMetadata, with the corresponding include added.
Format string checks are stricter.
FString::Printf now prefers compile-time-checkable literal format strings. Passing a variable as the format can fail under UE 5.8.
Lua internal names may conflict with UE types.
Lua’s internal TString can collide with UE-side types or aliases. When including Lua internal headers, the name has to be isolated carefully.
The final project layout I used was roughly:
YourProject/
Config/
DefaultUnLuaEditor.ini
Content/
Script/
Main.lua
Plugins/
UnLua/
UnLua.uplugin
Source/
Content/
If the project is a pure Blueprint project, create an empty C++ class from the UE editor first. This generates the Source, .Target.cs, .Build.cs, and other build-related files. UnLua is a C++ plugin, so it ultimately has to be compiled through Unreal Build Tool.
Plugins/UnLua is the plugin itself. Config/DefaultUnLuaEditor.ini configures editor-side UnLua behavior and the startup module. Content/Script/Main.lua is the default Lua entry point.
If the project already has an older Plugins/UnLua, back it up before replacing it. Do not treat old Binaries or Intermediate directories as reliable outputs. UE plugins should be compiled again on the current machine and against the current engine version.
Open the project .uproject file and add UnLua to the Plugins array:
{
"Name": "UnLua",
"Enabled": true
}
If the project already has other plugins, do not overwrite the whole Plugins array. Only append this item.
Then add Config/DefaultUnLuaEditor.ini:
[/Script/UnLuaEditor.UnLuaEditorSettings]
StartupModuleName=Main
This tells UnLua to load Content/Script/Main.lua during startup.
Create the Lua entry file:
Content/Script/Main.lua
For the first test, a minimal file is enough:
print("UnLua Main.lua loaded")
After the plugin source and project configuration are ready, compile the editor target with UE 5.8’s Build.bat.
The command shape is:
"C:\Program Files\Epic Games\UE_5.8\Engine\Build\BatchFiles\Build.bat" YourProjectEditor Win64 Development "C:\YourProject\YourProject.uproject" -waitmutex
Replace YourProjectEditor with your project editor target name, and replace the .uproject path with your actual project path.
If compilation succeeds, the plugin binaries should appear under something like:
Plugins/UnLua/Binaries/Win64/UnrealEditor-UnLua.dll
Plugins/UnLua/Binaries/Win64/UnrealEditor-UnLuaEditor.dll
Once these DLLs exist for the current engine version, opening the project should no longer show:
Missing Modules: UnLua, UnLuaEditor
For UE 5.8, the places most likely to break are the build helper projects, UHT integration, metadata copying, delegate calls, and linked field traversal.
For helper projects, update old framework targets and old compiler enum checks. For example, do not depend on WindowsCompiler.VisualStudio2019 style checks if the newer build environment exposes the compiler differently. Also remove unnecessary legacy package references such as Microsoft.CSharp when targeting the bundled newer .NET SDK.
For UHT-related code, follow the newer export session structure. If old code assumes a direct package list, rewrite it around the current Session.Modules traversal model.
For metadata copying, replace the old API with:
FMetaData::CopyMetadata(...)
and add the include required by the newer engine headers.
For multicast delegates, prefer the newer call shape:
ProcessDelegate<UObject>(Params)
For UStruct::Children and UField::Next, remember that the chain is now based on TObjectPtr<UField> rather than raw UField** manipulation.
For format strings, do not pass a runtime variable as the FString::Printf format. Use literal TEXT("...") or TEXT(R"(... )") format strings whenever possible.
If the project still reports Missing Modules, check:
Plugins/UnLua exists..uproject has enabled UnLua.UnrealEditor-UnLua.dll and UnrealEditor-UnLuaEditor.dll were generated.If Live Coding locks the DLLs, close the UE editor and Live Coding Console completely, then run Build.bat again.
If the project is pure Blueprint-only, add an empty C++ class first so that Unreal Build Tool has a complete project build structure to work with.
Usually, no.
It is better not to commit:
Plugins/UnLua/Binaries/
Plugins/UnLua/Intermediate/
These are build outputs tied to the current machine and engine version. Commit the source and configuration instead, and let each machine compile the plugin locally.
A typical .gitignore can include:
Binaries/
Intermediate/
Saved/
DerivedDataCache/
*.pdb
*.dll
*.modules
*.target
To configure UnLua in UE 5.8, the core work is:
First, use a UnLua source tree that has been adapted for UE 5.8. Older code will likely fail around UBT/UHT, delegates, TObjectPtr, metadata APIs, or stricter format string checks.
Second, integrate the plugin into the project: copy it to Plugins/UnLua, enable it in .uproject, add DefaultUnLuaEditor.ini, and create Content/Script/Main.lua.
Third, compile YourProjectEditor Win64 Development with UE 5.8’s Build.bat, allowing the current engine version to generate its own UnLua and UnLuaEditor DLLs.
Once the plugin modules compile successfully, the Missing Modules: UnLua, UnLuaEditor dialog should disappear, and the project can start moving gameplay, UI, or level logic into Lua step by step.