NEX Documentation
Discord GitHub

Functions

Global Functions

These are injected into the exploit global environment (genv) and are accessible from any script, including raw executor scripts running outside emulated Roblox scripts.

LoadLocalAsset(filepath:string):Instance

FilesEnabled

Loads a Roblox model file (.rbxm or .rbxmx) from the game's storage directory specified by filepath and returns the loaded instance. The path is automatically prefixed with the storage directory.

Example Usage

local FilePath = "Tool.rbxm" local FileData = -- [[ large string of binary/xml data ]] repeat task.wait() until NEX_Loaded if not Settings.FilesEnabled then warn("Please turn on FilesEnabled in settings!") end writefile(FilePath, FileData) repeat task.wait() until isfile(FilePath) local Object = LoadLocalAsset(FilePath) Object.Parent = game.Players.LocalPlayer.Backpack print("Loaded and parented:", Object.Name)

Accuracy: NEX Developed

GetLocalObjects(filepath:string):table

Reads a local Roblox XML or binary file from storage and deserializes it via SerializationService:DeserializeInstancesAsync. Automatically applies FixStudioXML to patch Studio-exported files (replaces Workspace with Model and Terrain with Folder). Returns a table of root-level instances.

Example Usage

repeat task.wait() until NEX_Loaded -- Works with both .rbxmx (XML) and .rbxm (binary) files local instances = GetLocalObjects("MyModel.rbxmx") for _, inst in ipairs(instances) do inst.Parent = workspace end

Accuracy: NEX Developed

GetObjects(assetUrl:string):table

Fetches a Roblox asset from the asset delivery CDN using its numeric ID, deserializes it, and returns a table of instances. The assetUrl string must contain a numeric asset ID.

Example Usage

repeat task.wait() until NEX_Loaded local instances = GetObjects("rbxassetid://12345678") for _, inst in ipairs(instances) do inst.Parent = workspace print("Inserted:", inst.Name) end

Accuracy: NEX Approved

InsertAsset(assetId:string):Instance

Loads an asset directly from Roblox using its asset ID or rbxassetid URL via InsertService:LoadLocalAsset and returns the loaded instance.

Example Usage

repeat task.wait() until NEX_Loaded local Object = InsertAsset("rbxassetid://123456789") if Object then Object.Parent = game.Workspace print("Inserted:", Object.Name) end

Accuracy: NEX Approved

GetProperties(instance:Instance):table

Returns a dictionary of all readable properties for the given instance using ReflectionService:GetPropertiesOfClass. Keys are property names, values are current property values.

Example Usage

repeat task.wait() until NEX_Loaded local props = GetProperties(workspace.BasePlate) for name, value in pairs(props) do print(name, "=", tostring(value)) end

Accuracy: NEX Developed

getfilename(path:string, removedot:boolean?):string

Extracts the filename from a full path string. If removedot is true, strips the file extension.

Example Usage

repeat task.wait() until NEX_Loaded print(getfilename("Folder/Sub/MyScript.lua")) -- "MyScript.lua" print(getfilename("Folder/MyScript.lua", true)) -- "MyScript"

Accuracy: NEX Developed

ToastNotify(options:table):null

Sends a native toast notification via GuiService:SendNotification. Accepts Title, Text, and Icon fields.

Example Usage

repeat task.wait() until NEX_Loaded ToastNotify({ Title = "NEX Emulator", Text = "Script executed successfully.", Icon = "rbxassetid://1347201659" })

