Limitations
Supported Lua Versions
Luraph is guaranteed to work on the latest patches of major Lua versions. Support for outdated Lua patches is not guaranteed. For example, every Luraph update is tested thoroughly on Lua 5.3.6, but Lua 5.3.2 may contain incompatibilities. Certain patches of Lua that are not the latest version may contain bugs that break Luraph, and it is generally best to be on the latest available version. Luraph does not support Lua 5.0.3 or earlier.
Luraph officially supports the latest releases of the following Lua versions:
- Lua 5.1 (5.1.5)
- Lua 5.2 (5.2.4)
- Lua 5.3 (5.3.6)
- Lua 5.4 (5.4.8)
- Luau (0.709)
- LuaJIT (2.1)
Luraph also supports popular platforms such as Roblox, FiveM, CS:GO, and World of Warcraft. Not all supported versions and platforms are listed. New versions are actively being added and suggestions are welcome.
Incompatibilities
debug Library Functions
The function of various debug library functions (including but not limited to debug.getinfo, debug.getlocal, debug.getupvalue, debug.gethook, and debug.traceback) may exhibit undefined behavior when used with level arguments or on functions created by Luraph. Because Luraph virtualizes your script, these functions will return internal VM information/constructs and exhibit incorrect behavior on obfuscated scripts.
Debug Information & Error Messages
Luraph strips all unnecessary debug information from your script, such as local, upvalue, and function names. This means debug information cannot be recovered, will be excluded from error messages, and cannot be accessed from debug library functions.
By default, Luraph's custom error handling provides line information with all errors that occur within obfuscated scripts. The formatting of these errors is not guaranteed to align with Lua's error messages, which may cause issues with any code that relies on exact error messages. Additionally, accurate line information is never provided with errors inside of functions wrapped in LPH_NO_VIRTUALIZE.
Recursion Depth & Stack Levels
This limitation is not present when the Disable Line Information setting is enabled.
By default, Luraph provides custom error-handling functions, which makes each Luraph function utilize more than one level in the call stack. This will cause a discrepancy between expected stack levels within obfuscated scripts, impact the functionality of certain recursive functions, and break functions that use a level on the call stack (such as getfenv and setfenv). For some functions, this behavior can be mitigated by using the function object instead of the level on the call stack (setfenv(function, environment) instead of setfenv(1, environment)). Using the Disable Line Information setting will remove the custom error handling functions and the limitations iterated in this paragraph.
Mid-Execution Environment Change
This limitation is not present when the Hardcode Globals setting is enabled.
On platforms with setfenv, the environment reference is cached at the start of function execution for performance reasons. Any changes to the environment reference (using setfenv) will only be recognized in future calls of that function. This behavior only applies to changes in the actual environment reference and does not apply to the modification of globals within the environment.
Upvalue Count
This limitation is not present on functions wrapped with LPH_NO_VIRTUALIZE or LPH_NO_UPVALUES.
Luraph functions are much larger than unobfuscated functions and will have higher upvalue counts than their corresponding unobfuscated versions. This may cause issues with certain functions that rely on functions having a small or specific upvalue count. On environments with getfenv/setfenv, the LPH_NO_UPVALUES macro can be used to wrap a function to have no upvalues. This macro is not available on platforms that use _ENV. LPH_NO_VIRTUALIZE can also be used to mitigate this issue on any version, but at the cost of not virtualizing the function that is being passed through.
string.dump
Because Luraph defines upvalues outside of the functions returned from Luraph, you will be unable to use loadstring(string.dump(x)), where x is a Luraph function. Additionally, the bytecode of a dumped Luraph function will never be the same as its corresponding unobfuscated version.
Iteration Variables
This limitation is not present on non-Luau versions.
To support Luau's __iter meta-method, Luraph needed to change how iterators are handled. This required us to limit the number of variables a for-loop statement can have (for a, b, c, d, e, ...) to 10. This limit is technically artificial and can be increased if a realistic need is presented. To request an increase of this limit, please contact support.
Table Constructor Length
This incompatibility is only present if nil values are used in a constructor, or the length of the table cannot be inferred at compile time (e.g. { 1, 1, unpack(...) }). Luraph's output is undefined and depends on the Lua version.
Due to inconsistent behavior across Lua versions, getting the length of tables with nil array elements is undefined behavior.
Example:
#{ 1, 2, 3, nil, 4 }Luraph: 5Lua 5.4: 5LuaJIT: 3
Table Constructor Order
This incompatibility is only present if duplicate keys are used in a table constructor.
Due to inconsistent behavior across various Lua versions, the assignment order of values in mixed tables (tables that have both array and dictionary elements) may differ. Luraph assigns elements in the exact order they are written (which differs from certain Lua 5.x versions that assign array elements first in some cases).
Example:
{ 1, 2, 3, [3] = 4 }Luraph: { 1, 2, 4 }Lua 5.4: { 1, 2, 3 }Luau: { 1, 2, 4 }
50MB File Size Limitation
To avoid abuse of our API, we artificially limit files to 50 MB in size. This should be enough for the majority of use cases, but we are open to increasing these limits if a realistic need is presented.
Closure Caching Optimization
In Luau and Lua 5.2/5.3, the VM may reuse a previously created function (when all upvalues captured are the same and are defined at the highest level) for efficiency. This behavior is never present in Luraph.
64-Bit Assumption
This limitation is not present on specific versions catered to 32-bit Lua environments.
Luraph currently assumes that platforms that support integers (ex: Lua 5.3 & 5.4) use 64-bit integers; however, certain Target Versions provide support for lesser integer sizes (e.g. Warcraft 3). If your desired platform utilizes integers with lesser integer sizes, please contact support so that proper support for your platform can be enabled.
hookfunction Errors
This limitation is not present on functions wrapped with LPH_NO_VIRTUALIZE or LPH_NO_UPVALUES.
Some Luau-based environments implement the custom function hookfunction. Due to hookfunction's often undefined (and commonly incorrectly implemented) behavior, hookfunction is known to have many issues with obfuscation. Due to various implementations of this function, there can be a number of bugs that occur. Upvalue overflow is the most common, which can be fixed using LPH_NO_UPVALUES or LPH_NO_VIRTUALIZE.
No __namecall Invocation
This limitation is not present on functions wrapped with LPH_NO_VIRTUALIZE.
Due to the nature of Luraph's VM, the __namecall method is not invoked by : method calls and will instead invoke __index. This can be an issue for code that uses : calls inside of __index method functions/hooks which may cause infinite recursion. To avoid this issue, ensure method calls inside of __index implementations will not cause infinite recursion. __namecall will be properly invoked inside of functions wrapped with LPH_NO_VIRTUALIZE.
Garbage Collection Order
For performance reasons, Luraph does not consistently clear certain values from the stack by default. This means that forcing a GC cycle using collectgarbage and expecting certain out-of-scope values to be collected may not happen. This behavior can be slightly mitigated using Enable GC Fixes, but there are still unfixable limitations and this option is not recommended due to its extreme hit to performance. If you utilize behavior that relies on forcing certain values to be collected and are looking for a performant solution, contact support.
<close> Attribute
This limitation is only present on Lua 5.4.
For performance and complexity reasons, Luraph does not support the <close> attribute on variables. Attempting to use it will throw a compiler error. Additionally, the closing value in generic for loops will never be closed properly.
FiveM's defer Statement
This limitation is only present on FiveM when it is compiled with GRIT_POWER_DEFER.
For reasons similar to the lack of support for <close>, FiveM's defer statement is not supported.