// reference / macros
Macros
Macros are compile-time constructs that allow you to write conditional code paths and optimize performance in your obfuscated scripts.
Quick Reference
| Macro | Type | Purpose |
|---|---|---|
WYNF_OBFUSCATED | boolean | Detect if script is obfuscated |
WYNF_NO_VIRTUALIZE | function wrapper | Mark function for native execution (unprotected) |
WYNF_JIT | function wrapper | Faster VM execution for hot functions (performance) |
WYNF_JIT_MAX | function wrapper | Maximum performance VM for extremely hot functions (performance) |
WYNF_INLINE | compile-time macro | Inline small helper functions to avoid call overhead (performance) |
WYNF_CRASH | function call | Immediately terminate the script (destructive) |
WYNF_IS_CALLER_WYNFUSCATE | function call | Detect external callers (security) |
WYNF_ENC_STRING | string wrapper | Extra encryption for sensitive strings (security) |
WYNF_ENC_NUM | number wrapper | Extra encryption for sensitive numbers (security) |
WYNF_LINE | function call | Get source line number at compile time (debug) |
WYNF_NO_UPVALUES | function wrapper | Compatibility wrapper for callbacks (compatibility) |
WYNF_SECURE_CALL | function wrapper | Restrict function to VM-only callers (security) |
WYNF_SECURE_CALLBACK | function wrapper | Secure wrapper for event callbacks (security) |
WYNF_ENC_FUNC | function wrapper | Runtime-decrypted function with key server support (security) |
WYNF_ENC_FUNC_SEED | function wrapper | Runtime-decrypted function with numeric seed key (security) |
WYNF_GET_RNG_SEEDPREMIUM | function call | Per-run non-deterministic seed for RNG/anti-replay (security) |
WYNF_BEGIN_CLIENT_LINESPREMIUM | statement | Reset line-info base for service/enterprise builds (debug) |
WYNF_OBFUSCATED
booleanA compile-time constant that evaluates to true in obfuscated builds. In plain Lua (non-obfuscated), it behaves like a normal global (typically nil/false).
Dead Code Pruning
When used as an if condition, the compiler removes unreachable branches from the output entirely. This means dev-only stubs and fallback code gated by WYNF_OBFUSCATED are not present in the obfuscated bytecode at all — not just skipped at runtime.
Basic Example
Loading...Stripping Dev Code from Output
This pattern ensures dev fallback code is never shipped in the obfuscated file:
Loading...Development Stubs
Define stubs for macros so your code runs in development without errors. These stubs are completely removed from obfuscated output:
Loading...- Use to strip dev-only stubs from output
- Use to gate debug/profiling code
- Use for feature flags between dev/prod
- Use for verbose logging in dev only
- Assuming it prevents debugging/tampering
- Relying on it as sole protection for secrets
- Using for license enforcement alone
WYNF_NO_VIRTUALIZE
performanceWARNING: Code Exposure
Code wrapped with WYNF_NO_VIRTUALIZE is NOT protected through virtualization. Your code will be minified (local names, upvalue names, comments, and line information are stripped), but raw strings and logic will still be exposed.
Only use this for performance-critical code that does not contain sensitive logic, API keys, URLs, or any code you need to keep private.
Marks a function to run as native Lua instead of inside the VM. This bypasses VM overhead for performance-critical code like hot loops or heavy math/table/string operations.
Correct Usage
Use for performance-critical code that contains no sensitive information:
Loading...Incorrect Usage
Never use for code containing sensitive information - it will be exposed:
Loading...Upvalues
Functions can capture variables from the parent scope (upvalues). While upvalue names are stripped, the values themselves are not secure. Avoid referencing upvalues that contain sensitive information.
Loading...Development Stub
To run un-obfuscated scripts without errors, add this stub at the top of your file:
Loading...This stub is automatically ignored when the script is obfuscated.
- Use for hot loops or heavy computations
- Use for math/table/string operations
- Use only for non-sensitive code
- Keep function body self-contained
- Test in both obfuscated and plain runs
- Sensitive strings (API keys, URLs)
- License/auth validation logic
- Proprietary algorithms
- Recursive functions
- Nesting inside another no-virt function
Limitations
- Self-recursion: Not supported - the function cannot call itself
- Nesting: Cannot use WYNF_NO_VIRTUALIZE inside another no-virt function
- Mutual recursion: Two no-virt functions cannot call each other
WYNF_JIT
performanceMarks a function for Wynfuscate's JIT-style micro-VM execution path. The function remains virtualized (it still runs encrypted bytecode), but executes under a more performance-oriented interpreter template than the main VM loop.
Still Protected
Unlike WYNF_NO_VIRTUALIZE, your code is still virtualized and protected. The micro-VM intentionally skips some VM hardening/anti-tamper work to improve performance, but your code logic remains encrypted and hidden.
Usage
Loading...Performance Gains
Observed speedups compared to standard virtualization (Luau CLI):
Math/Calculations
~2.9x faster
String Operations
~2.7x faster
Iteration/Loops
~1.5x faster
Coroutine Yield
~1.7x faster
Development Stub
Loading...WYNF_JIT_MAX
performanceA higher-performance variant of WYNF_JIT with more aggressive caching and faster dispatch. The function remains virtualized, but uses additional optimizations for maximum speed.
Still Protected
Like WYNF_JIT, your code remains virtualized and protected.WYNF_JIT_MAX trades off more anti-tamper work for speed, but logic stays encrypted.
Usage
Loading...Performance Gains
Observed speedups compared to standard virtualization (Luau CLI):
Math/Calculations
~5.7x faster
String Operations
~3.8x faster
Iteration/Loops
~1.9x faster
Coroutine Yield
~2.9x faster
When To Use Which
Use WYNF_JIT when...
- You want a safe, general-purpose speedup
- The function is hot, but not your absolute hottest path
- You want less setup overhead
Use WYNF_JIT_MAX when...
- The function is extremely hot (tight loops, per-frame code)
- You create the closure once but call it many times
- You can tolerate aggressive performance tradeoffs
WYNF_JIT_MAX Tradeoffs
- Closure creation: More work at creation time - slower if you create the function frequently
- Memory: Uses more memory for per-closure caches
- Dynamic rebinding: Less friendly to rebinding globals/imports at runtime
Development Stub
Loading...Limitations (Both WYNF_JIT and WYNF_JIT_MAX)
- Function literal required: Must receive a function literal, not a variable
- Scope: Only the wrapped function is affected; everything else uses the normal VM
- Platform: Biggest wins are on Luau/Roblox; other targets may see smaller gains
- Dynamic rebinding: Avoid monkey-patching globals/builtins at runtime if using JIT functions
- Wrap small, hot functions (tight loops, math, string processing)
- Create JIT closures once and reuse them
- Use for functions called many times
- Cold functions (rarely called) - setup overhead can make it slower
- Code relying on late hooks/rebinding of globals
- Creating JIT closures inside loops
WYNF_INLINE
performanceWYNF_INLINE is a compile-time macro that removes a small helper function and expands its body directly at supported callsites during obfuscation. This avoids the call boundary cost for tiny helpers that are called many times. The expanded code is still virtualized with the rest of your script.
Still Protected
Inlining happens at compile time. The resulting code is compiled into the same virtualized/obfuscated VM as the rest of your script, so your logic stays inside the protected runtime.
Correct Usage
The helper must be declared as a local bound to a function literal. Arguments and the body are substituted at the callsite during obfuscation.
Loading...Block helpers with locals and control flow are also supported. The helper body is expanded as a scoped block.
Loading...Multiple return values are supported in assignment positions.
Loading...Read-only captured locals (upvalues) are supported as long as the captured binding is stable (not reassigned elsewhere). Mutating a captured table through that stable reference is allowed.
Loading...Incorrect Usage
The transform rejects unsupported shapes at obfuscation time instead of silently guessing.
Loading...Performance Gains
Internal benchmarks showed roughly 9-46% faster runtime on helper-heavy workloads, depending on usage and script. The biggest wins are on small helpers called many times from hot paths.
Development Stub
To run the source without obfuscation, define a passthrough stub:
Loading...WYNF_CRASH
securityImmediately and irrecoverably terminates the script. Use this as a last-resort defense when tampering or unauthorized access is detected.
Correct Usage
Loading...Incorrect Usage
Loading...Important: Direct Calls Only
WYNF_CRASH() must be called directly - it cannot be stored in a variable, passed as a callback, or referenced indirectly. The macro is detected at compile time and replaced with a secure crash sequence.
Behavior
When executed, the script stops immediately and cannot resume. No code after WYNF_CRASH() will execute. This makes it ideal for anti-tamper checks where you want execution to end the moment a violation is detected.
Development Stub
To run un-obfuscated scripts without errors, add this stub at the top of your file:
Loading...This stub is automatically ignored when the script is obfuscated. In development, it throws a standard Lua error to simulate the crash behavior.
- Use for anti-tamper responses
- Call directly in conditionals
- Use as last line of defense
- Combine with WYNF_OBFUSCATED checks
- Storing in variables
- Passing as function arguments
- Using in table values
- Indirect references of any kind
WYNF_IS_CALLER_WYNFUSCATE
securityReturns true if the current function was called from within your obfuscated code, and false if it was called from an external source like an exploit script. This protects your functions from being hijacked or invoked by malicious code, even when exploiters have access to function references.
Basic Example
Loading...Protecting RemoteEvent Handlers
Loading...Protecting Module Functions
Loading...Correct Usage
Check once at the entry point, then proceed with your logic:
Loading...Incorrect Usage
Loading...Development Stub
To run un-obfuscated scripts without errors, add this stub at the top of your file:
Loading...The stub always returns true, bypassing protection during development. The real protection activates when you obfuscate.
Testing
Test external caller detection in your production target environment (such as Roblox), not from the CLI.
- Use at the beginning of sensitive functions
- Protect functions exposed via RemoteEvents
- Combine with other validation layers
- Test logic works when macro returns true
- Using as your only security measure
- Calling in tight loops (expensive)
- Assuming it catches all attack vectors
- Expecting it to work in CLI environments
WYNF_ENC_STRING
securityApplies additional encryption layers to a string literal, providing extra protection for highly sensitive values like API keys, passwords, and encryption keys.
Basic Example
Loading...When to Use
- API Keys — External service credentials
- Encryption Keys — Keys used to encrypt/decrypt game data
- License Validation — Strings used in license checking logic
- Admin Passwords — Hardcoded fallback credentials
- Secret URLs — Hidden API endpoints
When NOT to Use
- Frequently accessed strings — Each access has overhead
- Strings in tight loops — Performance impact multiplies
- Non-sensitive UI text — Regular encryption is sufficient
- Large strings — Encryption overhead increases with size
Performance Consideration
WYNF_ENC_STRING adds additional encryption layers which has a performance cost on each access. For strings accessed once or twice per session, this is negligible. For strings accessed frequently, consider using regular string encryption instead.
Example: Protecting an API Client
Loading...Syntax Rules
Loading...Long-bracket literals are supported as literal arguments only; expressions are still not supported.
Development Stub
To run your script without obfuscation during development, add this stub at the top:
Loading...This allows your code to run normally in Studio or CLI while developing. When obfuscated, the real macro takes over and provides the additional encryption.
- Use for your most sensitive secrets
- Place at module scope or function entry
- Combine with other security measures
- Test code works before obfuscating
- Using in tight loops
- Using for every string
- Assuming strings are impossible to extract
- Using with variables or expressions
WYNF_ENC_NUM
securityProtects a numeric literal by encoding it in an encrypted form, preventing magic numbers from being trivially found via memory scanning or static analysis.
Supported Literal Formats
Accepts decimal integers, floating-point literals, and hexadecimal numeric literals.
Loading...When to Use
- Product IDs — Asset or game pass identifiers
- Feature Flags — Numeric flags for premium features
- Salts — Values used in hashing or validation
- Thresholds — Limits you do not want easily modified
- Magic Numbers — Any constant you want hidden
Correct Usage
Loading...Incorrect Usage
Loading...Only literal number tokens are accepted. Variables, arithmetic expressions, and runtime-derived values are not supported.
Performance Consideration
WYNF_ENC_NUM has overhead on each access. For best performance, assign once to a local variable and reuse that local throughout your code.
Development Stub
To run your script without obfuscation during development, add this stub at the top:
Loading...This allows your code to run normally in Studio or CLI while developing. When obfuscated, the real macro takes over and provides the additional encryption.
- Use for sensitive magic numbers
- Assign to a local once, reuse it
- Use numeric literals only
- Combine with other security measures
- Using variables as arguments
- Using expressions
- Calling repeatedly in tight loops
- Assuming numbers are impossible to extract
WYNF_LINE
debugExpands to the current source line number at compile time. This provides a stable line marker for logs and error messages without relying on VM debug info, which is stripped during obfuscation.
Basic Example
Loading...When to Use
- Error Messages — Include line numbers in error reports
- Debug Logging — Track execution flow with stable markers
- Support Tickets — Help users report issues with line references
- Assertions — Add context to assertion failures
Correct Usage
Loading...Incorrect Usage
Loading...Development Stub
To run your script without obfuscation during development, add this stub at the top:
Loading...This uses the Lua debug library to get the actual line number during development. When obfuscated, the macro is replaced with the compile-time line number.
- Use for error and debug messages
- Call directly as a global function
- Use to help with support tickets
- Combine with other context info
- Shadowing with a local variable
- Storing the function reference
- Expecting runtime line tracking
- Using for security purposes
WYNF_NO_UPVALUES
compatibilityCreates a lightweight wrapper around your function for compatibility with certain environments or APIs that have issues with virtualized functions used as callbacks. Your function remains fully protected — only the wrapper is simplified for compatibility.
Basic Example
Loading...When to Use
- Signal Callbacks — Functions connected to events or signals
- Hook APIs — Functions passed to hooking or interception APIs
- Third-Party Libraries — Callbacks passed to external libraries
- Environment Compatibility — When you encounter errors with virtualized callbacks
Correct Usage
Loading...Compatibility, Not Security
This macro is for compatibility purposes only. Your function body remains virtualized and protected, but the wrapper itself is simplified. Only use this when you encounter compatibility issues with callbacks — for normal functions, standard virtualization provides stronger protection.
Development Stub
To run your script without obfuscation during development, add this stub at the top:
Loading...This simply returns the function as-is during development. When obfuscated, the macro creates the compatibility wrapper while keeping your code protected.
- Use for callbacks and signal handlers
- Use when you hit compatibility issues
- Wrap function literals directly
- Test in your target environment
- Using for all functions (unnecessary)
- Using when standard virtualization works
- Expecting extra security benefits
- Using for non-callback functions
WYNF_SECURE_CALL
securityMarks a function as VM-only callable. Calls to this function will only succeed when they originate from inside your obfuscated code. If an external script obtains a reference to this function and tries to call it directly, the call will be rejected.
Basic Example
Loading...When to Use
- Internal Helpers — Functions that should never be invoked from outside
- Decoders — Functions that decode or decrypt sensitive data
- Guard Logic — Internal security checks and validation functions
- Sensitive Operations — Functions that would be dangerous if called out of band
When NOT to Use
- Roblox Events — RemoteEvents, Signals, and UI callbacks are invoked by the engine, not the VM
- Engine Callbacks — Any function passed to Roblox APIs that will call it externally
For callbacks and event handlers, use WYNF_SECURE_CALLBACK instead.
Fail-Closed Behavior
When an external caller attempts to invoke a WYNF_SECURE_CALL function, the call is rejected immediately (fail-closed). This is intentional — use this for functions that should never be called from outside under any circumstances.
Development Stub
To run your script without obfuscation during development, add this stub at the top:
Loading...The stub returns the function as-is during development. When obfuscated, the real caller validation takes effect.
- Use for internal-only functions
- Use for decoders and sensitive helpers
- Use for functions that must never be called externally
- Combine with other security measures
- Using for event handlers or callbacks
- Using for functions called by Roblox APIs
- Using when you need soft rejection
- Using as your only security measure
WYNF_SECURE_CALLBACK
securityReturns a wrapped callback that performs a caller gate before invoking your function. Intended for event handlers and callbacks that are called by external systems like Roblox signals, RemoteEvents, and UI events.
Basic Example
Loading...Roblox Examples
Loading...Fail-Quiet Behavior
Unlike WYNF_SECURE_CALL, this macro uses fail-quiet behavior. If the caller is external, the callback simply returns nil instead of crashing. This is appropriate for callbacks where you want silent rejection rather than hard failure.
When to Use
- RemoteEvent Handlers — OnServerEvent, OnClientEvent callbacks
- BindableEvent Handlers — Internal signal callbacks
- UI Callbacks — Button clicks, input handlers
- RunService Connections — Heartbeat, RenderStepped callbacks
- Any Engine Callback — Functions passed to Roblox APIs that will invoke them
Development Stub
To run your script without obfuscation during development, add this stub at the top:
Loading...The stub returns the function as-is during development. When obfuscated, the wrapper provides caller validation while maintaining compatibility with engine callbacks.
- Use for event handlers and callbacks
- Use for functions passed to Roblox APIs
- Use when you need soft rejection
- Wrap directly before passing to Connect()
- Using for internal-only functions (use WYNF_SECURE_CALL)
- Using when you need fail-closed behavior
- Using as your only security measure
- Expecting it to prevent all callback attacks
WYNF_ENC_FUNC
securityEncrypts a function body at build time and returns a callable wrapper that decrypts and executes the function at runtime using a key provided by your server. This is designed for whitelist/key-server workflows where the correct decryption key is only available at runtime from a trusted source.
How It Works
- Build time: The function is encrypted with your key
- Runtime: The function is decrypted and executed using the key you provide
- Security: The encryption key never appears in the obfuscated output — it must come from your server
Signature
Loading...Generating a Key
You need a secure 64-character hex string to use as your encryption/decryption key. We provide a built-in generator in the dashboard:
- Go to Dashboard → Settings
- Scroll down to the Developer Tools section
- Click Generate to create a cryptographically secure 64-character hex key
- Copy the key and store it securely on your server
- Use this same key for both
encKeyHex64in your script and as the runtimedecKeyreturned by your server
Correct Usage
Loading...Incorrect Usage
Loading...Key Model
The runtime decKey must be the same 64-character hex string as the build-time encKeyHex64. Your server stores this key and returns it to authorized clients at runtime. An incorrect key fails safely and the function will not run.
Key Security
The encryption key (encKeyHex64) is a compile-time input only — it is never emitted in the obfuscated output. The decryption key must come from your server at runtime, not hardcoded in your script. If you hardcode the decryption key, you defeat the entire purpose of this macro.
Fail-Closed on Wrong Key
If the decryption key is wrong or the payload is tampered with, the function will fail closed — crash or poison the VM, not return garbage. This ensures attackers cannot probe for partial decryption or use incorrect keys.
Current Limitations
- The protected function must be a constant function literal (not a variable)
- The protected function must not capture upvalues from outer scopes
- The protected function must not contain nested function literals
Performance Notes
- First call: Incurs decrypt + load overhead (cold path)
- Subsequent calls: The dispatcher is cached for fast execution
- No persistent cache: Decrypted proto is not stored in a globally dumpable structure
Development Stub
To run your script without obfuscation during development, add this stub at the top:
Loading...This ignores the encryption key arguments and returns the function as-is during development. When obfuscated, the real macro encrypts the function and requires the correct runtime key.
- Fetch decryption key from your server
- Use for whitelist/license workflows
- Use constant function literals only
- Keep protected functions self-contained
- Handle key fetch failures gracefully
- Hardcoding the decryption key
- Using variables for the function argument
- Capturing upvalues in protected function
- Nesting functions inside protected function
- Using variables for the encryption key
WYNF_ENC_FUNC_SEED
securityA numeric-key variant of WYNF_ENC_FUNC. Instead of a 64-character hex string, this macro uses a numeric seed for encryption/decryption. This is intended for Roblox/Luau workflows where a numeric key is preferred over a hex string for key hygiene and lower grepability.
How It Works
- Build time: The function is extracted and encrypted using a deterministic stream keyed by
encSeed - Runtime: Returns a wrapper that decrypts and materializes the function on first call using
decSeed - Key format: Numeric seeds instead of hex strings for cleaner Roblox/Luau integration
Signature
Loading...Key Model
encSeedmust be a constant integer literal in the range [0, 2^53-1]- In Luau, numbers are doubles; integers above 2^53 lose precision
decSeedshould be runtime-derived (e.g., returned by your auth server)- Supplying the wrong seed produces undefined results; use
pcall()if you want to catch failures
Correct Usage
Loading...Incorrect Usage
Loading...Security Strength
Security strength is bounded by the seed space (up to 53 bits). This is typically sufficient to deter casual brute forcing, but it is not 256-bit strength like the hex-key variant. Runtime extraction is still possible with a fully privileged runtime attacker; this macro is about reducing trivial static/offline recovery and raising the bar.
WYNF_ENC_FUNC vs WYNF_ENC_FUNC_SEED
Use WYNF_ENC_FUNC when...
- You need maximum security (256-bit)
- You already have hex-based key infrastructure
- Key fingerprinting is not a concern (64-char hex strings may produce an identifiable fingerprint via introspection)
Use WYNF_ENC_FUNC_SEED when...
- You prefer numeric keys for Roblox/Luau
- You want to avoid key fingerprinting (numeric seeds blend in with normal numbers)
- 53-bit security is sufficient for your use case
Development Stub
Loading...WYNF_GET_RNG_SEED
securitypremiumReturns a unique, non-deterministic integer seed on every script execution. Use it to initialize your own RNG, generate per-session nonces, or build anti-replay logic without relying on globals like math.random or os.clock.
Premium Macro
This macro requires a Pro or Enterprise plan. Scripts using this macro on a free account will fail with a premium entitlement error.
Return Value
- Integer in the range
[0, 2147483647] - Different value on every script execution
- Multiple calls within the same execution return different values
- Resistant to common runtime patching
Alias
WYNF_GET_RNG() is accepted as an alias and behaves identically.
Basic Usage
Loading...Anti-Replay Example
Loading...Multiple Seeds
Each call returns a different value from an independent draw sequence:
Loading...When to Use
- Anti-replay - generate per-session nonces or tokens
- Randomized behavior - seed your own PRNG for gameplay variance
- Key derivation - combine with server provided material for per-session keys
- Fingerprinting - create unique per-execution identifiers
When NOT to Use
- Cryptographic randomness - this is not a cryptographic random number generator
- Tight loops - each call performs multiple internal draws. Call once and seed your own fast RNG for better performance
- Deterministic builds - produces different output each run by design
Performance
Each macro call is performance expensive. This is negligible for one-time seed initialization but not intended for tight loop usage.
Loading...Supported Platforms
| Platform | Supported |
|---|---|
| luau / roblox / roblox-compat | Yes |
| lua51 / luajit / lua52 / lua53 / lua54 | No (compile-time error) |
Syntax
Loading...Security Notes
- Uses multiple independent entropy lanes with validation, making naive patching ineffective
- Not a guarantee against fully privileged attackers with custom VM instrumentation
- Combine with server side validation for best results do not rely on this alone as protection
Development Stub
To run your script without obfuscation during development:
Loading...Complete Example: Session-Unique Game Logic
Loading...When to Use What
WYNF_OBFUSCATED
Use to strip dev-only code from obfuscated output. Unreachable branches are completely removed at compile time — not just skipped at runtime. Good for dev stubs, debug logging, and environment-specific code paths.
WYNF_NO_VIRTUALIZE
Use only for performance-critical code that runs frequently and contains no sensitive information. The function runs as native Lua (minified only), bypassing VM protection entirely. Code inside is exposed - use for math, loops, and non-secret operations only.
WYNF_CRASH
Use as a last-resort defense when tampering or unauthorized access is detected. Immediately and securely crashes the VM, making recovery impossible. Must be called directly - cannot be stored or passed indirectly.
WYNF_IS_CALLER_WYNFUSCATE
Use to protect sensitive functions from being called by external code (exploits). Returns true if called from your obfuscated code, false otherwise. Check once at entry point - avoid using in loops due to stack walking overhead.
WYNF_ENC_STRING
Use for highly sensitive strings like API keys, passwords, and encryption keys. Adds additional encryption layers for extra protection. Avoid using in tight loops or for frequently accessed strings due to performance overhead.
WYNF_ENC_NUM
Use for sensitive magic numbers like product IDs, feature flags, salts, and thresholds. Prevents numbers from being trivially found via scanning. Assign once to a local and reuse for best performance.
WYNF_LINE
Use for debugging and error reporting. Returns the source line number at compile time, providing stable line markers for logs and error messages even after obfuscation.
WYNF_NO_UPVALUES
Use for callback compatibility when virtualized functions cause issues with certain APIs or environments. Creates a compatible wrapper while keeping your code protected.
WYNF_SECURE_CALL
Use for internal-only functions that should never be called from outside your obfuscated code. External calls are rejected (fail-closed). For callbacks passed to Roblox APIs, use WYNF_SECURE_CALLBACK instead.
WYNF_SECURE_CALLBACK
Use for event handlers and callbacks passed to Roblox APIs (RemoteEvents, signals, UI events). Unlike WYNF_SECURE_CALL, uses fail-quiet behavior (returns nil) for compatibility with engine-invoked callbacks.
WYNF_ENC_FUNC
Use for whitelist/key-server workflows where critical functions should only work with a valid runtime key from your server. The function is encrypted at build time and decrypted at runtime using a key that must be fetched from your backend - never hardcoded.
WYNF_ENC_FUNC_SEED
Use for numeric-key workflows in Roblox/Luau where a numeric seed is preferred over hex strings. Same runtime decryption model as WYNF_ENC_FUNC but with 53-bit numeric keys that blend in with normal numbers, reducing the risk of key fingerprinting via introspection.
WYNF_GET_RNG_SEED PREMIUM
Use for anti-replay, session tokens, and seeding your own RNG without relying on globals. Returns a unique integer per execution using multiple internal entropy sources.
WYNF_BEGIN_CLIENT_LINES
statementpremiumA source-level line-info marker for enterprise builds that prepend their own loader, key system, or whitelist code above a customer's script. Available on the Enterprise plan.
When used with the Line Info setting enabled, the macro resets the displayed source line base so the next physical line is reported as client line 1. This makes runtime errors easier to support when service-owned prelude code is inserted above customer code before obfuscation.
Requires the Line Info setting to be enabled on the upload page. Without it, the marker has no runtime reporting effect, but invalid usage is still rejected at compile time. This macro is available exclusively on the Enterprise plan.
Basic Usage
Loading...With line info enabled, the error("client boom") line is reported as client line 4 (relative to the marker), not physical line 8.
Error Output Format
Errors before the marker are tagged with [prelude] to distinguish service-owned failures from client-script failures:
Loading...Recommended Use Case
Typical pattern for hosted script services, enterprise loaders, or key system wrappers:
Loading...Requirements
Single use only - exactly one use per file is allowed
Top-level standalone statement - must appear as its own top-level statement, not inside a function, expression, table, or wrapper call
Line Info required - only affects runtime error remapping when --enable-line-info is enabled
Syntax Rules
Valid
Loading...Valid - service prelude above, client code below
Loading...Invalid - duplicate usage
Loading...Invalid - nested inside a function
Loading...Invalid - not a standalone top-level statement
Loading...Invalid usage produces a compile-time InvalidMacroUsage error.
Development Stub
For running your code without obfuscation during development:
Loading...Summary
WYNF_BEGIN_CLIENT_LINES PREMIUM
Use when your build prepends service-owned code (loaders, key systems, auth wrappers) above customer scripts. Resets the line-info base so runtime errors report client-relative line numbers for easier support.