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
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
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
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
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
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
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
Accuracy: NEX Developed
ToastNotify(options:table):null
Sends a native toast notification via GuiService:SendNotification. Accepts Title, Text, and Icon fields.
Example Usage
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
Accuracy: NEX Developed
Rrequire(ModuleScript:ModuleScript):any
Exposes the native Roblox environment require function directly, allowing emulated scripts to load RobloxScript modules from protected locations like CorePackages.
Example Usage
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
Accuracy: NEX Developed
roblox.DownloadAsset(assetId:string, filename:string):null
Downloads the raw source of a Roblox asset and saves it to the game storage directory under filename.
Example Usage
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.
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.
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
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
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
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
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
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).
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
requests.post(url:string, options:table):table
requests.put(url:string, options:table):table
requests.patch(url:string, options:table):table
requests.delete(url:string, options:table):table
requests.options(url:string, options:table):table
Example Usage
Accuracy: NEX Developed
NEXHttp Namespace
NEXHttp.download(url:string, filename:string, chunksize:number?):table
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.
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
Accuracy: NEX Developed
NEXHttp.streamget(url:string, chunksize:number?):table
Streams the response body of a GET request in chunks without writing to disk. Accumulates into a body field on the returned state object.
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
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
Accuracy: NEX Developed
git.clone(url:string):null
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
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
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
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
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.
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
Accuracy: NEX Developed
readline(path:string, line:number):string
Reads a specific 1-indexed line from a file in storage.
Example Usage
Accuracy: NEX Developed
writeline(path:string, line:number, content:string):null
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
Accuracy: NEX Developed
typefile(path:string):string
Returns "file" or "folder" depending on what exists at path. Throws an error if the path doesn't exist.
Example Usage
Accuracy: NEX Developed
getcustomasset(filepath:string):string
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
Accuracy: NEX Developed
readfile(filepath:string):string
Reads and returns the content of a file in storage as a string.
Example Usage
Accuracy: NEX Developed
writefile(filepath:string, content:string):null
Writes a string to a file in storage, creating it if it does not exist.
makefolder(filepath:string):null
Creates a new folder at the given path in storage.
deletefile(filepath:string):null
Deletes a file from storage.
deletefolder(filepath:string):null
Deletes a folder and its contents from storage.
isfile(filepath:string):boolean
Returns true if a file exists at the path in storage.
isfolder(filepath:string):boolean
Returns true if a folder exists at the path in storage.
appendfile(filepath:string, content:string):null
Appends content to the end of a file in storage.
listfiles(filepath:string):table
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
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.
ExternalFileFunctions can read/write anywhere the executor can access. Enable ExternalFilePerms in Settings to populate this table.
Identity & Thread
setidentity(level:number):null
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
Accuracy: NEX Developed
getthreadidentity(null):number
Returns the current execution identity (privilege level) of the calling thread.
Example Usage
Accuracy: NEX Developed
HTTP
request(options:table):table
Performs an HTTP request using the options table. Returns a standard executor HTTP response with StatusCode, Body, Headers, Success, etc.
Example Usage
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.
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).
Accuracy: NEX Developed
clonefunction(func:function):function
Returns a cloned copy of a Luau function unaffected by later hookfunction calls on the original.
Accuracy: NEX Developed
hookfunction(original:function, hook:function):function
Replaces original with hook. Returns the original function.
Accuracy: NEX Developed
newcclosure(func:function):function
Wraps a Luau function in a C-closure, making it more resilient to certain forms of inspection.
Accuracy: NEX Developed
newlclosure(func:function, env:table):function
Creates a new Luau closure optionally bound to a custom environment table.
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.
Accuracy: NEX Developed
rawsetmetatable(target:userdata/table, mt:table):null
Sets the metatable for a table or userdata without triggering __metatable guards.
Accuracy: NEX Developed
rawgetmetatable(target:userdata/table):table
Retrieves the metatable of a table or userdata without triggering __metatable guards.
Accuracy: NEX Developed
GetRegisteredInstances(null):table
Returns a table containing references to most instances existing in Luau's internal registry state.
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.
Accuracy: NEX Developed
ReplicateSignal(signal:RBXScriptSignal):null
Replicates server-sided RBXScriptSignals to the client.
Accuracy: NEX Developed
GetConnections(signal:RBXScriptSignal):table
Returns a table of all active RBXScriptConnection objects connected to the given signal.
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.
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.
Settings:table
A snapshot of the current NEX settings (same keys as Settings.json), updated on each injection pass.
LoadedIcons:table
A table of loaded icon asset strings keyed by name. Always includes LoadedIcons.NEX.
_NEXVERSION:string
The currently running NEX version string.
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
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.
| Name | Maps to | Description |
|---|---|---|
| cout | Standard output. | |
| coutw | warn | Standard warning output. |
| throw | error | Raises an error. |
| dicti | next | Dictionary iterator — the raw next function for generic for loops. |
| tick | os.clock | Returns the CPU time in seconds. |
| sleep | task.wait | Yields the current thread. |
| task | task | The Roblox task library. |
| os | os | The Luau os library. |
| math | math | The Luau math library. |
| string | string | The Luau string library. |
| table | table | The Luau table library. |
| threads | coroutine | The Luau coroutine library. |
| random | Random | The Roblox Random class constructor. |
| luaL_dostring | loadstring | Compiles a string as a Luau chunk and returns it as a function. |
| call.protected | pcall | Protected call. |
| call.extended_protected | xpcall | Extended protected call with a message handler. |
| convert.tonumber | tonumber | String/value to number conversion. |
| convert.tostring | tostring | Value to string conversion. |
| types.luatype | type | Returns the Lua type of a value. |
| types.luautype | typeof | Returns the Roblox/Luau type of a value. |
| functiondebug.info | debug.info | Inspects functions or call stack frames. |
| functiondebug.getenvironment | getfenv | Returns the environment of a function. |
| luadebug.lua_registry | getreg() | A snapshot of the Lua registry captured at emulator startup. |
| tabledebug.__len | rawlen | Gets the raw length of a table, bypassing __len. |
| tabledebug.__index | rawget | Gets a table field, bypassing __index. |
| tabledebug.__newindex | rawset | Sets a table field, bypassing __newindex. |
| tabledebug.__equal | rawequal | Compares two values without metamethods. |
| tabledebug.setmetatable | setmetatable | Standard setmetatable. |
| tabledebug.getmetatable | getmetatable | Standard getmetatable. |
| tabledebug.__metatable.rawgetmetatable | getrawmetatable | Gets the raw metatable, bypassing __metatable protection. |
| tabledebug.__metatable.rawsetmetatable | setrawmetatable | Sets the raw metatable, bypassing protection. |
| globals.globalenvironment | _G | The Luau global environment table. |
| globals.sharedenvironment | shared | The 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.
| Name | Roblox type |
|---|---|
| RobloxObjects.Game | game (isolated cloneref) |
| RobloxObjects.Instance | Instance |
| RobloxObjects.Color3 | Color3 |
| RobloxObjects.Enum | Enum |
| RobloxObjects.Vector3 | Vector3 |
| RobloxObjects.Vector2 | Vector2 |
| RobloxObjects.CFrame | CFrame |
| RobloxObjects.UDim2 | UDim2 |
| RobloxObjects.UDim | UDim |
| RobloxObjects.Font | Font |
| RobloxObjects.TweenInfo | TweenInfo |
| RobloxObjects.RaycastParams | RaycastParams |
| RobloxObjects.OverlapParams | OverlapParams |
| RobloxObjects.PhysicalProperties | PhysicalProperties |
| RobloxObjects.Path2DControlPoint | Path2DControlPoint |
| RobloxObjects.RotationCurveKey | RotationCurveKey |
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.
| Name | Description |
|---|---|
| task | The Roblox task library (also in std; provided at both levels for convenience). |
| __index | The raw Instance __index method captured by NEX. |
| __newindex | The raw Instance __newindex method captured by NEX. |
| NEX_Loaded | Set to true once NEX has injected. In NEXLuau mode this lives on nexenv rather than on the individual script environment. |
Example
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
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
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).
Flag Combinations
| Flags set | Behaviour |
|---|---|
| none | Standard injection — renv globals written directly into the script environment. |
| NEXLuau | NEXLuau mode — env __index redirected to nexenv; renv placed in nexenv.std.NEXFunctions. |
| ExternalThread | Standard injection + thread is cancelled and re-spawned after globals are set. |
| NEXLuau + ExternalThread | NEXLuau mode with a re-spawned thread. |
| Protected_Environment | No injection at all. Script runs as vanilla Roblox Luau. |
| Protected_Environment + ForceDebuggedEnvironment | No injection, but logs "IS PROTECTED" to console. |
| ForceDebuggedEnvironment | Standard injection with a per-script "NEX LOADED IN" console message. |
Settings
Lua accessibility for settings
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.
File Header
Every binary file begins with a fixed 32-byte header before any chunks.
| Offset | Size | Type | Description |
|---|---|---|---|
| 0x00 | 8 bytes | ASCII | Magic signature: <roblox! |
| 0x08 | 6 bytes | bytes | Framing bytes: 89 FF 0D 0A 1A 0A |
| 0x0E | 2 bytes | uint16 LE | File format version (currently 0) |
| 0x10 | 4 bytes | int32 LE | Number of unique instance classes in the file |
| 0x14 | 4 bytes | int32 LE | Total number of instances across all classes |
| 0x18 | 8 bytes | reserved | Always 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.
| Offset | Size | Type | Description |
|---|---|---|---|
| +0 | 4 bytes | ASCII | Chunk type tag, e.g. INST, PROP, PRNT |
| +4 | 4 bytes | int32 LE | Compressed payload size. 0 = data is stored uncompressed. |
| +8 | 4 bytes | int32 LE | Uncompressed (logical) size in bytes |
| +12 | 4 bytes | reserved | Always zero |
| +16 | varies | bytes | Payload — LZ4-compressed if compressed size > 0, otherwise raw |
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.
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.
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.
PROP Property Values
Stores values for one property across all instances of one class. One chunk per (class, property) pair.
PRNT Parent Relationships
Declares the entire parent-child tree. Covers every instance in the file in one chunk.
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.
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.
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.
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.
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.
Property Type IDs
The type_id byte in each PROP chunk identifies the encoding of the value array. Key type IDs:
| ID | Name | Encoding |
|---|---|---|
| 0x01 | String | Array of length-prefixed strings |
| 0x02 | Bool | Array of uint8 (0 or 1) |
| 0x03 | Int32 | Interleaved zigzag int32 array |
| 0x04 | Float | Interleaved sign-rotated float32 array |
| 0x05 | Double | Array of raw little-endian float64 |
| 0x06 | UDim | Interleaved Scale floats then Offset int32s |
| 0x07 | UDim2 | Interleaved ScaleX/ScaleY floats, then OffsetX/OffsetY int32s |
| 0x08 | Ray | Interleaved: origin XYZ + direction XYZ float arrays |
| 0x09 | Faces | Array of uint8 bitfield (Right=1, Top=2, Back=4, Left=8, Bottom=16, Front=32) |
| 0x0A | Axes | Array of uint8 bitfield (X=1, Y=2, Z=4) |
| 0x0B | BrickColor | Interleaved int32 palette index array |
| 0x0C | Color3 | Interleaved R, G, B float arrays |
| 0x0D | Vector2 | Interleaved X, Y float arrays |
| 0x0E | Vector3 | Interleaved X, Y, Z float arrays |
| 0x10 | CFrame | Per-value rotation ID byte + optional 9-float matrix; then interleaved X/Y/Z position floats for all values (see below) |
| 0x12 | Enum / token | Interleaved uint32 array (enum integer value) |
| 0x13 | Ref | Interleaved delta-encoded referent array; -1 = null reference |
| 0x14 | Vector3int16 | Three raw int16 LE per value (X, Y, Z) |
| 0x15 | NumberSequence | uint32 keypoint count, then (time, value, envelope) float triples |
| 0x16 | ColorSequence | uint32 keypoint count, then (time, R, G, B, 0) float tuples |
| 0x17 | NumberRange | Two raw float32 LE (min, max) |
| 0x18 | Rect2D | Interleaved MinX, MinY, MaxX, MaxY float arrays |
| 0x19 | PhysicalProperties | uint8 custom flag; if 1, five raw float32 LE follow (density, friction, elasticity, frictionWeight, elasticityWeight) |
| 0x1A | Color3uint8 | Three bytes per value: R, G, B (0–255, stored as packed uint32 internally: 0xFF000000 + R*65536 + G*256 + B) |
| 0x1B | Int64 | Interleaved zigzag int64 array |
| 0x1C | SharedString | Interleaved uint32 index array into the SSTR pool |
| 0x1E | UniqueId | Interleaved arrays: random int32, time int32, index int32 |
| 0x1F | Font | Length-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.
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:
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 Tag | Binary Type ID | Notes |
|---|---|---|
| Vector3 | 0x0E | X/Y/Z as <X><Y><Z> tags; interleaved floats in binary |
| Vector2 | 0x0D | X/Y tags; interleaved floats |
| Vector3int16 | 0x14 | X/Y/Z integer tags; raw int16 LE triplets in binary |
| Vector2int16 | — | X/Y integer tags; stored as Vector2 variant |
| CFrame / CoordinateFrame | 0x10 | 12 component tags (X,Y,Z,R00–R22); rotation ID + optional matrix + interleaved position in binary |
| UDim | 0x06 | <S> scale, <O> offset; interleaved separately |
| UDim2 | 0x07 | <XS><XO><YS><YO>; four interleaved arrays |
| Rect2D | 0x18 | <min><max> with X/Y; interleaved float arrays |
| Color3 | 0x0C | <R><G><B> float tags; interleaved float arrays |
| Color3uint8 | 0x1A | Packed as uint32 (0xFF000000+R*65536+G*256+B) in XML; three bytes per value in binary |
| NumberRange | 0x17 | Space-separated "min max" string; two raw float32 in binary |
| NumberSequence | 0x15 | Space-separated "t v e" triples; count + float array in binary |
| ColorSequence | 0x16 | Space-separated "t R G B 0" tuples; count + float array (trailing 0 preserved) |
| PhysicalProperties | 0x19 | Five float tags or "null"; flag byte + optional floats in binary |
| Faces | 0x09 | Integer bitfield in both formats (Right=1, Top=2, Back=4, Left=8, Bottom=16, Front=32) |
| Axes | 0x0A | Integer bitfield (X=1, Y=2, Z=4) |
| BinaryString / ProtectedString | 0x01 | CDATA in XML; length-prefixed bytes in binary |
| SharedString | 0x1C | MD5 key string in XML; SSTR pool index in binary |
| Ref | 0x13 | "null" string in XML; -1 sentinel in binary; referent strings remapped to NEX1/NEX2/… on TableToXML |
| token (Enum) | 0x12 | Integer value in both formats; rounded to nearest integer on encode |
| bool | 0x02 | "true"/"false" string in XML; uint8 0/1 in binary |
| int / int64 | 0x03 / 0x1B | Integer string in XML; interleaved zigzag array in binary |
| float / double | 0x04 / 0x05 | Float string in XML; interleaved rotated float32 or raw float64 in binary |
| UniqueId | 0x1E | Hex string in XML; three interleaved int32 arrays in binary |