Accuracy: Inaccurate (There are more properties that we don't know of.)

DisconnectFromServer(null):null

Immediately disconnects the client by kicking the local player, waiting for the ClientReplicator to be destroyed, then rebuilds the character locally (removing BasePart and Accessory children that were network-replicated) so the game remains usable offline. Also disables the Dead humanoid state to prevent ragdoll.

Accuracy: NEX Developed

GetCurrentThread(null):thread

Returns the native Luau thread object for the calling environment by scanning the Lua registry for a thread whose first function matches the caller.

Example Usage

repeat task.wait() until NEX_Loaded local t = GetCurrentThread() print(typeof(t)) -- "thread"

Accuracy: NEX Developed

Rrequire(ModuleScript:ModuleScript):any

RobloxScriptRequire

Exposes the native Roblox environment require function directly, allowing emulated scripts to load RobloxScript modules from protected locations like CorePackages.

Example Usage

repeat task.wait() until NEX_Loaded local SpecialModule = game.CorePackages.Packages.HttpRequest local RequiredModule = Rrequire(SpecialModule)

Accuracy: NEX Developed

roblox Namespace

Available to emulated scripts via the roblox global.

roblox.GetAssetSource(assetId:string):string

Fetches the raw source data of a Roblox asset from the delivery CDN. The returned data may be in XML or binary format.

Example Usage

repeat task.wait() until NEX_Loaded local source = roblox.GetAssetSource("12345678") print(roblox.BinaryFormat.XMLType(source)) -- "xml" or "binary"

Accuracy: NEX Developed

roblox.DownloadAsset(assetId:string, filename:string):null

FilesEnabled

Downloads the raw source of a Roblox asset and saves it to the game storage directory under filename.

Example Usage

repeat task.wait() until NEX_Loaded roblox.DownloadAsset("12345678", "MyModel.rbxm") repeat task.wait() until isfile("MyModel.rbxm") print("Downloaded.")

Accuracy: NEX Developed

roblox.BinaryFormat.XMLType(data:string):string

Detects the format of a Roblox data string. Returns "binary" if the string starts with <roblox!, "xml" if it starts with <roblox, or "unknown" otherwise.

local fmt = roblox.BinaryFormat.XMLType(data) -- "binary", "xml", or "unknown"

Accuracy: NEX Developed

roblox.BinaryFormat.FixStudioXML(xml:string):string

Patches Studio-exported XML for use in live games. Replaces Workspace item class with Model and Terrain with Folder, since those classes cannot be deserialized outside their native context.

local fixed = roblox.BinaryFormat.FixStudioXML(studioXml) local instances = roblox.XML.Load(fixed)

Accuracy: NEX Developed

roblox.XML.Object(className:string, parent:Instance):Instance

Creates a new instance of the given class by building a minimal Roblox XML document and deserializing it. Parents the result to parent. Requires XMLEnabled.

Example Usage

repeat task.wait() until NEX_Loaded local part = roblox.XML.Object("Part", workspace) print(part.ClassName) -- "Part"

Accuracy: NEX Developed

roblox.XML.Load(xml:string):table

Deserializes a Roblox XML string and returns a table of root instances. Requires XMLEnabled.

Example Usage

repeat task.wait() until NEX_Loaded local instances = roblox.XML.Load(readfile("MyModel.rbxmx")) for _, inst in ipairs(instances) do inst.Parent = workspace end

Accuracy: NEX Developed

roblox.XML.XMLToTable(xml:string):table

Parses a Roblox XML string into a Luau table tree without creating live instances. Each instance becomes a sub-table keyed as Item1, Item2, etc., with ClassName, Referent, and property fields tagged as {Tag=typeName, Value=value}. Shared strings are stored in a top-level SharedStrings field.

Example Usage

repeat task.wait() until NEX_Loaded local t = roblox.XML.XMLToTable(xmlString) -- t.Item1.ClassName → "Part" -- t.Item1.Name.Tag → "string" -- t.Item1.Name.Value → "Baseplate"

Accuracy: NEX Developed

roblox.XML.TableToXML(root:table):string

Serializes a Luau table tree (as produced by XMLToTable) back into valid Roblox XML. Referents are remapped to sequential NEX1, NEX2, etc. IDs and Ref-type properties are relinked accordingly.

Example Usage

repeat task.wait() until NEX_Loaded local t = roblox.XML.XMLToTable(xmlString) t.Item1.Name = {Tag="string", Value="NewName"} writefile("Modified.rbxmx", roblox.XML.TableToXML(t))

Accuracy: NEX Developed

roblox.XML.SplitXML(xml:string, wrap:boolean?):table

Splits a multi-item Roblox XML document into individual per-item XML chunks. Returns a table of {Class, XML} entries. If wrap is true, each chunk is wrapped in a full <roblox>…</roblox> document with needed SharedStrings included.

Example Usage

repeat task.wait() until NEX_Loaded local chunks = roblox.XML.SplitXML(bigXml, true) for _, chunk in ipairs(chunks) do print(chunk.Class, #chunk.XML) end

Accuracy: NEX Developed

requests Namespace

A Python-requests-style HTTP library. All methods take a URL string and an options table (same fields as request).

Response object fields:
ok — boolean success
status_code — HTTP status code
text — raw body string
content — body as hex-escaped UTF-8 byte string
headers — response headers table
url — the request URL
elapsed — timing from x-timer header
json() — decodes body as JSON and returns table
raise_for_status() — throws if ok is false

requests.get(url:string, options:table):table

HTTPEnabled

requests.post(url:string, options:table):table

HTTPEnabled

requests.put(url:string, options:table):table

HTTPEnabled

requests.patch(url:string, options:table):table

HTTPEnabled

requests.delete(url:string, options:table):table

HTTPEnabled

requests.options(url:string, options:table):table

HTTPEnabled

Example Usage

repeat task.wait() until NEX_Loaded local res = requests.get("https://api.example.com/data", { Headers = {["Authorization"] = "Bearer mytoken"} }) res:raise_for_status() local data = res:json() print("Name:", data.name)

Accuracy: NEX Developed

NEXHttp Namespace

NEXHttp.download(url:string, filename:string, chunksize:number?):table

FilesEnabled

Downloads a file from url into storage using HTTP Range headers in chunks. Runs asynchronously in a coroutine. chunksize is a KB multiplier; default is 16 KB. Returns a download-state object.

Download state:
finished — true when complete
installedsize — bytes written so far
size — Content-Length string (or "0" if HEAD unsupported)
WaitForFile(self) — yields until done, returns final byte count

Example Usage

repeat task.wait() until NEX_Loaded local dl = NEXHttp.download("https://example.com/file.dat", "file.dat", 64) print("Size:", dl.size) dl:WaitForFile() print("Done! Bytes:", dl.installedsize)

Accuracy: NEX Developed

NEXHttp.streamget(url:string, chunksize:number?):table

HTTPEnabled

Streams the response body of a GET request in chunks without writing to disk. Accumulates into a body field on the returned state object.

Stream state:
finished — true when complete
body — accumulated response so far
installedsize — bytes received
size — Content-Length if available
WaitForFile(self) — yields until finished, returns full body

Example Usage

repeat task.wait() until NEX_Loaded local stream = NEXHttp.streamget("https://example.com/large.html") local body = stream:WaitForFile() print("Got", #body, "bytes")

Accuracy: NEX Developed

git Namespace

git.getgit(url:string):table, string

Queries the GitHub API for the contents of a repository or folder at the given GitHub URL. Automatically converts github.com URLs to the appropriate api.github.com endpoint. Returns a contents table (keys are filenames, values have path, url, rawurl, type, self) and the repository name.

Example Usage

repeat task.wait() until NEX_Loaded local contents, repoName = git.getgit("https://github.com/User/Repo") for name, info in pairs(contents) do print(name, info.type, info.rawurl) end

Accuracy: NEX Developed

git.clone(url:string):null

FilesEnabled

Clones an entire GitHub repository into the game storage directory, preserving folder structure. Subdirectories are recursively fetched via the GitHub API and files are downloaded with NEXHttp.download.

Example Usage

repeat task.wait() until NEX_Loaded git.clone("https://github.com/User/Repo") -- Files now in: Repo/

Accuracy: NEX Developed

crypt Namespace

crypt.utf8.encode(data:string):string

Encodes a string to a hex-escaped byte string where each byte is represented as \xHH. Useful for safely encoding binary data as printable ASCII.

crypt.utf8.decode(data:string):string

Decodes a hex-escaped \xHH string back to its original binary form.

Example Usage

repeat task.wait() until NEX_Loaded local enc = crypt.utf8.encode("Hello\0World") print(enc) -- "\x48\x65\x6C\x6C\x6F\x00\x57..." print(crypt.utf8.decode(enc)) -- "Hello\0World"

Accuracy: NEX Developed

crypt.base64.encode(data:string):string

Encodes a string using Base64.

crypt.base64.decode(data:string):string

Decodes a Base64 string back to its original form.

Example Usage

repeat task.wait() until NEX_Loaded local b64 = crypt.base64.encode("Hello, NEX!") print(b64) -- "SGVsbG8sIE5FWCE=" print(crypt.base64.decode(b64)) -- "Hello, NEX!"

Accuracy: NEX Approved (via crypt.base64)

File Functions

All sandboxed file functions operate within the game's isolated storage directory (GameData/<rootPlaceId>/Storage/). Paths are automatically prefixed — you cannot escape this directory. The ExternalFileFunctions table (requires ExternalFilePerms) provides the raw unsandboxed originals.

OpenFile(path:string?):File

FilesEnabled

Creates or opens a file or folder at the given path within storage and returns a File userdata object. If path is nil, creates an "unnamed" file (or "unnamed (N)" to avoid collisions). The returned object has a locked metatable and uses a buffer as its underlying userdata.

File object API:
Path — current path (assigning renames/moves the file)
Name — filename only (assigning renames in-place)
Type"file" or "folder" (assigning converts the entry)
Read(self):string — returns full file content
Write(self, content:string) — overwrites file content
ReadLine(self, line:number):string — returns a specific line (1-indexed)
ReplaceLine(self, line:number, content:string) — replaces a specific line
GetChildren(self):table — lists direct children (folders only)
GetDescendants(self):table — lists all descendants recursively (folders only)
Destroy(self) — deletes the file or folder

Example Usage

repeat task.wait() until NEX_Loaded local f = OpenFile("config.txt") f:Write("version=1\nenabled=true") print(f:ReadLine(2)) -- "enabled=true" f:ReplaceLine(1, "version=2") print(f:Read()) -- "version=2\nenabled=true" f:Destroy()

Accuracy: NEX Developed

readline(path:string, line:number):string

FilesEnabled

Reads a specific 1-indexed line from a file in storage.

Example Usage

repeat task.wait() until NEX_Loaded local line2 = readline("config.txt", 2) print("Line 2:", line2)

Accuracy: NEX Developed

writeline(path:string, line:number, content:string):null

FilesEnabled

Writes content to a specific 1-indexed line in a file in storage. If the line doesn't exist, the file is extended with empty lines as needed.

Example Usage

repeat task.wait() until NEX_Loaded writeline("config.txt", 3, "newkey=hello") print(readline("config.txt", 3)) -- "newkey=hello"

Accuracy: NEX Developed

typefile(path:string):string

FilesEnabled

Returns "file" or "folder" depending on what exists at path. Throws an error if the path doesn't exist.

Example Usage

repeat task.wait() until NEX_Loaded print(typefile("config.txt")) -- "file" print(typefile("Scripts")) -- "folder"

Accuracy: NEX Developed

getcustomasset(filepath:string):string

FilesEnabled

Uploads a file from storage to Roblox's temporary content system and returns its rbxasset:// URL. Suitable for use as texture or audio source properties.

Example Usage

repeat task.wait() until NEX_Loaded local url = getcustomasset("flower.png") workspace.Part.Decal.Texture = url

Accuracy: NEX Developed

readfile(filepath:string):string

FilesEnabled

Reads and returns the content of a file in storage as a string.

Example Usage

repeat task.wait() until NEX_Loaded if isfile("MyData.txt") then print(readfile("MyData.txt")) end

Accuracy: NEX Developed

writefile(filepath:string, content:string):null

FilesEnabled

Writes a string to a file in storage, creating it if it does not exist.

makefolder(filepath:string):null

FilesEnabled

Creates a new folder at the given path in storage.

deletefile(filepath:string):null

FilesEnabled

Deletes a file from storage.

deletefolder(filepath:string):null

FilesEnabled

Deletes a folder and its contents from storage.

isfile(filepath:string):boolean

FilesEnabled

Returns true if a file exists at the path in storage.

isfolder(filepath:string):boolean

FilesEnabled

Returns true if a folder exists at the path in storage.

appendfile(filepath:string, content:string):null

FilesEnabled

Appends content to the end of a file in storage.

listfiles(filepath:string):table

FilesEnabled

Returns a table of file/folder names in the given directory within storage. Pass nil or "./" to list the root of storage.

loadfile(filepath:string):function

FilesEnabled

Loads and returns a Luau script from storage as a callable function.

ExternalFileFunctions

A table populated only when ExternalFilePerms is enabled. Contains the raw, unsandboxed exploit file functions (readfile, writefile, getcustomasset, etc.) that operate on the full filesystem rather than the game storage directory.

Warning: Functions inside ExternalFileFunctions can read/write anywhere the executor can access. Enable ExternalFilePerms in Settings to populate this table.
-- Only available when ExternalFilePerms = true local raw = ExternalFileFunctions.readfile("C:/path/to/anything.txt")

Identity & Thread

setidentity(level:number):null

CapabilityMax

Changes the execution identity (privilege level) of the current thread. The level cannot exceed the CapabilityMax setting value. If it does, a warning is issued and nothing happens.

Example Usage

repeat task.wait() until NEX_Loaded local id = getthreadidentity() setidentity(3) print(getthreadidentity()) -- 3 setidentity(id) -- restore

Accuracy: NEX Developed

getthreadidentity(null):number

Returns the current execution identity (privilege level) of the calling thread.

Example Usage

repeat task.wait() until NEX_Loaded print("Identity:", getthreadidentity())

Accuracy: NEX Developed

HTTP

request(options:table):table

HTTPEnabled

Performs an HTTP request using the options table. Returns a standard executor HTTP response with StatusCode, Body, Headers, Success, etc.

Example Usage

repeat task.wait() until NEX_Loaded local resp = request({ Url = "https://example.com/api/data", Method = "GET", Headers = {["Content-Type"] = "application/json"} }) print(resp.StatusCode, resp.Body)

Accuracy: NEX Approved

Miscellaneous

UpdateNEX(null):null

Re-runs NEX's environment injection pass (nexify) on all currently registered Luau threads. Useful if a new script spawned after the initial load and did not receive the NEX environment.

repeat task.wait() until NEX_Loaded UpdateNEX()

Accuracy: NEX Developed

getrenv(null):table

Returns the Roblox environment table — the injected global table that emulated scripts receive.

Accuracy: NEX Developed

getsenv(instance:Instance):table

Returns the script environment of the given instance (typically a LocalScript or Script).

repeat task.wait() until NEX_Loaded local env = getsenv(game.StarterPlayer.StarterPlayerScripts.MyScript)

Accuracy: NEX Developed

clonefunction(func:function):function

Returns a cloned copy of a Luau function unaffected by later hookfunction calls on the original.

repeat task.wait() until NEX_Loaded local cloned = clonefunction(print) hookfunction(print, function() warn("Hooked!") end) cloned("Not hooked.") -- works normally print("Is hooked.")

Accuracy: NEX Developed

hookfunction(original:function, hook:function):function

Replaces original with hook. Returns the original function.

repeat task.wait() until NEX_Loaded hookfunction(print, function(...) warn("Print called!") end)

Accuracy: NEX Developed

newcclosure(func:function):function

Wraps a Luau function in a C-closure, making it more resilient to certain forms of inspection.

repeat task.wait() until NEX_Loaded local c = newcclosure(function(a, b) return a + b end) print(c(5, 7)) -- 12

Accuracy: NEX Developed

newlclosure(func:function, env:table):function

Creates a new Luau closure optionally bound to a custom environment table.

repeat task.wait() until NEX_Loaded local l = newlclosure(function() print(CustomGlobal) end, {CustomGlobal="Hello!"}) l()

Accuracy: NEX Developed

setreadonly(table:table, readonly:boolean):null

Sets the read-only status of a table. If the executor lacks native setreadonly, NEX emulates it by locking the metatable with a blocking __newindex.

repeat task.wait() until NEX_Loaded local t = {a=1} setreadonly(t, true) t.a = 5 -- silently fails print(t.a) -- 1 setreadonly(t, false) t.a = 10 print(t.a) -- 10

Accuracy: NEX Developed

rawsetmetatable(target:userdata/table, mt:table):null

Sets the metatable for a table or userdata without triggering __metatable guards.

repeat task.wait() until NEX_Loaded rawsetmetatable(myTable, {__index = function(t,k) return "Intercepted: "..k end}) print(myTable.someKey)

Accuracy: NEX Developed

rawgetmetatable(target:userdata/table):table

Retrieves the metatable of a table or userdata without triggering __metatable guards.

repeat task.wait() until NEX_Loaded local mt = rawgetmetatable(Instance.new("Part")) print(typeof(mt))

Accuracy: NEX Developed

GetRegisteredInstances(null):table

Returns a table containing references to most instances existing in Luau's internal registry state.

repeat task.wait() until NEX_Loaded local all = GetRegisteredInstances() for _, inst in pairs(all) do if inst:IsA("Part") then print(inst.Name) end end

Accuracy: NEX Developed

CloneReference(ref:userdata):userdata

Returns a new independent reference to the given userdata. Changes to the clone's metatable do not affect the original.

repeat task.wait() until NEX_Loaded local clone = CloneReference(game) rawsetmetatable(clone, {}) print(rawgetmetatable(game) == rawgetmetatable(clone)) -- false

Accuracy: NEX Developed

ReplicateSignal(signal:RBXScriptSignal):null

Replicates server-sided RBXScriptSignals to the client.

repeat task.wait() until NEX_Loaded ReplicateSignal(game.Players.LocalPlayer.Kill)

Accuracy: NEX Developed

GetConnections(signal:RBXScriptSignal):table

Returns a table of all active RBXScriptConnection objects connected to the given signal.

repeat task.wait() until NEX_Loaded local conn = workspace.ChildAdded:Connect(function() end) local conns = GetConnections(workspace.ChildAdded) print("#connections:", #conns) conn:Disconnect()

Accuracy: NEX Developed

loadstring(str:string, chunkname:string?):function

Loads a Luau code string and returns it as a callable function. chunkname is used in error messages.

repeat task.wait() until NEX_Loaded local fn = loadstring("print('Hello from loadstring!')", "MyChunk") if fn then fn() end

Accuracy: NEX Developed

Runtime Variables

NEX_Loaded:boolean

Set to true in the script environment once NEX has finished injecting. Always wait for this before calling any NEX function.

repeat task.wait() until NEX_Loaded print("NEX is ready!")

Settings:table

A snapshot of the current NEX settings (same keys as Settings.json), updated on each injection pass.

repeat task.wait() until NEX_Loaded print(Settings.FilesEnabled) -- true/false print(Settings.CapabilityMax) -- e.g. 2 print(Settings.XMLEnabled) -- true/false

LoadedIcons:table

A table of loaded icon asset strings keyed by name. Always includes LoadedIcons.NEX.

repeat task.wait() until NEX_Loaded print(LoadedIcons.NEX) -- rbxasset://... URL for the NEX icon

_NEXVERSION:string

The currently running NEX version string.

repeat task.wait() until NEX_Loaded print(_NEXVERSION) -- "1.0.9"

Compiling

NEX scans the Lua registry on startup (and again whenever UpdateNEX is called) and injects the NEX environment into every eligible Luau thread it finds. This scan is called nexify. The behaviour for a given thread is controlled by a set of special boolean flags that a script sets on its own environment before NEX runs.

Setting these flags tells NEX how to treat the script — whether to skip it entirely, inject the standard renv, or switch it to the low-level NEXLuau API. All flags are checked during the nexify pass; they have no effect after injection has already occurred for that thread.

Environment Flags

Protected_Environment:boolean

When set to true in a script's environment, NEX will completely skip that thread during injection. No NEX functions, no NEX_Loaded, nothing. The script runs as a plain Roblox Luau script with no emulator involvement.

If Settings.DebugMode is on, or if ForceDebuggedEnvironment is also set on the same environment, NEX prints a warning: "{script} IS PROTECTED".

Use this to opt a script out of NEX entirely — useful for utility modules that must run in a clean Roblox environment and must not have their globals overwritten.

Example

-- At the very top of your script, before any yields, -- so NEX sees the flag during the nexify pass. local env = getfenv() env.Protected_Environment = true -- NEX will never touch this thread. -- Standard Roblox globals only from here on. print(game.Name)

NEXLuau:boolean

Opts the script into NEXLuau mode — a low-level C-style API surface inspired by C++ standard library naming. When NEX sees this flag it redirects the script environment's __index metamethod to the global nexenv table instead of the normal Roblox environment.

The practical effects are:

1. All NEX renv functions (normally injected directly into the script's environment) are instead placed into nexenv.std.NEXFunctions. They are still accessible because nexenv.std.NEXFunctions is the effective __index target for global lookups.

2. NEX_Loaded is set on the shared nexenv table rather than on the individual script environment.

3. The script gains access to the full nexenv.std namespace directly by name — for example, cout(...) instead of print(...).

nexenv.std — The NEXLuau Standard Library

All names below are accessible directly as globals inside a NEXLuau script.

NameMaps toDescription
coutprintStandard output.
coutwwarnStandard warning output.
throwerrorRaises an error.
dictinextDictionary iterator — the raw next function for generic for loops.
tickos.clockReturns the CPU time in seconds.
sleeptask.waitYields the current thread.
tasktaskThe Roblox task library.
ososThe Luau os library.
mathmathThe Luau math library.
stringstringThe Luau string library.
tabletableThe Luau table library.
threadscoroutineThe Luau coroutine library.
randomRandomThe Roblox Random class constructor.
luaL_dostringloadstringCompiles a string as a Luau chunk and returns it as a function.
call.protectedpcallProtected call.
call.extended_protectedxpcallExtended protected call with a message handler.
convert.tonumbertonumberString/value to number conversion.
convert.tostringtostringValue to string conversion.
types.luatypetypeReturns the Lua type of a value.
types.luautypetypeofReturns the Roblox/Luau type of a value.
functiondebug.infodebug.infoInspects functions or call stack frames.
functiondebug.getenvironmentgetfenvReturns the environment of a function.
luadebug.lua_registrygetreg()A snapshot of the Lua registry captured at emulator startup.
tabledebug.__lenrawlenGets the raw length of a table, bypassing __len.
tabledebug.__indexrawgetGets a table field, bypassing __index.
tabledebug.__newindexrawsetSets a table field, bypassing __newindex.
tabledebug.__equalrawequalCompares two values without metamethods.
tabledebug.setmetatablesetmetatableStandard setmetatable.
tabledebug.getmetatablegetmetatableStandard getmetatable.
tabledebug.__metatable.rawgetmetatablegetrawmetatableGets the raw metatable, bypassing __metatable protection.
tabledebug.__metatable.rawsetmetatablesetrawmetatableSets the raw metatable, bypassing protection.
globals.globalenvironment_GThe Luau global environment table.
globals.sharedenvironmentsharedThe Roblox shared table.

nexenv.std.RobloxObjects

The RobloxObjects sub-table exposes Roblox datatype constructors that are normally in the global scope. Game is wrapped in an isolated cloneref with a blank metatable so changes to it don't leak back to the real game service.

NameRoblox type
RobloxObjects.Gamegame (isolated cloneref)
RobloxObjects.InstanceInstance
RobloxObjects.Color3Color3
RobloxObjects.EnumEnum
RobloxObjects.Vector3Vector3
RobloxObjects.Vector2Vector2
RobloxObjects.CFrameCFrame
RobloxObjects.UDim2UDim2
RobloxObjects.UDimUDim
RobloxObjects.FontFont
RobloxObjects.TweenInfoTweenInfo
RobloxObjects.RaycastParamsRaycastParams
RobloxObjects.OverlapParamsOverlapParams
RobloxObjects.PhysicalPropertiesPhysicalProperties
RobloxObjects.Path2DControlPointPath2DControlPoint
RobloxObjects.RotationCurveKeyRotationCurveKey

nexenv top-level fields

In addition to nexenv.std, the following fields sit on nexenv itself and are visible as globals inside a NEXLuau script.

NameDescription
taskThe Roblox task library (also in std; provided at both levels for convenience).
__indexThe raw Instance __index method captured by NEX.
__newindexThe raw Instance __newindex method captured by NEX.
NEX_LoadedSet to true once NEX has injected. In NEXLuau mode this lives on nexenv rather than on the individual script environment.

Example

-- Tell NEX this is a NEXLuau script local env = getfenv() env.NEXLuau = true -- Wait for injection (NEX_Loaded is on nexenv, still visible as a global) repeat sleep(0) until NEX_Loaded -- Use the NEXLuau stdlib cout("Hello from NEXLuau!") -- print coutw("This is a warning") -- warn local ok, err = call.protected(function() throw("oops") -- error end) coutw("Caught:", err) -- Access Roblox datatypes local part = RobloxObjects.Instance.new("Part") part.Size = RobloxObjects.Vector3.new(4, 1, 2) part.Parent = RobloxObjects.Game.Workspace -- Low-level table access local t = {10, 20, 30} cout(tabledebug.__len(t)) -- 3 cout(tabledebug.__index(t, 2)) -- 20 -- Compile and run a string at runtime local chunk = luaL_dostring("return 1 + 1") cout(chunk()) -- 2 -- type checking cout(types.luatype(part)) -- "userdata" cout(types.luautype(part)) -- "Instance"

ExternalThread:boolean

Marks the thread as external — meaning it originated outside of the normal Roblox script context (for example, a thread spawned directly by an executor). When NEX detects this flag during nexify it performs a thread re-spawn:

1. The thread is cancelled with task.cancel.

2. NEX yields one frame with task.wait().

3. The same thread coroutine is re-spawned with task.spawn.

This re-spawn happens after the renv has already been injected into the thread's environment, so the thread resumes with full NEX globals available from the very first line. If Settings.DebugMode is on, NEX logs "{script} is EXTERNAL".

ExternalThread is independent of NEXLuau — both flags can be set together.

Example

local env = getfenv() env.ExternalThread = true -- After NEX re-spawns this thread, NEX_Loaded is already true. repeat task.wait() until NEX_Loaded print("Running as an external thread with NEX globals loaded.")

ForceDebuggedEnvironment:boolean

Forces NEX to emit debug log messages for this specific script regardless of the global Settings.DebugMode value. Two messages may be printed:

— If Protected_Environment is also set: "{script} IS PROTECTED"

— After successful injection: "NEX LOADED IN {script}"

Use this for per-script injection diagnostics without enabling global DebugMode (which would flood the console from every script).

Example

local env = getfenv() env.ForceDebuggedEnvironment = true -- NEX will print "NEX LOADED IN <script>" even if DebugMode is false. repeat task.wait() until NEX_Loaded print("Loaded with per-script debug logging.")

Injection Flow

The diagram below shows the exact decision tree NEX follows for each thread during a nexify pass. Every thread is visited at most once per pass (tracked via an internal seen-table).

nexify() └─ for each thread in the Lua registry ├─ already seen this pass? → skip ├─ env metatable is read-only? → skip (abnormal/protected system thread) │ └─ DebugMode: warn "abnormal thread" └─ env.Protected_Environment == true? ├─ YES → skip injection entirely │ └─ DebugMode or ForceDebuggedEnvironment: warn "{script} IS PROTECTED" └─ NO → proceed ├─ env.NEXLuau == true? │ ├─ YES → set env.__index = nexenv │ │ target = nexenv.std.NEXFunctions (renv goes here) │ │ nexenv.NEX_Loaded = true │ └─ NO → target = env │ env.NEX_Loaded = true ├─ inject all renv functions → target ├─ env.ExternalThread == true? │ └─ task.cancel(thread) → task.wait() → task.spawn(thread) │ └─ DebugMode: warn "{script} is EXTERNAL" └─ DebugMode or ForceDebuggedEnvironment: warn "NEX LOADED IN {script}"

Flag Combinations

Flags setBehaviour
noneStandard injection — renv globals written directly into the script environment.
NEXLuauNEXLuau mode — env __index redirected to nexenv; renv placed in nexenv.std.NEXFunctions.
ExternalThreadStandard injection + thread is cancelled and re-spawned after globals are set.
NEXLuau + ExternalThreadNEXLuau mode with a re-spawned thread.
Protected_EnvironmentNo injection at all. Script runs as vanilla Roblox Luau.
Protected_Environment + ForceDebuggedEnvironmentNo injection, but logs "IS PROTECTED" to console.
ForceDebuggedEnvironmentStandard injection with a per-script "NEX LOADED IN" console message.

Settings

Lua accessibility for settings

repeat task.wait() until NEX_Loaded print(Settings["Setting"])

Settings are persisted in GameData/<rootPlaceId>/Settings.json and the global StarterSettings.json. On first run or after a version update, missing keys are auto-populated from defaults.

CapabilityMax:number

The maximum identity level scripts may pass to setidentity. Default: 2. Increasing this allows emulated scripts to elevate privilege further.

FilesEnabled:boolean

Master switch for all sandboxed file functions. Default: true. When false, all file APIs warn and return nothing.

EmulateOnGameIsLoaded:boolean

When true (default), NEX waits for game:IsLoaded() before starting injection. Set to false to inject immediately.

HTTPEnabled:boolean

Master switch for all HTTP functions including request, requests.*, and NEXHttp.*. Default: true.

XMLEnabled:boolean

Enables XML-based instance creation via roblox.XML.Object and roblox.XML.Load. Default: true. Disabling prevents any XML deserialization.

RobloxScriptRequire:boolean

When true (default), exposes the Roblox environment's native require as Rrequire. When false, a stub warning function is exposed instead.

ExternalFilePerms:boolean

When true, populates the ExternalFileFunctions table with raw, unsandboxed exploit file functions. Default: false. These are not restricted to the game storage directory.

DebugMode:boolean

Enables verbose warn() output during injection, reporting protected threads, external threads, and successful NEX loads. Default: false.

Roblox Binary Format

This tab documents the Roblox binary model format (.rbxm / .rbxl) — the on-disk representation of Roblox instance trees. NEX uses this format internally when converting between XML and binary via BinaryFormat.XMLToBinary / BinaryFormat.BinaryToXML, and detects it via the magic bytes checked by roblox.BinaryFormat.XMLType.

Binary files begin with 3C 72 6F 62 6C 6F 78 21 89 FF 0D 0A 1A 0A — the ASCII string <roblox! followed by four special framing bytes. NEX's type detector checks only for the <roblox! prefix (8 bytes) to distinguish binary from XML.

File Header

Every binary file begins with a fixed 32-byte header before any chunks.

OffsetSizeTypeDescription
0x008 bytesASCIIMagic signature: <roblox!
0x086 bytesbytesFraming bytes: 89 FF 0D 0A 1A 0A
0x0E2 bytesuint16 LEFile format version (currently 0)
0x104 bytesint32 LENumber of unique instance classes in the file
0x144 bytesint32 LETotal number of instances across all classes
0x188 bytesreservedAlways zero — reserved for future use

Chunk Structure

After the header, the file is a sequence of self-describing chunks. Each chunk carries its own name, sizes, and payload. Chunks repeat until an END· chunk is reached.

OffsetSizeTypeDescription
+04 bytesASCIIChunk type tag, e.g. INST, PROP, PRNT
+44 bytesint32 LECompressed payload size. 0 = data is stored uncompressed.
+84 bytesint32 LEUncompressed (logical) size in bytes
+124 bytesreservedAlways zero
+16variesbytesPayload — LZ4-compressed if compressed size > 0, otherwise raw
Compression: When the compressed size field is non-zero, the payload is LZ4 block-compressed. Decompress to the declared uncompressed size before parsing. When compressed size is 0, the payload length equals the uncompressed size and is stored verbatim.

Chunk Types

META Metadata

Stores arbitrary key-value string pairs (e.g. the Studio version that exported the file). Usually the first chunk present.

uint32 entry_count for each entry: string key (uint32 length + UTF-8 bytes) string value (uint32 length + UTF-8 bytes)

SSTR Shared Strings

A deduplicated pool of binary blobs referenced by SharedString properties. Properties store only a 16-byte MD5 hash; the actual data lives here.

uint32 version (always 0) uint32 entry_count for each entry: bytes[16] md5_hash (raw 16-byte digest, used as lookup key) string data (uint32 length + raw bytes)

INST Instance Class Declaration

Declares all instances of a single class and assigns them a local numeric Class ID used throughout the file. One chunk per unique class name.

int32 class_id (0-based index for this chunk) string class_name (uint32 length + bytes) uint8 is_service (1 if this class is a Roblox service) int32 instance_count int32[] referents (interleaved zigzag delta-encoded; one per instance) -- if is_service == 1, also: string[] service_names (one per instance)

PROP Property Values

Stores values for one property across all instances of one class. One chunk per (class, property) pair.

int32 class_id (matches a previously declared INST class_id) string property_name (uint32 length + bytes) uint8 type_id (see Property Type IDs table) <array of N values — one per instance in the class, type-specific encoding>

PRNT Parent Relationships

Declares the entire parent-child tree. Covers every instance in the file in one chunk.

uint8 version (always 0) int32 instance_count int32[] child_referents (interleaved zigzag delta-encoded) int32[] parent_referents (interleaved zigzag delta-encoded; -1 = root / no parent)

END· End of File

Marks the end of all chunks. The payload is always the 9-byte ASCII string </roblox>. No chunks follow.

Data Encodings

Roblox uses several non-obvious encoding strategies to improve LZ4 compression ratios across the bulk data arrays.

Length-Prefixed Strings

All strings are stored as a little-endian uint32 byte-count followed immediately by the raw bytes. There is no null terminator.

uint32 length -- number of bytes that follow bytes data -- `length` raw bytes (UTF-8 or binary)

Interleaved Integer Arrays

Arrays of int32 values use a byte-interleaving scheme: all first bytes of each integer are stored together, then all second bytes, and so on. This groups similar bytes together, dramatically improving compression of correlated data like referent sequences.

-- Given N int32 values → 4*N bytes stored as: -- byte[0], byte[0+N], byte[0+2N], byte[0+3N], -- byte[1], byte[1+N], byte[1+2N], byte[1+3N], ... -- (i.e. byte columns first, not rows)

After de-interleaving, each integer is also zigzag-decoded: the raw bytes encode the value with the sign bit rotated to the least-significant position, keeping small-magnitude integers (positive and negative) small in binary.

-- Zigzag decode: value = (raw_uint32 >> 1) XOR -(raw_uint32 AND 1) -- Positive N encodes as 2*N, negative N as 2*(-N) - 1

Referent Delta Encoding

Referent arrays (instance IDs in INST and PRNT chunks) are additionally delta-encoded before interleaving. Each stored value is the difference from the previous referent, not the absolute ID. The first value is stored as-is. Since instances are usually assigned sequential IDs, deltas are almost always +1, yielding near-perfect compression.

-- Encoding: prev = 0 for i = 1 to N: delta = referent[i] - prev store zigzag(delta) prev = referent[i] -- Decoding: prev = 0 for i = 1 to N: referent[i] = prev + zigzag_decode(raw[i]) prev = referent[i]

Interleaved Float Arrays

Arrays of float32 values use the same byte-interleaving, but with a sign-bit rotation rather than zigzag. The sign bit is rotated to the least-significant position so that floats near zero (common for positions) pack tightly into few distinct byte values.

-- Encoding (rotate float bits left by 1): bits = reinterpret_cast<uint32>(float_value) stored = (bits << 1) | (bits >> 31) -- rotate left -- Decoding (rotate right by 1): bits = (stored >> 1) | ((stored & 1) << 31) value = reinterpret_cast<float>(bits)

Property Type IDs

The type_id byte in each PROP chunk identifies the encoding of the value array. Key type IDs:

IDNameEncoding
0x01StringArray of length-prefixed strings
0x02BoolArray of uint8 (0 or 1)
0x03Int32Interleaved zigzag int32 array
0x04FloatInterleaved sign-rotated float32 array
0x05DoubleArray of raw little-endian float64
0x06UDimInterleaved Scale floats then Offset int32s
0x07UDim2Interleaved ScaleX/ScaleY floats, then OffsetX/OffsetY int32s
0x08RayInterleaved: origin XYZ + direction XYZ float arrays
0x09FacesArray of uint8 bitfield (Right=1, Top=2, Back=4, Left=8, Bottom=16, Front=32)
0x0AAxesArray of uint8 bitfield (X=1, Y=2, Z=4)
0x0BBrickColorInterleaved int32 palette index array
0x0CColor3Interleaved R, G, B float arrays
0x0DVector2Interleaved X, Y float arrays
0x0EVector3Interleaved X, Y, Z float arrays
0x10CFramePer-value rotation ID byte + optional 9-float matrix; then interleaved X/Y/Z position floats for all values (see below)
0x12Enum / tokenInterleaved uint32 array (enum integer value)
0x13RefInterleaved delta-encoded referent array; -1 = null reference
0x14Vector3int16Three raw int16 LE per value (X, Y, Z)
0x15NumberSequenceuint32 keypoint count, then (time, value, envelope) float triples
0x16ColorSequenceuint32 keypoint count, then (time, R, G, B, 0) float tuples
0x17NumberRangeTwo raw float32 LE (min, max)
0x18Rect2DInterleaved MinX, MinY, MaxX, MaxY float arrays
0x19PhysicalPropertiesuint8 custom flag; if 1, five raw float32 LE follow (density, friction, elasticity, frictionWeight, elasticityWeight)
0x1AColor3uint8Three bytes per value: R, G, B (0–255, stored as packed uint32 internally: 0xFF000000 + R*65536 + G*256 + B)
0x1BInt64Interleaved zigzag int64 array
0x1CSharedStringInterleaved uint32 index array into the SSTR pool
0x1EUniqueIdInterleaved arrays: random int32, time int32, index int32
0x1FFontLength-prefixed string (family URL) + uint16 weight + uint8 style

CFrame Special Encoding

CFrame values receive extra treatment because their rotation can often be described by a single lookup-table index rather than a full 9-component matrix. This saves space for axis-aligned objects, which are the majority of parts in most games.

-- For each of N CFrame values: uint8 rotation_id if rotation_id == 0: float32[9] rotation_matrix (raw little-endian, NOT interleaved) -- else: rotation is looked up from a 36-entry canonical table -- After all per-value rotation data: float32[] X (interleaved sign-rotated, all N values) float32[] Y (interleaved sign-rotated, all N values) float32[] Z (interleaved sign-rotated, all N values)

The 36 canonical orientations (IDs 2–36) cover all possible axis-aligned CFrame rotations used for snapped parts. ID 0x02 is the identity rotation. ID 0 means a custom non-axis-aligned rotation follows inline as a raw 9-float matrix.

Deserialization Pipeline in NEX

When NEX loads a Roblox asset or local file that may be in binary format, the following pipeline is used:

1. Receive raw data string (from local file, HTTP, or asset delivery CDN) 2. Detect format: roblox.BinaryFormat.XMLType(data) → "binary" → roblox.BinaryFormat.BinaryToXML(data) returns equivalent XML string → "xml" → use data directly (optionally FixStudioXML first) → "unknown" → error / unsupported 3. Deserialize: SerializationService:DeserializeInstancesAsync( buffer.fromstring(xmlString) ) returns a table of root Instances 4. Optional Studio-export fix (for GetLocalObjects and GetObjects): roblox.BinaryFormat.FixStudioXML(xml) patches: Workspace class → Model Terrain class → Folder
Why convert to XML first? Roblox's SerializationService:DeserializeInstancesAsync accepts both formats via a buffer, but NEX's BinaryFormat layer provides a Luau-level round-trip, enabling inspection and modification of the data as a table structure via roblox.XML.XMLToTable before materializing into live instances.

XML ↔ Binary Type Correspondence

NEX's internal typemap handles encoding and decoding of every Roblox value type between XML tag format and binary. The same map drives both roblox.XML.TableToXML and the binary serializer's type dispatch:

XML TagBinary Type IDNotes
Vector30x0EX/Y/Z as <X><Y><Z> tags; interleaved floats in binary
Vector20x0DX/Y tags; interleaved floats
Vector3int160x14X/Y/Z integer tags; raw int16 LE triplets in binary
Vector2int16X/Y integer tags; stored as Vector2 variant
CFrame / CoordinateFrame0x1012 component tags (X,Y,Z,R00–R22); rotation ID + optional matrix + interleaved position in binary
UDim0x06<S> scale, <O> offset; interleaved separately
UDim20x07<XS><XO><YS><YO>; four interleaved arrays
Rect2D0x18<min><max> with X/Y; interleaved float arrays
Color30x0C<R><G><B> float tags; interleaved float arrays
Color3uint80x1APacked as uint32 (0xFF000000+R*65536+G*256+B) in XML; three bytes per value in binary
NumberRange0x17Space-separated "min max" string; two raw float32 in binary
NumberSequence0x15Space-separated "t v e" triples; count + float array in binary
ColorSequence0x16Space-separated "t R G B 0" tuples; count + float array (trailing 0 preserved)
PhysicalProperties0x19Five float tags or "null"; flag byte + optional floats in binary
Faces0x09Integer bitfield in both formats (Right=1, Top=2, Back=4, Left=8, Bottom=16, Front=32)
Axes0x0AInteger bitfield (X=1, Y=2, Z=4)
BinaryString / ProtectedString0x01CDATA in XML; length-prefixed bytes in binary
SharedString0x1CMD5 key string in XML; SSTR pool index in binary
Ref0x13"null" string in XML; -1 sentinel in binary; referent strings remapped to NEX1/NEX2/… on TableToXML
token (Enum)0x12Integer value in both formats; rounded to nearest integer on encode
bool0x02"true"/"false" string in XML; uint8 0/1 in binary
int / int640x03 / 0x1BInteger string in XML; interleaved zigzag array in binary
float / double0x04 / 0x05Float string in XML; interleaved rotated float32 or raw float64 in binary
UniqueId0x1EHex string in XML; three interleaved int32 arrays in binary