macros
in your script. This documentation will show you everything about the LPH_NO_VIRTUALIZE
macro
Why does obfuscation affect performance?
Because Luraph™️ is a VM based obfuscator that generates its own instructions that are interpreted by Luraph, which, in turn, is interpreted by the Lua interpreter. So the number of instruction cycles increases exponentially.How obfuscation works
How obfuscation works
Normally, your script gets compiled into a set of Lua instructions. See the example below:
As you can see, your simple “print” statement gets compiled into 4 instructions. Each instruction is a cycle, so it will take 4 cycles to execute your code.When you obfuscate your script, the main goal is to make the original code unreadable. Luraph does this by generating its custom instruction set that can be understood by Luraph VM only.See the example below:
Notice how your simple print statement turned into 40 instructions, which will take 40 cycles to execute. Also keep in mind that Luraph does a lot of things to obfuscate the code flow, which will ultimately lead to even more instructions.

How Lua code is compiled to bytecode

How Luraph obfuscates Lua code
RenderStepped example
RenderStepped example

Example of a RenderStepped connection
CalculateParameters
) used in this loop, which automatically means that function will be executed as well, which will lead to even more and more instructions to run.__index
:
__index example
__index example

Example of a metamethod hook
__index
runs quite often. Example:game.Workspace
,game.Players...
- etc…
__index
function and run the code above. This will be extremely resource intensive and heavy, considering that it is probably called thousands of times per second.And on top of that, if you obfuscate this part, you will end up with more than a million instructions to run every second, which will crash your game.How to deal with this problem?
Do not wrap your entire script in LPH_NO_VIRTUALIZE as it defeats the purpose of virtualization (obfuscation). Only use this macro if a function runs more than 30 times per second.
loadstring()
, or LPH_NO_VIRTUALIZE
.
It is recommended to use LPH_NO_VIRTUALIZE
instead of loadstring while excluding chunks from obfuscation, because it is generally harder to view the code when you’re using LPH_NO_VIRTUALIZE
.
How to use LPH_NO_VIRTUALIZE
?
LPH_NO_VIRTUALIZE
takes one constant argument which must be a function, and returns a function that can be called.
It is important to add this on top of your script, so you won’t have issues while running the original code.
LPH_NO_VIRTUALIZE
:
Good usage
Good usage
Bad usage
Bad usage
Where to use LPH_NO_VIRTUALIZE
?
RenderStepped
connectionsHeartbeat
connections__index
metamethod hooks__namecall
metamethod hooks (optional)while true
loops with no delay- GC scan loops
function
s, if they are called by one of those above