Morpheus V1 Documentation

MPS intrinsics

MPS intrinsics are compile-time directives for requesting targeted protection. They look like normal Luau calls in your input, but Morpheus consumes them before scope resolution and removes them from protected output.

You do not define an MPS runtime library. Use these only where extra protection is useful. Normal Morpheus protection still applies everywhere else.
Getting started

Write normal Luau, mark only the sensitive parts.

MPS is designed to be selective. The rest of your script still runs through the normal Morpheus pipeline, so you do not need to wrap every value or function.

example.luaLuau
local endpoint = MPS.ENCSTR_STRONG("internal-name")

local sensitive = MPS.VM(function(input)
    local salt = MPS.ENCNUM(38191)
    return input * salt
end)
Strings

Protect selected string literals.

String directives currently require a literal string. Stronger variants trade more generated work for a less direct representation before normal VM and atom protection.

MPS.ENCSTR("text")Low cost

Splits a literal into randomized pieces before virtualization.

local service = MPS.ENCSTR("InventoryService")
MPS.SPLITSTR("text")Low cost

Uses more aggressive literal fragmentation before the rest of the protection pipeline.

local tag = MPS.SPLITSTR("private-tag")
MPS.ENCSTR_STRONG("text")Medium cost

Converts the literal into byte reconstruction before VM lowering, after which the normal atom and string layers protect the result.

local token = MPS.ENCSTR_STRONG("private-tag")
MPS.ENCSTR_KEYED("text", key)Medium cost

Uses strong byte reconstruction with a generated shape influenced by your literal numeric or string key. The key diversifies compilation and is not a cryptographic secret.

local keyed = MPS.ENCSTR_KEYED(
    "payload-name",
    0x519A
)
AliasesMPS.STRING = MPS.ENCSTRMPS.SECURESTR = MPS.ENCSTR_STRONGMPS.KEYSTR = MPS.ENCSTR_KEYED
Numbers and booleans

Remove obvious literal forms.

MPS.ENCNUM(123)Very low cost

Rewrites a numeric literal into an equivalent masked arithmetic expression.

local id = MPS.ENCNUM(90210)
MPS.ENCNUM_STRONG(123)Low cost

Adds another reversible arithmetic layer before VM lowering.

local limit = MPS.ENCNUM_STRONG(500)
MPS.ENCBOOL(true)Very low cost

Rewrites a literal boolean as an equivalent comparison.

local enabled = MPS.ENCBOOL(true)
AliasesMPS.NUMBER = MPS.ENCNUMMPS.SECURENUM = MPS.ENCNUM_STRONGMPS.BOOL = MPS.ENCBOOL
Expression barriers

Break direct data flow without changing evaluation.

These directives preserve single evaluation of the expression.

MPS.OPAQUE(expr)

Forces the value through an extra table and dataflow boundary before normal shatter and VM lowering.

MPS.BARRIER(expr)

Uses the same protection family as MPS.OPAQUE, while also serving as a clear semantic marker in source.

MPS.NOFOLD(expr)

Prevents the marked expression from remaining a trivial literal or expression at the source AST stage.

MPS.IDENTITY(expr)

A compile-time identity marker. It disappears without changing the expression.

local value = MPS.OPAQUE(config.Value)
local important = MPS.NOFOLD(100 + offset)
AliasesMPS.HIDE = MPS.OPAQUEMPS.FENCE = MPS.BARRIER
Function protection

Give a sensitive function its own VM domain.

Function protection directives require an inline function(...) ... end expression and semantically return that function. You can store it, call it later, or immediately invoke it.

Protected section

You can immediately invoke the returned function when you only want to isolate a section of code.

MPS.VM(function()
    local players = game:GetService("Players")
    -- sensitive section
end)()
Strong aliasesMPS.VM_MAXMPS.REGIONMPS.PROTECT
Targeted VM transforms

Force one specific VM behavior.

MPS.FLATTEN(function(...) ... end)

Forces the VM-level CFG split rate to 100% for eligible blocks in this function.

MPS.SUPER(function(...) ... end)

Forces the superoperator fusion rate to 100% for eligible instruction patterns in this function.

MPS.CLOSURE(function(...) ... end)

Marks a closure-sensitive region for the MPS metadata path while keeping semantics unchanged.

MPS.VM_FAST(function(...) ... end)

Alias of MPS.VM.

AliasesMPS_CFFLAT = MPS.FLATTENMPS.SUPEROPS = MPS.SUPER
Choosing a directive

Do not turn every line into a special case.

For most code, use no directive. Prefer MPS.ENCSTR for a few sensitive literals and MPS.VM for a small sensitive function. Use MPS.VM_STRONG only for genuinely valuable sections because it intentionally creates more VM structure and can increase output and runtime cost.

NeedHide one sensitive stringMPS.ENCSTR
NeedStronger literal treatmentMPS.ENCSTR_STRONG
NeedIsolate one functionMPS.VM
NeedMaximum targeted VM treatmentMPS.VM_STRONG
Restrictions

What MPS expects.

  • String directives require literal strings.
  • Number directives require literal numbers.
  • Boolean directives require literal booleans.
  • VM, flatten, super and closure directives require an inline function expression.
  • The MPS namespace and MPS_* prefix are reserved compile-time intrinsics.
  • Unknown MPS intrinsics are treated as errors instead of silently becoming runtime globals.
  • MPS is obfuscation and hardening, not cryptographic secrecy. Client-side code can ultimately be analyzed.
Compatibility syntax

Namespace syntax is recommended.

Every canonical MPS.NAME(...) intrinsic also accepts the flat MPS_NAME(...) form.

-- recommended
local fn = MPS.VM(function() end)

-- compatibility form
local fn = MPS_VM(function() end)