This is the full developer documentation for Conduit
# Conduit
> An external for Roblox, driven by a Lua API.
The whole surface
## One API, every layer of the game
Twenty-one namespaces, from raw memory up to the overlay you draw on. Here are the ones you will reach for first.
[memoryTyped reads and writes straight into live process memory.reference →](/reference/memory/)[robloxWalk the DataModel and touch any instance or property.reference →](/reference/roblox/)[entityA batched, always-fresh cache of every player on the map.reference →](/reference/entity/)[vmRun Luau against the game, live, this very frame.reference →](/reference/vm/)[eventsHook the frame loop and the place and character lifecycle.reference →](/reference/events/)[drawLines, text, and shapes on an external overlay.reference →](/reference/draw/)[chamsSee players through walls with programmable shaders.reference →](/reference/chams/)[physicsDrive the character: fly, teleport, rewrite its motion.reference →](/reference/physics/)[inputRead and synthesize mouse and keyboard through the kernel.reference →](/reference/input/)[httpRequests and responses, straight off the network.reference →](/reference/http/)[cryptHashing, base64, and real ciphers for your scripts.reference →](/reference/crypt/)[fileSandboxed reads and writes on the local disk.reference →](/reference/file/)
[21 namespaces, end to endEvery read, write, draw, and hook, documented with a runnable example.Open the reference →](/reference/memory/)
## See it run
[Section titled “See it run”](#see-it-run)
A box-and-name ESP over every enemy on the map, drawn on the external overlay and redrawn each frame. Nothing is injected into the game, and there is no in-game GUI.
conduit \~ esp.luaREADY
```lua
-- Outline every enemy and label them, once per frame.
local cyan = Color3.new(0.18, 0.83, 0.75)
cheat.Register("onPaint", function()
for _, player in pairs(entity.GetPlayers()) do
if player.IsEnemy and player.IsAlive then
local box = player.BoundingBox
draw.Rect(box.x, box.y, box.w, box.h, cyan, 1)
draw.Text(player.Name, box.x, box.y - 14, cyan, 13)
end
end
end)
```
This leans on three namespaces: [`entity`](/reference/entity/) for the players, [`draw`](/reference/draw/) for the overlay, and [`events`](/reference/events/) for the frame hook. [Getting Started](/guides/getting-started/) has you running your own in a couple of minutes.
# Core Concepts
> The model behind the Conduit API.
A short mental model makes the rest of the API predictable.
## Conduit is external
[Section titled “Conduit is external”](#conduit-is-external)
Conduit runs as its own process with its own Luau VM. Your scripts do not run inside Roblox. Instead, Conduit reads and writes the running game through remote memory, and the Lua API is the interface to all of it. This is why the API has a `memory` namespace and why reading instances goes through Conduit rather than a normal in-game script environment.
## Attach state
[Section titled “Attach state”](#attach-state)
Anything that touches the live game (the `memory` namespace and the `game` object model) requires Conduit to be attached to a running engine. Check it with `memory.IsEnabled` before you read, and calls will error clearly if no engine is attached.
## The workspace sandbox
[Section titled “The workspace sandbox”](#the-workspace-sandbox)
The `file` namespace is confined to a per-user workspace directory. Paths are relative to that directory, and attempts to escape it (absolute paths, `..`, or symlinks that leave the workspace) raise an error. This keeps script file access contained.
## The frame loop
[Section titled “The frame loop”](#the-frame-loop)
Scripts drive continuous behavior by registering event handlers with `cheat.Register`:
* `onUpdate` runs once per frame. Use it for logic that tracks the game.
* `onPaint` runs during the draw pass. Use it with the `draw` namespace to render overlays, matched to the client frame rate.
* Lifecycle events like `newPlace` and `characterAdded` let a script react to the player moving between places or respawning.
## Running scripts
[Section titled “Running scripts”](#running-scripts)
The `run` command executes a script and prints its output immediately. Loading a script without running it is silent by design. Keep prints intentional and throttled inside frame handlers, since they fire every frame.
# Getting Started
> Write and run your first Conduit script.
This walks through a first script, from a plain file write to reading live game state.
## Your first script
[Section titled “Your first script”](#your-first-script)
The simplest thing that proves the runtime works is a file round trip. The `file` namespace is sandboxed to a per-user workspace directory, so this is safe to run anywhere.
```lua
file.write("hello.txt", "conduit is running")
print(file.read("hello.txt"))
```
Run it with the `run` command. Output appears immediately. Loading a script on its own is silent; `run` is the path that prints.
## Reading the game
[Section titled “Reading the game”](#reading-the-game)
Most scripts read live game state. That needs Conduit attached to a running engine, which you can check with `memory.IsEnabled`. From there, `game` behaves like the Roblox DataModel and `roblox.FindFirst` locates a service or instance by class name.
```lua
if not memory.IsEnabled() then
return print("Conduit is not attached to a running engine")
end
local workspace = roblox.FindFirst("Workspace")
print(#workspace:GetChildren(), "objects in Workspace")
```
## Running every frame
[Section titled “Running every frame”](#running-every-frame)
To do work continuously, register a handler with `cheat.Register`. Use `onUpdate` for per-frame logic and `onPaint` for drawing to the overlay.
```lua
cheat.Register("onUpdate", function()
-- runs once per frame
end)
```
## Where to go next
[Section titled “Where to go next”](#where-to-go-next)
* [Core Concepts](/guides/core-concepts/) explains the model behind the API.
* The **API Reference** documents every namespace, each method with a signature and example. Good starting points are [`memory`](/reference/memory/), [`roblox`](/reference/roblox/), and [`draw`](/reference/draw/).
# Introduction
> What Conduit is and what these docs cover.
Conduit is an external for Roblox. It runs out of process with its own Luau VM, reads and writes the running game through remote memory, and exposes all of that to you as a Lua API. You write Lua scripts against that API and run them live.
These docs are the developer reference for that API. They cover every stable namespace, from process memory and the Roblox object model through drawing, physics, and entities, down to the datatypes, events, and globals the rest is built on.
## How to read these docs
[Section titled “How to read these docs”](#how-to-read-these-docs)
If you are new, [Getting Started](/guides/getting-started/) walks you through writing and running your first script, and [Core Concepts](/guides/core-concepts/) explains the model underneath. When you already know what you need, every namespace has its own page under **API Reference**, with each method’s signature and a runnable example.
## For AI-assisted development
[Section titled “For AI-assisted development”](#for-ai-assisted-development)
The entire reference is also published as machine-readable text at [`/llms.txt`](/llms.txt) (and a fuller [`/llms-full.txt`](/llms-full.txt)). Point your AI tooling at those files to give it the exact, current API surface.
# Connect with MCP
> Give any AI assistant live access to the Conduit docs through one MCP endpoint.
The Conduit docs are served as an MCP (Model Context Protocol) endpoint, so any AI assistant that speaks MCP can search and read them directly. It exposes two tools, `search` and `fetch`, backed by the same content this site renders, so it never goes stale.
**Endpoint:** `https://conduit-docs.vercel.app/mcp`
It is read-only, public, and stateless. No API key, no login.
## Claude Code
[Section titled “Claude Code”](#claude-code)
```sh
claude mcp add --transport http conduit-docs https://conduit-docs.vercel.app/mcp
```
## Cursor
[Section titled “Cursor”](#cursor)
Add to `.cursor/mcp.json` in your project (or the global one):
```json
{
"mcpServers": {
"conduit-docs": {
"url": "https://conduit-docs.vercel.app/mcp"
}
}
}
```
## VS Code
[Section titled “VS Code”](#vs-code)
Add to `.vscode/mcp.json` (note the top-level `servers` key):
```json
{
"servers": {
"conduit-docs": {
"type": "http",
"url": "https://conduit-docs.vercel.app/mcp"
}
}
}
```
## Claude Desktop and Windsurf
[Section titled “Claude Desktop and Windsurf”](#claude-desktop-and-windsurf)
These use a local bridge to reach a remote endpoint. Add to the MCP config:
```json
{
"mcpServers": {
"conduit-docs": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://conduit-docs.vercel.app/mcp"]
}
}
}
```
## ChatGPT
[Section titled “ChatGPT”](#chatgpt)
In a Deep Research or connector-enabled workspace, add a custom connector and paste the endpoint URL:
```plaintext
https://conduit-docs.vercel.app/mcp
```
The `search` and `fetch` tools follow the connector contract ChatGPT expects.
## No MCP client?
[Section titled “No MCP client?”](#no-mcp-client)
Every chatbot can still read the plain-text exports:
* [`/llms.txt`](/llms.txt) is a compact index of the whole site.
* [`/llms-full.txt`](/llms-full.txt) is the full docs in one file.
Paste either into any chat, or point a tool that accepts a URL at them.
# assets
> Play, stop, and query local audio files via a system media player, plus read Roblox Sound instance metadata.
## `audio`
[Section titled “audio”](#audio)
Play, stop, and query local audio files via a system media player, plus read Roblox Sound instance metadata.
### audio.Play
[Section titled “audio.Play”](#audioplay)
audio.Play(path: string, loop: boolean?, volume: number?, pitch: number?) -> (ok: boolean, pidOrError: number|string)
Plays a local file confined to the fs workspace through the first available system media player (mpv, ffplay, paplay, cvlc, or aplay), replacing any currently playing audio started this way.
```lua
local ok, pid = audio.Play("sounds/theme.mp3", true, 0.8, 1.0)
if not ok then print(pid) end
```
### audio.Stop
[Section titled “audio.Stop”](#audiostop)
audio.Stop() -> stopped: boolean
Terminates the audio player process started by audio.Play, if one is running.
```lua
audio.Stop()
```
### audio.IsPlaying
[Section titled “audio.IsPlaying”](#audioisplaying)
audio.IsPlaying() -> playing: boolean
Returns whether the audio player process started by audio.Play is still alive.
```lua
if audio.IsPlaying() then print("still playing") end
```
### audio.Metadata
[Section titled “audio.Metadata”](#audiometadata)
audio.Metadata(sound: Instance) -> table|nil
Reads a Roblox Sound instance’s SoundId, Volume, PlaybackSpeed, TimeLength, TimePosition, Looped, Playing, IsPaused, IsLoaded, and RollOffMaxDistance properties into a table, returning nil if the instance or engine handle is unavailable.
```lua
local meta = audio.Metadata(sound)
if meta then print(meta.SoundId, meta.Volume) end
```
Note
audio.Play/Stop/IsPlaying operate on a local file played through an external system media player (not the game’s own audio engine); audio.Metadata is the only method that reads a Roblox Sound Instance via the bridge.
## `font`
[Section titled “font”](#font)
Load custom fonts for the draw API and get or set the default font used for text rendering.
### font.Load
[Section titled “font.Load”](#fontload)
font.Load(path: string) -> any
Loads a font file by delegating to draw\.LoadFont and returns whatever draw\.LoadFont returns, or false if draw\.LoadFont is unavailable.
```lua
local handle = font.Load("fonts/Roboto-Regular.ttf")
```
### font.SetDefault
[Section titled “font.SetDefault”](#fontsetdefault)
font.SetDefault(path: string) -> boolean
Sets the default font path by writing it to settings under the key font, returns true on success or false if the settings table is unavailable.
```lua
local ok = font.SetDefault("fonts/Roboto-Regular.ttf")
```
### font.Get
[Section titled “font.Get”](#fontget)
font.Get() -> string | nil
Returns the current default font path read from settings, or nil if unavailable.
```lua
local current = font.Get()
```
Note
`font` is a thin convenience wrapper: `Load` calls [`draw.LoadFont`](/reference/draw/), and `SetDefault` and `Get` store and read the default font under a `font` key through [`settings`](/reference/settings/).
## `image`
[Section titled “image”](#image)
Load static images and GIFs from the confined workspace and draw or sample them.
### image.Load
[Section titled “image.Load”](#imageload)
image.Load(path: string) -> Image | nil, string?
Decodes an image file from the fs-confined workspace into an Image object, returning nil plus an error string on failure.
```lua
local img, err = image.Load("textures/logo.png")
if img then print(img.Width, img.Height) end
```
### image.LoadGif
[Section titled “image.LoadGif”](#imageloadgif)
image.LoadGif(path: string) -> Gif | nil, string?
Decodes a GIF file from the fs-confined workspace into a Gif object with all frames and per-frame delays, returning nil plus an error string on failure.
```lua
local gif, err = image.LoadGif("anim/spinner.gif")
if gif then print(gif.Frames) end
```
### Image.Width
[Section titled “Image.Width”](#imagewidth)
Image.Width: number
The pixel width of a loaded image.
```lua
local img = image.Load("a.png")
print(img.Width)
```
### Image.Height
[Section titled “Image.Height”](#imageheight)
Image.Height: number
Pixel height of a loaded Image.
```lua
local img = image.Load("a.png")
print(img.Height)
```
### Image.Size
[Section titled “Image.Size”](#imagesize)
Image.Size: Vector2
Width and height of the Image packed as a Vector2.
```lua
local img = image.Load("a.png")
print(img.Size)
```
### Image.Path
[Section titled “Image.Path”](#imagepath)
Image.Path: string
Resolved, confined filesystem path the Image was loaded from.
```lua
local img = image.Load("a.png")
print(img.Path)
```
### Image:GetPixel
[Section titled “Image:GetPixel”](#imagegetpixel)
Image:GetPixel(x: number, y: number) -> Color3, number | nil
Reads the color and alpha (0 to 1) of a 0-based pixel coordinate, returning nil if the coordinate is out of bounds.
```lua
local img = image.Load("a.png")
local color, alpha = img:GetPixel(0, 0)
```
### Image:Draw
[Section titled “Image:Draw”](#imagedraw)
Image:Draw(x: number, y: number, w: number?, h: number?, alpha: number?)
Draws the Image to the overlay at the given position, defaulting width, height and alpha to the image’s native size and full opacity; delegates to the global draw\.Image function.
```lua
local img = image.Load("a.png")
img:Draw(100, 100)
```
### Gif.Width
[Section titled “Gif.Width”](#gifwidth)
Gif.Width: number
Pixel width of a loaded Gif’s frames.
```lua
local gif = image.LoadGif("a.gif")
print(gif.Width)
```
### Gif.Height
[Section titled “Gif.Height”](#gifheight)
Gif.Height: number
Pixel height of a loaded Gif’s frames.
```lua
local gif = image.LoadGif("a.gif")
print(gif.Height)
```
### Gif.Frames
[Section titled “Gif.Frames”](#gifframes)
Gif.Frames: number
Total number of decoded frames in the Gif.
```lua
local gif = image.LoadGif("a.gif")
print(gif.Frames)
```
### Gif:Draw
[Section titled “Gif:Draw”](#gifdraw)
Gif:Draw(x: number, y: number, w: number?, h: number?, alpha: number?)
Draws the currently-due animation frame at the given position based on elapsed time since first draw, defaulting size to native and alpha to full opacity.
```lua
local gif = image.LoadGif("a.gif")
-- call every frame to animate
gif:Draw(50, 50)
```
Note
`image.Load` and `image.LoadGif` paths are confined to the Conduit workspace directory (no absolute or `..` paths). The `Image` and `Gif` values they return expose their fields as both properties and methods.
# chams
> Render occlusion-aware mesh overlays (chams) on MeshParts, with custom shader materials.
Render occlusion-aware mesh overlays (chams) on MeshParts, with custom shader materials.
### chams.RegisterMaterial
[Section titled “chams.RegisterMaterial”](#chamsregistermaterial)
chams.RegisterMaterial(name: string, source: { vertex: string, fragment: string }) -> ok: boolean, errorLog: string?
Compiles and registers a named GLSL material (vertex and fragment shader source) usable as the material option in chams.Apply, returning false plus a compile log on failure.
```lua
local ok, err = chams.RegisterMaterial("outline", { vertex = vsSource, fragment = fsSource })
if not ok then warn(err) end
```
### chams.Apply
[Section titled “chams.Apply”](#chamsapply)
chams.Apply(target: Instance, opts: { fill: Color3?, occludedFill: Color3?, alpha: number?, material: string?, occlusion: boolean?, uniforms: {\[string]: number|Color3|Vector3}? }) -> ()
Queues a chams overlay for the given Player, Character root, or MeshPart (and its MeshPart descendants) to be drawn this frame, using the fill colors, alpha (0-255), named material, optional through-wall occlusion, and optional shader uniforms in opts.
```lua
chams.Apply(player, { fill = Color3.new(1,0,0), occludedFill = Color3.new(0,0,1), alpha = 200, occlusion = true })
```
Note
Apply is meant to be called every frame (it is throttled/cached internally per Instance); it is a no-op if the overlay frame is not ready or the target has no live geometry yet. occludedFill defaults to fill; alpha defaults to 200; material defaults to “default”. Materials must be registered via RegisterMaterial before being referenced by name.
# cheat
> Meta namespace for registering event handlers and querying the game window/viewport size.
Meta namespace for registering event handlers and querying the game window/viewport size.
### cheat.Register
[Section titled “cheat.Register”](#cheatregister)
cheat.Register(eventName: string, handler: function): void
Registers a handler function to be called when the named event fires, erroring if the event name is not one of the known events.
```lua
cheat.Register("onUpdate", function() print("tick") end)
```
### cheat.GetWindowSize
[Section titled “cheat.GetWindowSize”](#cheatgetwindowsize)
cheat.GetWindowSize(): (number, number)
Returns the current game window viewport width and height in pixels, reading the Workspace Camera’s ViewportSize, or 0, 0 if unavailable.
```lua
local w, h = cheat.GetWindowSize()
print(w, h)
```
Note
Valid event names accepted by cheat.Register are: onUpdate, onSlowUpdate, onPaint, newPlace, characterAdded, characterRemoving, shutdown. These event names are documented separately, not part of this cheat-namespace method list.
# crypt
> Cryptographic primitives (hashing, HMAC, AES/ChaCha20/AEAD ciphers, Blake2b/Blake3, Ed25519/X25519, base64/hex, random bytes) exposed to scripts.
Cryptographic primitives (hashing, HMAC, AES/ChaCha20/AEAD ciphers, Blake2b/Blake3, Ed25519/X25519, base64/hex, random bytes) exposed to scripts.
## Hashing
[Section titled “Hashing”](#hashing)
### crypt.Hash
[Section titled “crypt.Hash”](#crypthash)
crypt.Hash(data: string, algo: string): string
Hashes data with the named algorithm (sha1, sha256, sha384, sha512, md5) and returns the digest as a hex string.
```lua
local h = crypt.Hash("hello", "sha256")
```
### crypt.HashToBuffer
[Section titled “crypt.HashToBuffer”](#crypthashtobuffer)
crypt.HashToBuffer(data: string, algo: string): string
Hashes data with the named algorithm and returns the raw binary digest instead of hex.
```lua
local raw = crypt.HashToBuffer("hello", "sha256")
```
### crypt.Hmac
[Section titled “crypt.Hmac”](#crypthmac)
crypt.Hmac(data: string, key: string, algo: string): string
Computes an HMAC over data with the given key and algorithm, returned as a hex string.
```lua
local mac = crypt.Hmac("msg", "secretkey", "sha256")
```
### crypt.HmacToBuffer
[Section titled “crypt.HmacToBuffer”](#crypthmactobuffer)
crypt.HmacToBuffer(data: string, key: string, algo: string): string
Computes an HMAC over data with the given key and algorithm, returned as raw binary.
```lua
local mac = crypt.HmacToBuffer("msg", "secretkey", "sha256")
```
### crypt.Blake2b
[Section titled “crypt.Blake2b”](#cryptblake2b)
crypt.Blake2b(data: string, key: string?, outLen: number?): string
Computes a keyed or unkeyed BLAKE2b hash of data, returning raw bytes of the requested length (clamped to libsodium’s min and max, default 32).
```lua
local digest = crypt.Blake2b("data")
```
### crypt.Blake3
[Section titled “crypt.Blake3”](#cryptblake3)
crypt.Blake3(data: string): string
Computes a 32 byte BLAKE3 hash of data and returns it as a hex string.
```lua
local h = crypt.Blake3("data")
```
### crypt.Blake3ToBuffer
[Section titled “crypt.Blake3ToBuffer”](#cryptblake3tobuffer)
crypt.Blake3ToBuffer(data: string): string
Computes a 32 byte BLAKE3 hash of data and returns it as raw binary.
```lua
local raw = crypt.Blake3ToBuffer("data")
```
### crypt.Blake3Keyed
[Section titled “crypt.Blake3Keyed”](#cryptblake3keyed)
crypt.Blake3Keyed(data: string, key: string): string
Computes a keyed 32 byte BLAKE3 hash of data (key zero-padded or truncated to 32 bytes) and returns it as a hex string.
```lua
local h = crypt.Blake3Keyed("data", key)
```
## Encoding
[Section titled “Encoding”](#encoding)
### crypt.Base64Encode
[Section titled “crypt.Base64Encode”](#cryptbase64encode)
crypt.Base64Encode(data: string): string
Encodes a string as standard base64.
```lua
local b64 = crypt.Base64Encode("hello")
```
### crypt.Base64Decode
[Section titled “crypt.Base64Decode”](#cryptbase64decode)
crypt.Base64Decode(data: string): string
Decodes a standard base64 string back to raw bytes.
```lua
local raw = crypt.Base64Decode(b64)
```
### crypt.HexEncode
[Section titled “crypt.HexEncode”](#crypthexencode)
crypt.HexEncode(data: string): string
Encodes a string as lowercase hexadecimal.
```lua
local hex = crypt.HexEncode("hello")
```
### crypt.HexDecode
[Section titled “crypt.HexDecode”](#crypthexdecode)
crypt.HexDecode(data: string): string
Decodes a hexadecimal string back to raw bytes.
```lua
local raw = crypt.HexDecode(hex)
```
## Random & keys
[Section titled “Random & keys”](#random--keys)
### crypt.Random
[Section titled “crypt.Random”](#cryptrandom)
crypt.Random(count: number): string
Returns count cryptographically random bytes as a string. Negative counts are clamped to 0.
```lua
local r = crypt.Random(16)
```
### crypt.GenerateKey
[Section titled “crypt.GenerateKey”](#cryptgeneratekey)
crypt.GenerateKey(): string
Generates 32 random bytes and returns them base64 encoded, suitable for use as a key.
```lua
local key = crypt.GenerateKey()
```
### crypt.GenerateBytes
[Section titled “crypt.GenerateBytes”](#cryptgeneratebytes)
crypt.GenerateBytes(count: number): string
Returns count cryptographically random bytes as a string. Negative counts are clamped to 0.
```lua
local b = crypt.GenerateBytes(24)
```
## Symmetric encryption
[Section titled “Symmetric encryption”](#symmetric-encryption)
### crypt.EncryptAesCbc
[Section titled “crypt.EncryptAesCbc”](#cryptencryptaescbc)
crypt.EncryptAesCbc(plaintext: string, key: string, iv: string): string
Encrypts plaintext with AES-CBC using a 16, 24 or 32 byte key and a 16 byte IV, returning raw ciphertext.
```lua
local ct = crypt.EncryptAesCbc("data", key16, iv16)
```
### crypt.DecryptAesCbc
[Section titled “crypt.DecryptAesCbc”](#cryptdecryptaescbc)
crypt.DecryptAesCbc(ciphertext: string, key: string, iv: string): string
Decrypts AES-CBC ciphertext using a 16, 24 or 32 byte key and a 16 byte IV, returning raw plaintext.
```lua
local pt = crypt.DecryptAesCbc(ct, key16, iv16)
```
### crypt.EncryptAesGcm
[Section titled “crypt.EncryptAesGcm”](#cryptencryptaesgcm)
crypt.EncryptAesGcm(plaintext: string, key: string, iv: string, aad: string?): (ciphertext: string, tag: string)
Encrypts plaintext with AES-GCM using the given key and non-empty IV and optional additional authenticated data, returning the ciphertext and a 16 byte auth tag.
```lua
local ct, tag = crypt.EncryptAesGcm("data", key32, iv12)
```
### crypt.DecryptAesGcm
[Section titled “crypt.DecryptAesGcm”](#cryptdecryptaesgcm)
crypt.DecryptAesGcm(ciphertext: string, key: string, iv: string, tag: string, aad: string?): string?
Decrypts AES-GCM ciphertext and verifies the auth tag, returning nil if the tag does not match (tampered or wrong key).
```lua
local pt = crypt.DecryptAesGcm(ct, key32, iv12, tag)
```
### crypt.Encrypt
[Section titled “crypt.Encrypt”](#cryptencrypt)
crypt.Encrypt(plaintext: string, base64Key: string): (base64Ciphertext: string, base64Iv: string)
Legacy AES-CBC helper that base64-decodes the key, pads or truncates it to 32 bytes, generates a random 16 byte IV, and returns base64 ciphertext and IV.
```lua
local ct, iv = crypt.Encrypt("data", crypt.GenerateKey())
```
### crypt.Decrypt
[Section titled “crypt.Decrypt”](#cryptdecrypt)
crypt.Decrypt(base64Ciphertext: string, base64Key: string, base64Iv: string): string
Legacy AES-CBC helper that base64-decodes ciphertext, key (padded or truncated to 32 bytes) and IV, and returns the raw plaintext.
```lua
local pt = crypt.Decrypt(ct, key, iv)
```
### crypt.ChaCha20
[Section titled “crypt.ChaCha20”](#cryptchacha20)
crypt.ChaCha20(data: string, key: string, nonce: string, counter: number?): string
Encrypts or decrypts data with the ChaCha20 stream cipher using a 32 byte key, a nonce (up to 12 bytes), and an optional initial block counter (default 0).
```lua
local out = crypt.ChaCha20("data", key32, nonce12)
```
### crypt.ChaCha20Poly1305Encrypt
[Section titled “crypt.ChaCha20Poly1305Encrypt”](#cryptchacha20poly1305encrypt)
crypt.ChaCha20Poly1305Encrypt(plaintext: string, key: string, nonce: string, aad: string?): string
Encrypts plaintext with ChaCha20-Poly1305 AEAD using a fixed size key and nonce and optional additional authenticated data, returning ciphertext with the tag appended.
```lua
local ct = crypt.ChaCha20Poly1305Encrypt("data", key32, nonce12)
```
### crypt.ChaCha20Poly1305Decrypt
[Section titled “crypt.ChaCha20Poly1305Decrypt”](#cryptchacha20poly1305decrypt)
crypt.ChaCha20Poly1305Decrypt(ciphertext: string, key: string, nonce: string, aad: string?): string?
Decrypts and verifies a ChaCha20-Poly1305 ciphertext (with appended tag), returning nil on authentication failure.
```lua
local pt = crypt.ChaCha20Poly1305Decrypt(ct, key32, nonce12)
```
## Signing & key exchange
[Section titled “Signing & key exchange”](#signing--key-exchange)
### crypt.Ed25519Keypair
[Section titled “crypt.Ed25519Keypair”](#crypted25519keypair)
crypt.Ed25519Keypair(): (publicKey: string, secretKey: string)
Generates a new Ed25519 keypair and returns the raw public and secret keys.
```lua
local pk, sk = crypt.Ed25519Keypair()
```
### crypt.Ed25519Sign
[Section titled “crypt.Ed25519Sign”](#crypted25519sign)
crypt.Ed25519Sign(message: string, secretKey: string): string
Signs a message with an Ed25519 secret key and returns the detached signature.
```lua
local sig = crypt.Ed25519Sign("msg", sk)
```
### crypt.Ed25519Verify
[Section titled “crypt.Ed25519Verify”](#crypted25519verify)
crypt.Ed25519Verify(message: string, signature: string, publicKey: string): boolean
Verifies an Ed25519 detached signature against a message and public key.
```lua
local ok = crypt.Ed25519Verify("msg", sig, pk)
```
### crypt.X25519Keypair
[Section titled “crypt.X25519Keypair”](#cryptx25519keypair)
crypt.X25519Keypair(): (publicKey: string, secretKey: string)
Generates a new X25519 keypair for elliptic curve Diffie-Hellman and returns the raw public and secret keys.
```lua
local pk, sk = crypt.X25519Keypair()
```
### crypt.X25519SharedSecret
[Section titled “crypt.X25519SharedSecret”](#cryptx25519sharedsecret)
crypt.X25519SharedSecret(secretKey: string, peerPublicKey: string): string?
Computes the X25519 shared secret from your secret key and a peer’s public key, returning nil on failure.
```lua
local shared = crypt.X25519SharedSecret(sk, peerPk)
```
Note
All string parameters are treated as raw byte buffers (Lua strings), not necessarily printable text. crypt.Encrypt/crypt.Decrypt are legacy helpers kept for backward compatibility with weaker key handling (short keys are NUL-padded); prefer EncryptAesCbc/EncryptAesGcm or ChaCha20Poly1305 for new code.
# datatypes
> Roblox-mirror value types (Vector3, CFrame, Color3, UDim2, Enum, BrickColor, and more), with the same constructors, properties, methods, and operators you know from Roblox.
Roblox-mirror value types (Vector3, CFrame, Color3, UDim2, Enum, BrickColor, and more), with the same constructors, properties, methods, and operators you know from Roblox.
## Vector3
[Section titled “Vector3”](#vector3)
### Vector3.new
[Section titled “Vector3.new”](#vector3new)
Vector3.new(x: number?, y: number?, z: number?) -> Vector3
Constructs a Vector3, defaulting any omitted component to 0.
```lua
local v = Vector3.new(1, 2, 3)
```
### Vector3.zero
[Section titled “Vector3.zero”](#vector3zero)
Vector3.zero -> Vector3
Static Vector3(0, 0, 0).
```lua
local v = Vector3.zero
```
### Vector3.one
[Section titled “Vector3.one”](#vector3one)
Vector3.one -> Vector3
Static Vector3(1, 1, 1).
```lua
local v = Vector3.one
```
### Vector3.xAxis
[Section titled “Vector3.xAxis”](#vector3xaxis)
Vector3.xAxis -> Vector3
Static Vector3(1, 0, 0).
```lua
local v = Vector3.xAxis
```
### Vector3.yAxis
[Section titled “Vector3.yAxis”](#vector3yaxis)
Vector3.yAxis -> Vector3
Static Vector3(0, 1, 0).
```lua
local v = Vector3.yAxis
```
### Vector3.zAxis
[Section titled “Vector3.zAxis”](#vector3zaxis)
Vector3.zAxis -> Vector3
Static Vector3(0, 0, 1).
```lua
local v = Vector3.zAxis
```
### Vector3.X/Y/Z
[Section titled “Vector3.X/Y/Z”](#vector3xyz)
vec.X, vec.Y, vec.Z -> number
Read-only component accessors.
```lua
print(v.X, v.Y, v.Z)
```
### Vector3.Magnitude
[Section titled “Vector3.Magnitude”](#vector3magnitude)
vec.Magnitude -> number
Vector length.
```lua
print(v.Magnitude)
```
### Vector3.Unit
[Section titled “Vector3.Unit”](#vector3unit)
vec.Unit -> Vector3
Normalized copy of the vector, zero-length vectors return the zero vector unchanged.
```lua
local u = v.Unit
```
### Vector3:Dot
[Section titled “Vector3:Dot”](#vector3dot)
vec:Dot(other: Vector3) -> number
Dot product of two vectors.
```lua
local d = v:Dot(Vector3.new(0,1,0))
```
### Vector3:Cross
[Section titled “Vector3:Cross”](#vector3cross)
vec:Cross(other: Vector3) -> Vector3
Cross product of two vectors.
```lua
local c = v:Cross(Vector3.new(0,1,0))
```
### Vector3:Lerp
[Section titled “Vector3:Lerp”](#vector3lerp)
vec:Lerp(goal: Vector3, alpha: number) -> Vector3
Linear interpolation between two vectors.
```lua
local m = a:Lerp(b, 0.5)
```
### Vector3:Abs
[Section titled “Vector3:Abs”](#vector3abs)
vec:Abs() -> Vector3
Component-wise absolute value.
```lua
local a = v:Abs()
```
### Vector3:Ceil
[Section titled “Vector3:Ceil”](#vector3ceil)
vec:Ceil() -> Vector3
Component-wise ceiling.
```lua
local c = v:Ceil()
```
### Vector3:Floor
[Section titled “Vector3:Floor”](#vector3floor)
vec:Floor() -> Vector3
Component-wise floor.
```lua
local f = v:Floor()
```
### Vector3:Sign
[Section titled “Vector3:Sign”](#vector3sign)
vec:Sign() -> Vector3
Component-wise sign (-1, 0, or 1).
```lua
local s = v:Sign()
```
### Vector3:Max
[Section titled “Vector3:Max”](#vector3max)
vec:Max(...other: Vector3) -> Vector3
Component-wise maximum across this vector and any number of others.
```lua
local m = a:Max(b, c)
```
### Vector3:Min
[Section titled “Vector3:Min”](#vector3min)
vec:Min(...other: Vector3) -> Vector3
Component-wise minimum across this vector and any number of others.
```lua
local m = a:Min(b, c)
```
### Vector3:FuzzyEq
[Section titled “Vector3:FuzzyEq”](#vector3fuzzyeq)
vec:FuzzyEq(other: Vector3, epsilon: number?) -> boolean
True if all components are within epsilon (default 1e-5) of each other.
```lua
if a:FuzzyEq(b, 0.01) then end
```
### Vector3:Angle
[Section titled “Vector3:Angle”](#vector3angle)
vec:Angle(other: Vector3, axis: Vector3?) -> number
Angle in radians between two vectors, signed about an optional axis.
```lua
local ang = a:Angle(b)
```
### Vector3 operators
[Section titled “Vector3 operators”](#vector3-operators)
+, -, \* (Vector3|number), / (Vector3|number), unary -, ==, tostring
Arithmetic operators; multiply/divide accept either another Vector3 (component-wise) or a scalar.
```lua
local v = a + b * 2
```
## Vector2
[Section titled “Vector2”](#vector2)
### Vector2.new
[Section titled “Vector2.new”](#vector2new)
Vector2.new(x: number?, y: number?) -> Vector2
Constructs a Vector2, defaulting any omitted component to 0.
```lua
local v = Vector2.new(1, 2)
```
### Vector2.zero
[Section titled “Vector2.zero”](#vector2zero)
Vector2.zero -> Vector2
Static Vector2(0, 0).
```lua
local v = Vector2.zero
```
### Vector2.one
[Section titled “Vector2.one”](#vector2one)
Vector2.one -> Vector2
Static Vector2(1, 1).
```lua
local v = Vector2.one
```
### Vector2.xAxis
[Section titled “Vector2.xAxis”](#vector2xaxis)
Vector2.xAxis -> Vector2
Static Vector2(1, 0).
```lua
local v = Vector2.xAxis
```
### Vector2.yAxis
[Section titled “Vector2.yAxis”](#vector2yaxis)
Vector2.yAxis -> Vector2
Static Vector2(0, 1).
```lua
local v = Vector2.yAxis
```
### Vector2.X/Y
[Section titled “Vector2.X/Y”](#vector2xy)
vec.X, vec.Y -> number
Read-only component accessors.
```lua
print(v.X, v.Y)
```
### Vector2.Magnitude
[Section titled “Vector2.Magnitude”](#vector2magnitude)
vec.Magnitude -> number
Vector length.
```lua
print(v.Magnitude)
```
### Vector2.Unit
[Section titled “Vector2.Unit”](#vector2unit)
vec.Unit -> Vector2
Normalized copy of the vector, zero-length vectors return the zero vector unchanged.
```lua
local u = v.Unit
```
### Vector2:Dot
[Section titled “Vector2:Dot”](#vector2dot)
vec:Dot(other: Vector2) -> number
Dot product of two vectors.
```lua
local d = v:Dot(Vector2.new(0,1))
```
### Vector2:Cross
[Section titled “Vector2:Cross”](#vector2cross)
vec:Cross(other: Vector2) -> number
2D cross product (scalar) of two vectors.
```lua
local c = v:Cross(Vector2.new(0,1))
```
### Vector2:Lerp
[Section titled “Vector2:Lerp”](#vector2lerp)
vec:Lerp(goal: Vector2, alpha: number) -> Vector2
Linear interpolation between two vectors.
```lua
local m = a:Lerp(b, 0.5)
```
### Vector2:Abs
[Section titled “Vector2:Abs”](#vector2abs)
vec:Abs() -> Vector2
Component-wise absolute value.
```lua
local a = v:Abs()
```
### Vector2:Ceil
[Section titled “Vector2:Ceil”](#vector2ceil)
vec:Ceil() -> Vector2
Component-wise ceiling.
```lua
local c = v:Ceil()
```
### Vector2:Floor
[Section titled “Vector2:Floor”](#vector2floor)
vec:Floor() -> Vector2
Component-wise floor.
```lua
local f = v:Floor()
```
### Vector2:Sign
[Section titled “Vector2:Sign”](#vector2sign)
vec:Sign() -> Vector2
Component-wise sign (-1, 0, or 1).
```lua
local s = v:Sign()
```
### Vector2:Max
[Section titled “Vector2:Max”](#vector2max)
vec:Max(...other: Vector2) -> Vector2
Component-wise maximum across this vector and any number of others.
```lua
local m = a:Max(b)
```
### Vector2:Min
[Section titled “Vector2:Min”](#vector2min)
vec:Min(...other: Vector2) -> Vector2
Component-wise minimum across this vector and any number of others.
```lua
local m = a:Min(b)
```
### Vector2 operators
[Section titled “Vector2 operators”](#vector2-operators)
+, -, \* (Vector2|number), / (Vector2|number), unary -, ==, tostring
Arithmetic operators; multiply/divide accept either another Vector2 (component-wise) or a scalar.
```lua
local v = a + b * 2
```
## Color3
[Section titled “Color3”](#color3)
### Color3.new
[Section titled “Color3.new”](#color3new)
Color3.new(r: number?, g: number?, b: number?) -> Color3
Constructs a Color3 from 0-1 channel values, defaulting omitted channels to 0.
```lua
local c = Color3.new(1, 0, 0)
```
### Color3.fromRGB
[Section titled “Color3.fromRGB”](#color3fromrgb)
Color3.fromRGB(r: number?, g: number?, b: number?) -> Color3
Constructs a Color3 from 0-255 channel values.
```lua
local c = Color3.fromRGB(255, 0, 0)
```
### Color3.fromHSV
[Section titled “Color3.fromHSV”](#color3fromhsv)
Color3.fromHSV(h: number, s: number, v: number) -> Color3
Constructs a Color3 from hue/saturation/value in 0-1 range.
```lua
local c = Color3.fromHSV(0.5, 1, 1)
```
### Color3.fromHex
[Section titled “Color3.fromHex”](#color3fromhex)
Color3.fromHex(hex: string) -> Color3
Constructs a Color3 from a hex string, an optional leading ‘#’ is stripped.
```lua
local c = Color3.fromHex("#FF0000")
```
### Color3.R/G/B
[Section titled “Color3.R/G/B”](#color3rgb)
col.R, col.G, col.B -> number
Read-only 0-1 channel accessors.
```lua
print(c.R, c.G, c.B)
```
### Color3:Lerp
[Section titled “Color3:Lerp”](#color3lerp)
col:Lerp(other: Color3, alpha: number) -> Color3
Linear interpolation between two colors.
```lua
local m = a:Lerp(b, 0.5)
```
### Color3:ToHSV
[Section titled “Color3:ToHSV”](#color3tohsv)
col:ToHSV() -> (number, number, number)
Returns hue, saturation, value in 0-1 range.
```lua
local h, s, v = c:ToHSV()
```
### Color3:ToHex
[Section titled “Color3:ToHex”](#color3tohex)
col:ToHex() -> string
Returns an uppercase 6-digit hex string with no leading ‘#’.
```lua
local hex = c:ToHex()
```
### Color3 operators
[Section titled “Color3 operators”](#color3-operators)
\==, tostring
Equality and string conversion.
```lua
if a == b then end
```
## CFrame
[Section titled “CFrame”](#cframe)
### CFrame.new
[Section titled “CFrame.new”](#cframenew)
CFrame.new() | CFrame.new(pos: Vector3) | CFrame.new(pos: Vector3, lookAt: Vector3) | CFrame.new(x: number, y: number, z: number) | CFrame.new(x,y,z, r00..r22: number x9) -> CFrame
Constructs a CFrame; overload chosen by argument count and type (identity, position-only, look-at, position, or full 3x4 component list).
```lua
local cf = CFrame.new(0, 5, 0)
```
### CFrame.lookAt
[Section titled “CFrame.lookAt”](#cframelookat)
CFrame.lookAt(pos: Vector3, target: Vector3, up: Vector3?) -> CFrame
Constructs a CFrame at pos oriented toward target, up defaults to (0,1,0).
```lua
local cf = CFrame.lookAt(Vector3.zero, Vector3.new(0,0,-1))
```
### CFrame.Angles
[Section titled “CFrame.Angles”](#cframeangles)
CFrame.Angles(rx: number, ry: number, rz: number) -> CFrame
Constructs a rotation-only CFrame from Euler angles in radians (Rx*Ry*Rz order).
```lua
local cf = CFrame.Angles(0, math.pi/2, 0)
```
### CFrame.fromEulerAnglesXYZ
[Section titled “CFrame.fromEulerAnglesXYZ”](#cframefromeuleranglesxyz)
CFrame.fromEulerAnglesXYZ(rx: number, ry: number, rz: number) -> CFrame
Alias for CFrame.Angles.
```lua
local cf = CFrame.fromEulerAnglesXYZ(0, 0, 0)
```
### CFrame.Position/p
[Section titled “CFrame.Position/p”](#cframepositionp)
cf.Position, cf.p -> Vector3
Translation component of the CFrame.
```lua
print(cf.Position)
```
### CFrame.X/Y/Z
[Section titled “CFrame.X/Y/Z”](#cframexyz)
cf.X, cf.Y, cf.Z -> number
Position components.
```lua
print(cf.X, cf.Y, cf.Z)
```
### CFrame.RightVector/XVector
[Section titled “CFrame.RightVector/XVector”](#cframerightvectorxvector)
cf.RightVector, cf.XVector -> Vector3
World-space right (rotation column 0).
```lua
print(cf.RightVector)
```
### CFrame.UpVector/YVector
[Section titled “CFrame.UpVector/YVector”](#cframeupvectoryvector)
cf.UpVector, cf.YVector -> Vector3
World-space up (rotation column 1).
```lua
print(cf.UpVector)
```
### CFrame.LookVector
[Section titled “CFrame.LookVector”](#cframelookvector)
cf.LookVector -> Vector3
World-space forward, negated rotation column 2.
```lua
print(cf.LookVector)
```
### CFrame.ZVector
[Section titled “CFrame.ZVector”](#cframezvector)
cf.ZVector -> Vector3
Raw rotation column 2 (not negated, unlike LookVector).
```lua
print(cf.ZVector)
```
### CFrame:Inverse
[Section titled “CFrame:Inverse”](#cframeinverse)
cf:Inverse() -> CFrame
Returns the inverse transform.
```lua
local inv = cf:Inverse()
```
### CFrame:Lerp
[Section titled “CFrame:Lerp”](#cframelerp)
cf:Lerp(goal: CFrame, alpha: number) -> CFrame
Interpolates position linearly and rotation via quaternion slerp.
```lua
local m = a:Lerp(b, 0.5)
```
### CFrame:GetComponents
[Section titled “CFrame:GetComponents”](#cframegetcomponents)
cf:GetComponents() -> (number x12)
Returns the 12 raw components: position xyz then the 3x3 rotation matrix row-major.
```lua
local x,y,z, r00,r01,r02, r10,r11,r12, r20,r21,r22 = cf:GetComponents()
```
### CFrame:components
[Section titled “CFrame:components”](#cframecomponents)
cf:components() -> (number x12)
Alias for GetComponents.
```lua
local vals = {cf:components()}
```
### CFrame:ToWorldSpace
[Section titled “CFrame:ToWorldSpace”](#cframetoworldspace)
cf:ToWorldSpace(other: CFrame) -> CFrame
Composes this CFrame with another (self \* other).
```lua
local w = base:ToWorldSpace(offset)
```
### CFrame:ToObjectSpace
[Section titled “CFrame:ToObjectSpace”](#cframetoobjectspace)
cf:ToObjectSpace(other: CFrame) -> CFrame
Returns other expressed relative to this CFrame (inverse(self) \* other).
```lua
local rel = base:ToObjectSpace(world)
```
### CFrame:PointToWorldSpace
[Section titled “CFrame:PointToWorldSpace”](#cframepointtoworldspace)
cf:PointToWorldSpace(point: Vector3) -> Vector3
Transforms a local point to world space.
```lua
local w = cf:PointToWorldSpace(Vector3.new(0,1,0))
```
### CFrame:PointToObjectSpace
[Section titled “CFrame:PointToObjectSpace”](#cframepointtoobjectspace)
cf:PointToObjectSpace(point: Vector3) -> Vector3
Transforms a world point to local space.
```lua
local l = cf:PointToObjectSpace(worldPoint)
```
### CFrame:VectorToWorldSpace
[Section titled “CFrame:VectorToWorldSpace”](#cframevectortoworldspace)
cf:VectorToWorldSpace(vec: Vector3) -> Vector3
Rotates a direction vector into world space, ignoring translation.
```lua
local w = cf:VectorToWorldSpace(Vector3.new(1,0,0))
```
### CFrame:VectorToObjectSpace
[Section titled “CFrame:VectorToObjectSpace”](#cframevectortoobjectspace)
cf:VectorToObjectSpace(vec: Vector3) -> Vector3
Rotates a direction vector into local space, ignoring translation.
```lua
local l = cf:VectorToObjectSpace(worldDir)
```
### CFrame:ToEulerAnglesXYZ
[Section titled “CFrame:ToEulerAnglesXYZ”](#cframetoeuleranglesxyz)
cf:ToEulerAnglesXYZ() -> (number, number, number)
Returns Euler angles in radians (Roblox YXZ decomposition).
```lua
local rx, ry, rz = cf:ToEulerAnglesXYZ()
```
### CFrame:ToOrientation
[Section titled “CFrame:ToOrientation”](#cframetoorientation)
cf:ToOrientation() -> (number, number, number)
Alias for ToEulerAnglesXYZ.
```lua
local rx, ry, rz = cf:ToOrientation()
```
### CFrame:ToEulerAngles
[Section titled “CFrame:ToEulerAngles”](#cframetoeulerangles)
cf:ToEulerAngles() -> (number, number, number)
Alias for ToEulerAnglesXYZ.
```lua
local rx, ry, rz = cf:ToEulerAngles()
```
### CFrame operators
[Section titled “CFrame operators”](#cframe-operators)
\* (CFrame|Vector3), + (Vector3), - (Vector3), ==, tostring
Multiply composes with another CFrame or transforms a Vector3; add/subtract offset the position by a Vector3.
```lua
local moved = cf * CFrame.new(0,1,0)
```
## UDim
[Section titled “UDim”](#udim)
### UDim.new
[Section titled “UDim.new”](#udimnew)
UDim.new(scale: number?, offset: number?) -> UDim
Constructs a UDim, defaulting omitted components to 0.
```lua
local u = UDim.new(0.5, 10)
```
### UDim.Scale/Offset
[Section titled “UDim.Scale/Offset”](#udimscaleoffset)
u.Scale, u.Offset -> number
Read-only component accessors.
```lua
print(u.Scale, u.Offset)
```
### UDim operators
[Section titled “UDim operators”](#udim-operators)
+, -, ==, tostring
Component-wise arithmetic and equality.
```lua
local u = a + b
```
## UDim2
[Section titled “UDim2”](#udim2)
### UDim2.new
[Section titled “UDim2.new”](#udim2new)
UDim2.new(xScale, xOffset, yScale, yOffset: number?) | UDim2.new(x: UDim, y: UDim) -> UDim2
Constructs a UDim2 from four scalars or two UDims.
```lua
local u = UDim2.new(0.5, 0, 1, -10)
```
### UDim2.fromScale
[Section titled “UDim2.fromScale”](#udim2fromscale)
UDim2.fromScale(x: number?, y: number?) -> UDim2
Constructs a UDim2 with only scale components set.
```lua
local u = UDim2.fromScale(0.5, 0.5)
```
### UDim2.fromOffset
[Section titled “UDim2.fromOffset”](#udim2fromoffset)
UDim2.fromOffset(x: number?, y: number?) -> UDim2
Constructs a UDim2 with only offset components set.
```lua
local u = UDim2.fromOffset(100, 50)
```
### UDim2.X/Width
[Section titled “UDim2.X/Width”](#udim2xwidth)
u.X, u.Width -> UDim
The X-axis UDim (scale/offset pair).
```lua
print(u.X.Scale)
```
### UDim2.Y/Height
[Section titled “UDim2.Y/Height”](#udim2yheight)
u.Y, u.Height -> UDim
The Y-axis UDim (scale/offset pair).
```lua
print(u.Y.Offset)
```
### UDim2:Lerp
[Section titled “UDim2:Lerp”](#udim2lerp)
u:Lerp(goal: UDim2, alpha: number) -> UDim2
Linear interpolation of all four components.
```lua
local m = a:Lerp(b, 0.5)
```
### UDim2 operators
[Section titled “UDim2 operators”](#udim2-operators)
+, -, ==, tostring
Component-wise arithmetic and equality.
```lua
local u = a + b
```
## Rect
[Section titled “Rect”](#rect)
### Rect.new
[Section titled “Rect.new”](#rectnew)
Rect.new(minOrX: Vector2|number?, maxOrY: Vector2|number?, maxX: number?, maxY: number?) -> Rect
Constructs a Rect from two Vector2 corners or four numbers.
```lua
local r = Rect.new(0, 0, 100, 50)
```
### Rect.Min/Max
[Section titled “Rect.Min/Max”](#rectminmax)
r.Min, r.Max -> Vector2
Corner accessors.
```lua
print(r.Min, r.Max)
```
### Rect.Width/Height
[Section titled “Rect.Width/Height”](#rectwidthheight)
r.Width, r.Height -> number
Derived size (Max minus Min per axis).
```lua
print(r.Width, r.Height)
```
### Rect operators
[Section titled “Rect operators”](#rect-operators)
\==, tostring
Equality and string conversion.
```lua
if a == b then end
```
## NumberRange
[Section titled “NumberRange”](#numberrange)
### NumberRange.new
[Section titled “NumberRange.new”](#numberrangenew)
NumberRange.new(min: number, max: number?) -> NumberRange
Constructs a NumberRange, max defaults to min.
```lua
local r = NumberRange.new(0, 10)
```
### NumberRange.Min/Max
[Section titled “NumberRange.Min/Max”](#numberrangeminmax)
r.Min, r.Max -> number
Read-only bound accessors.
```lua
print(r.Min, r.Max)
```
### NumberRange operators
[Section titled “NumberRange operators”](#numberrange-operators)
\==, tostring
Equality and string conversion.
```lua
if a == b then end
```
## TweenInfo
[Section titled “TweenInfo”](#tweeninfo)
### TweenInfo.new
[Section titled “TweenInfo.new”](#tweeninfonew)
TweenInfo.new(time: number?, easingStyle: EnumItem|number?, easingDirection: EnumItem|number?, repeatCount: number?, reverses: boolean?, delayTime: number?) -> TweenInfo
Constructs a TweenInfo; easingStyle/Direction accept a raw number or an Enum.\* EnumItem.
```lua
local ti = TweenInfo.new(1, Enum.EasingStyle.Sine)
```
### TweenInfo.Time/EasingStyle/EasingDirection/RepeatCount/Reverses/DelayTime
[Section titled “TweenInfo.Time/EasingStyle/EasingDirection/RepeatCount/Reverses/DelayTime”](#tweeninfotimeeasingstyleeasingdirectionrepeatcountreversesdelaytime)
ti.Time -> number, ti.EasingStyle -> number, ti.EasingDirection -> number, ti.RepeatCount -> number, ti.Reverses -> boolean, ti.DelayTime -> number
Read-only field accessors.
```lua
print(ti.Time, ti.Reverses)
```
## Color4
[Section titled “Color4”](#color4)
### Color4.new
[Section titled “Color4.new”](#color4new)
Color4.new(r: number?, g: number?, b: number?, a: number?) -> Color4
Constructs a Color4, alpha defaults to 1.
```lua
local c = Color4.new(1, 0, 0, 0.5)
```
### Color4.R/G/B/A
[Section titled “Color4.R/G/B/A”](#color4rgba)
c.R, c.G, c.B, c.A -> number
Read-only channel accessors.
```lua
print(c.R, c.A)
```
### Color4 operators
[Section titled “Color4 operators”](#color4-operators)
\==, tostring
Equality and string conversion.
```lua
if a == b then end
```
## Ray
[Section titled “Ray”](#ray)
### Ray.new
[Section titled “Ray.new”](#raynew)
Ray.new(origin: Vector3, direction: Vector3) -> Ray
Constructs a Ray from an origin and direction.
```lua
local r = Ray.new(Vector3.zero, Vector3.new(0,0,-1))
```
### Ray.Origin/Direction
[Section titled “Ray.Origin/Direction”](#rayorigindirection)
ray.Origin, ray.Direction -> Vector3
Read-only field accessors.
```lua
print(ray.Origin, ray.Direction)
```
### Ray.Unit
[Section titled “Ray.Unit”](#rayunit)
ray.Unit -> Ray
Copy of the ray with the direction normalized.
```lua
local u = ray.Unit
```
### Ray:ClosestPoint
[Section titled “Ray:ClosestPoint”](#rayclosestpoint)
ray:ClosestPoint(point: Vector3) -> Vector3
Closest point on the ray (clamped to t >= 0) to the given point.
```lua
local p = ray:ClosestPoint(target)
```
### Ray:Distance
[Section titled “Ray:Distance”](#raydistance)
ray:Distance(point: Vector3) -> number
Distance from the ray (clamped to t >= 0) to the given point.
```lua
local d = ray:Distance(target)
```
## Region3
[Section titled “Region3”](#region3)
### Region3.new
[Section titled “Region3.new”](#region3new)
Region3.new(min: Vector3, max: Vector3) -> Region3
Constructs an axis-aligned Region3 from min/max corners.
```lua
local r = Region3.new(Vector3.new(-5,-5,-5), Vector3.new(5,5,5))
```
### Region3.Size
[Section titled “Region3.Size”](#region3size)
r.Size -> Vector3
Derived size (max minus min).
```lua
print(r.Size)
```
### Region3.CFrame
[Section titled “Region3.CFrame”](#region3cframe)
r.CFrame -> CFrame
Identity-rotation CFrame centered on the region.
```lua
print(r.CFrame)
```
## Enum
[Section titled “Enum”](#enum)
### Enum table
[Section titled “Enum table”](#enum-table)
Enum.\.\ -> EnumItem
Curated set of Enum types/values (EasingStyle, EasingDirection, UserInputType, UserInputState, KeyCode, Material, HumanoidStateType, KeybindMode, FontWeight, FontStyle, Font), not the full Roblox enum set.
```lua
local style = Enum.EasingStyle.Sine
```
## EnumItem
[Section titled “EnumItem”](#enumitem)
### EnumItem.Name/Value/EnumType
[Section titled “EnumItem.Name/Value/EnumType”](#enumitemnamevalueenumtype)
item.Name -> string, item.Value -> number, item.EnumType -> string
Read-only field accessors on an EnumItem.
```lua
print(item.Name, item.Value)
```
### EnumItem operators
[Section titled “EnumItem operators”](#enumitem-operators)
\==, tostring
Equality compares value and enum type; tostring formats as Enum.Type.Name.
```lua
if a == b then end
```
## RaycastResult
[Section titled “RaycastResult”](#raycastresult)
### RaycastResult.Position/Normal/Distance/Instance/Material
[Section titled “RaycastResult.Position/Normal/Distance/Instance/Material”](#raycastresultpositionnormaldistanceinstancematerial)
rr.Position -> Vector3, rr.Normal -> Vector3, rr.Distance -> number, rr.Instance -> Instance|nil, rr.Material -> EnumItem
Read-only fields on a raycast hit result. You get one back from a raycast; it is not user-constructible. `Instance` may be nil when the hit object can’t be resolved.
```lua
local hit = workspace:Raycast(origin, dir); print(hit.Position)
```
## NumberSequence
[Section titled “NumberSequence”](#numbersequence)
### NumberSequence.new
[Section titled “NumberSequence.new”](#numbersequencenew)
NumberSequence.new(keypoints: {NumberSequenceKeypoint}) | NumberSequence.new(value: number, value2: number?) -> NumberSequence
Constructs from an explicit keypoint array, or a constant/two-point sequence from one or two numbers.
```lua
local ns = NumberSequence.new(0, 1)
```
### NumberSequence.Keypoints
[Section titled “NumberSequence.Keypoints”](#numbersequencekeypoints)
ns.Keypoints -> {NumberSequenceKeypoint}
Rebuilds and returns the keypoint array.
```lua
for _, kp in ns.Keypoints do end
```
## ColorSequence
[Section titled “ColorSequence”](#colorsequence)
### ColorSequence.new
[Section titled “ColorSequence.new”](#colorsequencenew)
ColorSequence.new(keypoints: {ColorSequenceKeypoint}) | ColorSequence.new(color: Color3, color2: Color3?) -> ColorSequence
Constructs from an explicit keypoint array, or a constant/two-point sequence from one or two colors.
```lua
local cs = ColorSequence.new(Color3.new(1,0,0))
```
### ColorSequence.Keypoints
[Section titled “ColorSequence.Keypoints”](#colorsequencekeypoints)
cs.Keypoints -> {ColorSequenceKeypoint}
Rebuilds and returns the keypoint array.
```lua
for _, kp in cs.Keypoints do end
```
## NumberSequenceKeypoint
[Section titled “NumberSequenceKeypoint”](#numbersequencekeypoint)
### NumberSequenceKeypoint.new
[Section titled “NumberSequenceKeypoint.new”](#numbersequencekeypointnew)
NumberSequenceKeypoint.new(time: number, value: number, envelope: number?) -> NumberSequenceKeypoint
Constructs a keypoint, envelope defaults to 0.
```lua
local kp = NumberSequenceKeypoint.new(0, 1)
```
### NumberSequenceKeypoint.Time/Value/Envelope
[Section titled “NumberSequenceKeypoint.Time/Value/Envelope”](#numbersequencekeypointtimevalueenvelope)
kp.Time, kp.Value, kp.Envelope -> number
Read-only field accessors.
```lua
print(kp.Time, kp.Value)
```
## ColorSequenceKeypoint
[Section titled “ColorSequenceKeypoint”](#colorsequencekeypoint)
### ColorSequenceKeypoint.new
[Section titled “ColorSequenceKeypoint.new”](#colorsequencekeypointnew)
ColorSequenceKeypoint.new(time: number, color: Color3) -> ColorSequenceKeypoint
Constructs a keypoint from a time and Color3.
```lua
local kp = ColorSequenceKeypoint.new(0, Color3.new(1,0,0))
```
### ColorSequenceKeypoint.Time/Value
[Section titled “ColorSequenceKeypoint.Time/Value”](#colorsequencekeypointtimevalue)
kp.Time -> number, kp.Value -> Color3
Read-only field accessors.
```lua
print(kp.Time, kp.Value)
```
## Font
[Section titled “Font”](#font)
### Font.new
[Section titled “Font.new”](#fontnew)
Font.new(family: string, weight: EnumItem|number?, style: EnumItem|number?) -> Font
Constructs a Font from a family string; weight/style accept a raw number or Enum.FontWeight/FontStyle EnumItem, defaulting to Regular/Normal.
```lua
local f = Font.new("rbxasset://fonts/families/Roboto.json")
```
### Font.fromName
[Section titled “Font.fromName”](#fontfromname)
Font.fromName(name: string, weight: EnumItem|number?, style: EnumItem|number?) -> Font
Builds a Font from a short family name via the rbxasset families path convention.
```lua
local f = Font.fromName("Roboto")
```
### Font.fromEnum
[Section titled “Font.fromEnum”](#fontfromenum)
Font.fromEnum(fontEnum: EnumItem|string) -> Font
Builds a Font from an Enum.Font EnumItem (or raw name string), defaulting to SourceSans if unrecognized.
```lua
local f = Font.fromEnum(Enum.Font.Gotham)
```
### Font.Family/Bold/Weight/Style
[Section titled “Font.Family/Bold/Weight/Style”](#fontfamilyboldweightstyle)
f.Family -> string, f.Bold -> boolean, f.Weight -> EnumItem, f.Style -> EnumItem
Read-only field accessors; Bold is derived from weight >= 600.
```lua
print(f.Family, f.Bold)
```
### Font operators
[Section titled “Font operators”](#font-operators)
\==, tostring
Equality compares family, weight and style; tostring formats as a descriptive string.
```lua
if a == b then end
```
## PhysicalProperties
[Section titled “PhysicalProperties”](#physicalproperties)
### PhysicalProperties.new
[Section titled “PhysicalProperties.new”](#physicalpropertiesnew)
PhysicalProperties.new(density: number, friction: number?, elasticity: number?, frictionWeight: number?, elasticityWeight: number?) -> PhysicalProperties
Constructs a PhysicalProperties; friction/elasticity default to 0, the two weights default to 1.
```lua
local pp = PhysicalProperties.new(0.7)
```
### PhysicalProperties fields
[Section titled “PhysicalProperties fields”](#physicalproperties-fields)
pp.Density, pp.Friction, pp.Elasticity, pp.FrictionWeight, pp.ElasticityWeight -> number
Read-only field accessors.
```lua
print(pp.Density)
```
### PhysicalProperties operators
[Section titled “PhysicalProperties operators”](#physicalproperties-operators)
\==, tostring
Equality and string conversion.
```lua
if a == b then end
```
## Vector3int16
[Section titled “Vector3int16”](#vector3int16)
### Vector3int16.new
[Section titled “Vector3int16.new”](#vector3int16new)
Vector3int16.new(x: number?, y: number?, z: number?) -> Vector3int16
Constructs a Vector3int16, components truncated to int16.
```lua
local v = Vector3int16.new(1, 2, 3)
```
### Vector3int16.X/Y/Z
[Section titled “Vector3int16.X/Y/Z”](#vector3int16xyz)
v.X, v.Y, v.Z -> number
Read-only integer component accessors.
```lua
print(v.X, v.Y, v.Z)
```
### Vector3int16 operators
[Section titled “Vector3int16 operators”](#vector3int16-operators)
+, -, ==, tostring
Component-wise arithmetic (results truncated to int16) and equality.
```lua
local v = a + b
```
## Vector2int16
[Section titled “Vector2int16”](#vector2int16)
### Vector2int16.new
[Section titled “Vector2int16.new”](#vector2int16new)
Vector2int16.new(x: number?, y: number?) -> Vector2int16
Constructs a Vector2int16, components truncated to int16.
```lua
local v = Vector2int16.new(1, 2)
```
### Vector2int16.X/Y
[Section titled “Vector2int16.X/Y”](#vector2int16xy)
v.X, v.Y -> number
Read-only integer component accessors.
```lua
print(v.X, v.Y)
```
### Vector2int16 operators
[Section titled “Vector2int16 operators”](#vector2int16-operators)
+, -, ==, tostring
Component-wise arithmetic (results truncated to int16) and equality.
```lua
local v = a + b
```
## BrickColor
[Section titled “BrickColor”](#brickcolor)
### BrickColor.new
[Section titled “BrickColor.new”](#brickcolornew)
BrickColor.new() | BrickColor.new(color: Color3) | BrickColor.new(name: string) | BrickColor.new(r,g,b: number) | BrickColor.new(number: integer) -> BrickColor
Constructs a BrickColor from a Color3 (nearest palette match), a palette name, RGB numbers, or a palette number; falls back to Medium stone grey (194) if unresolved.
```lua
local bc = BrickColor.new("Bright red")
```
### BrickColor.random
[Section titled “BrickColor.random”](#brickcolorrandom)
BrickColor.random() -> BrickColor
Returns a BrickColor chosen from the palette via a self-contained xorshift RNG.
```lua
local bc = BrickColor.random()
```
### BrickColor.White/Gray/DarkGray/Black/Red/Green/Blue/Yellow
[Section titled “BrickColor.White/Gray/DarkGray/Black/Red/Green/Blue/Yellow”](#brickcolorwhitegraydarkgrayblackredgreenblueyellow)
BrickColor.White() -> BrickColor (etc.)
Static convenience constructors for common palette entries.
```lua
local bc = BrickColor.Red()
```
### BrickColor.Number/Name/Color/r/g/b
[Section titled “BrickColor.Number/Name/Color/r/g/b”](#brickcolornumbernamecolorrgb)
bc.Number -> integer, bc.Name -> string, bc.Color -> Color3, bc.r/bc.R, bc.g/bc.G, bc.b/bc.B -> number
Read-only field accessors; r/g/b (and uppercase variants) are 0-1 channel values, unresolved palette numbers fall back to Medium stone grey’s RGB.
```lua
print(bc.Name, bc.Color)
```
### BrickColor operators
[Section titled “BrickColor operators”](#brickcolor-operators)
\==, tostring
Equality compares palette number; tostring returns the palette name (empty string if unknown).
```lua
if a == b then end
```
Note
`Enum` exposes a curated subset of Roblox’s enums (`EasingStyle`, `EasingDirection`, `UserInputType`, `UserInputState`, `KeyCode`, `Material`, `HumanoidStateType`, `KeybindMode`, `FontWeight`, `FontStyle`, `Font`), not the whole catalogue. `RaycastResult` has no constructor; you get one back from a raycast. `TweenInfo`, `PhysicalProperties`, `Font`, `BrickColor`, `Color4`, `Vector3int16`, and `Vector2int16` only support what is listed above, and `TweenInfo` can’t be compared with `==`.
# draw
> Immediate-mode 2D/3D drawing primitives for building ESP and overlay visuals on the external layer-shell surface.
Immediate-mode 2D/3D drawing primitives for building ESP and overlay visuals on the external layer-shell surface.
## Shapes
[Section titled “Shapes”](#shapes)
### draw\.Line
[Section titled “draw.Line”](#drawline)
draw\.Line(x1: number, y1: number, x2: number, y2: number, color: Color3, thickness: number?, alpha: number?)
Draws a line segment between two screen points, thickness defaults to 1 and alpha (0-255) defaults to 255.
```lua
draw.Line(0, 0, 100, 100, Color3.new(1, 0, 0), 2, 255)
```
### draw\.Rect
[Section titled “draw.Rect”](#drawrect)
draw\.Rect(x: number, y: number, w: number, h: number, color: Color3, thickness: number?, alpha: number?)
Draws an unfilled rectangle outline, thickness defaults to 1 and alpha (0-255) defaults to 255.
```lua
draw.Rect(50, 50, 100, 40, Color3.new(0, 1, 0))
```
### draw\.RectFilled
[Section titled “draw.RectFilled”](#drawrectfilled)
draw\.RectFilled(x: number, y: number, w: number, h: number, color: Color3, rounding: number?, alpha: number?)
Draws a filled rectangle, rounding defaults to 0 (sharp corners) and alpha (0-255) defaults to 255.
```lua
draw.RectFilled(50, 50, 100, 40, Color3.new(0, 0, 1), 4)
```
### draw\.Circle
[Section titled “draw.Circle”](#drawcircle)
draw\.Circle(x: number, y: number, radius: number, color: Color3, thickness: number?, alpha: number?)
Draws an unfilled circle outline, thickness defaults to 1 and alpha (0-255) defaults to 255.
```lua
draw.Circle(200, 200, 20, Color3.new(1, 1, 0))
```
### draw\.CircleFilled
[Section titled “draw.CircleFilled”](#drawcirclefilled)
draw\.CircleFilled(x: number, y: number, radius: number, color: Color3, alpha: number?)
Draws a filled circle, alpha (0-255) defaults to 255.
```lua
draw.CircleFilled(200, 200, 20, Color3.new(1, 1, 0), 180)
```
### draw\.Triangle
[Section titled “draw.Triangle”](#drawtriangle)
draw\.Triangle(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, color: Color3, thickness: number?, alpha: number?)
Draws an unfilled triangle outline from three screen points, thickness defaults to 1 and alpha defaults to 255.
```lua
draw.Triangle(0,0, 50,0, 25,50, Color3.new(1,1,1))
```
### draw\.TriangleFilled
[Section titled “draw.TriangleFilled”](#drawtrianglefilled)
draw\.TriangleFilled(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, color: Color3, alpha: number?)
Draws a filled triangle from three screen points, alpha (0-255) defaults to 255.
```lua
draw.TriangleFilled(0,0, 50,0, 25,50, Color3.new(1,1,1), 200)
```
### draw\.Polyline
[Section titled “draw.Polyline”](#drawpolyline)
draw\.Polyline(points: {Vector2}, color: Color3, thickness: number?, alpha: number?)
Draws connected line segments through an array of at least two Vector2 points, thickness defaults to 1 and alpha defaults to 255.
```lua
draw.Polyline({Vector2.new(0,0), Vector2.new(10,10), Vector2.new(20,0)}, Color3.new(1,0,0))
```
### draw\.ConvexPolyFilled
[Section titled “draw.ConvexPolyFilled”](#drawconvexpolyfilled)
draw\.ConvexPolyFilled(points: {Vector2}, color: Color3, alpha: number?)
Draws a filled convex polygon from an array of at least three Vector2 points, alpha (0-255) defaults to 255.
```lua
draw.ConvexPolyFilled({Vector2.new(0,0), Vector2.new(10,0), Vector2.new(5,10)}, Color3.new(0,1,0))
```
### draw\.Gradient
[Section titled “draw.Gradient”](#drawgradient)
draw\.Gradient(x: number, y: number, w: number, h: number, colorTop: Color3, colorBottom: Color3, alphaTop: number?, alphaBottom: number?)
Draws a filled rectangle with a vertical gradient between two colors, both alphas (0-255) default to 255.
```lua
draw.Gradient(0, 0, 200, 40, Color3.new(1,0,0), Color3.new(0,0,1))
```
## Text
[Section titled “Text”](#text)
### draw\.Text
[Section titled “draw.Text”](#drawtext)
draw\.Text(text: string, x: number, y: number, color: Color3, size: number?, alpha: number?, font: string?): nil
Draws text at a screen position, size defaults to 14px, alpha defaults to 255, and font is a bundled or workspace font path (defaults to the built-in font).
```lua
draw.Text("Hello", 10, 10, Color3.new(1,1,1), 16)
```
### draw\.TextOutlined
[Section titled “draw.TextOutlined”](#drawtextoutlined)
draw\.TextOutlined(text: string, x: number, y: number, color: Color3, size: number?, alpha: number?, font: string?)
Draws text with a dark outline for legibility over any background, same parameters and defaults as draw\.Text.
```lua
draw.TextOutlined("HP: 100", 10, 30, Color3.new(0,1,0))
```
### draw\.LoadFont
[Section titled “draw.LoadFont”](#drawloadfont)
draw\.LoadFont(path: string): boolean
Explicitly preloads and bakes a font atlas from a bundled name or confined workspace path, returns whether the load succeeded.
```lua
local ok = draw.LoadFont("Inter-Bold.ttf")
```
### draw\.GetTextSize
[Section titled “draw.GetTextSize”](#drawgettextsize)
draw\.GetTextSize(text: string, size: number?, font: string?): Vector2
Measures the rendered width and height of a text string at a given font size, size defaults to 14px.
```lua
local dims = draw.GetTextSize("Hello", 16)
```
## Images & meshes
[Section titled “Images & meshes”](#images--meshes)
### draw\.Image
[Section titled “draw.Image”](#drawimage)
draw\.Image(path: string, x: number, y: number, w: number, h: number, alpha: number?): nil
Draws an image loaded from a confined path at the given screen rect, alpha is 0-1 and defaults to 1.0.
```lua
draw.Image("icon.png", 10, 10, 32, 32, 0.8)
```
### draw\.GetMesh
[Section titled “draw.GetMesh”](#drawgetmesh)
draw\.GetMesh(...): nil, string
Deprecated, always returns nil plus an error string directing callers to mesh.OfPart or draw\.MeshChams.
```lua
local ok, err = draw.GetMesh(part)
```
### draw\.MeshChams
[Section titled “draw.MeshChams”](#drawmeshchams)
draw\.MeshChams(part: Instance, color: Color3, thickness: number?, alpha: number?, style: string?)
Draws a cached silhouette or wireframe overlay on a MeshPart, part must be a MeshPart, style is “outline” (default), “filled”, or “wireframe”, alpha (0-255) defaults to 180.
```lua
draw.MeshChams(part, Color3.new(1,0,0), 1.5, 200, "outline")
```
### draw\.MeshChamsBulk
[Section titled “draw.MeshChamsBulk”](#drawmeshchamsbulk)
draw\.MeshChamsBulk(parts: {Instance}, color: Color3, thickness: number?, alpha: number?, style: string?)
Batched form of draw\.MeshChams for many MeshParts in one call, caller must pre-filter the array to MeshParts, same style options and defaults as draw\.MeshChams.
```lua
draw.MeshChamsBulk(meshParts, Color3.new(0,1,1), 1.0, 180, "filled")
```
### draw\.Wireframe
[Section titled “draw.Wireframe”](#drawwireframe)
draw\.Wireframe(mesh: MeshHandle, options: {color: Color3?, alpha: number?, colors: {Color3}?}?)
Draws every triangle edge of a mesh handle obtained from mesh.OfPart, options.color defaults to a green tint and options.colors supplies optional per-vertex colors.
```lua
local m = mesh.OfPart(part)
draw.Wireframe(m, {color = Color3.new(0,1,0), alpha = 255})
```
## Helpers
[Section titled “Helpers”](#helpers)
### draw\.GetScreenSize
[Section titled “draw.GetScreenSize”](#drawgetscreensize)
draw\.GetScreenSize(): Vector2
Returns the current Sober window viewport size in screen coordinates used by all draw.\* calls.
```lua
local size = draw.GetScreenSize()
```
### draw\.GetPartCorners
[Section titled “draw.GetPartCorners”](#drawgetpartcorners)
draw\.GetPartCorners(part: Instance): {Vector2}
Projects all 8 world-space corners of a BasePart to screen coordinates, returns an empty table if the part cannot be read (corners behind the camera are still included).
```lua
local corners = draw.GetPartCorners(workspace.Part)
```
### draw\.ComputeConvexHull
[Section titled “draw.ComputeConvexHull”](#drawcomputeconvexhull)
draw\.ComputeConvexHull(points: {Vector2}): {Vector2}
Computes the 2D convex hull of an array of Vector2 points using Andrew’s monotone chain algorithm.
```lua
local hull = draw.ComputeConvexHull(corners)
```
Note
All draw.\* calls are no-ops when the overlay frame is not open (Sober not frontmost, or the overlay swap chain is not ready). Colors are Color3 (0-1 per channel); alpha parameters accept 0-255 unless noted otherwise (draw\.Image uses 0-1).
# entity
> Query and filter players/characters in the current place, tune visibility (line-of-sight) checks, register custom (non-Roblox-Player) entities, and enumerate BaseParts across all tracked characters.
Query and filter players/characters in the current place, tune visibility (line-of-sight) checks, register custom (non-Roblox-Player) entities, and enumerate BaseParts across all tracked characters.
## Queries
[Section titled “Queries”](#queries)
### entity.GetPlayers
[Section titled “entity.GetPlayers”](#entitygetplayers)
entity.GetPlayers(onlyEnemies: boolean?) -> { Player }
Returns an array of Player handles for every cached player except the LocalPlayer, optionally restricted to enemies.
```lua
for _, p in entity.GetPlayers() do print(p) end
```
### entity.GetLocalPlayer
[Section titled “entity.GetLocalPlayer”](#entitygetlocalplayer)
entity.GetLocalPlayer() -> Player | nil
Returns a Player handle for the local player, or nil if it could not be resolved.
```lua
local me = entity.GetLocalPlayer()
```
### entity.GetClosestPlayer
[Section titled “entity.GetClosestPlayer”](#entitygetclosestplayer)
entity.GetClosestPlayer(screenPos: Vector2, maxRadius: number?, filter: table?) -> Player | nil
Returns the player whose Head (or HRP fallback) projects closest on screen to screenPos within maxRadius, subject to an optional filter table.
```lua
local target = entity.GetClosestPlayer(Vector2.new(960, 540), 200)
```
### entity.GetClosestToCursor
[Section titled “entity.GetClosestToCursor”](#entitygetclosesttocursor)
entity.GetClosestToCursor(maxRadiusOrFilter: (number | table)?, filter: table?) -> Player | nil
Returns the player closest to the current mouse cursor position, subject to an optional radius and filter table (if the first argument is a table it is treated as the filter with unlimited radius).
```lua
local target = entity.GetClosestToCursor({ onlyEnemies = true })
```
### entity.GetOccluders
[Section titled “entity.GetOccluders”](#entitygetoccluders)
entity.GetOccluders(origin: Vector3?, radius: number?) -> { { h: MeshHandle, kind: number } }
Returns the occluder grid’s current geometry per tracked part as mesh handles with a kind code (Enum.PartType 0-4, or 5 for Union/MeshPart), optionally limited to parts near origin within radius.
```lua
local occ = entity.GetOccluders()
```
### entity.GetParts
[Section titled “entity.GetParts”](#entitygetparts)
entity.GetParts() -> { Part }
Returns a Part handle for every BasePart across all tracked entities’ characters (players and custom models).
```lua
for _, part in entity.GetParts() do print(part:GetPartPosition()) end
```
### entity.GetPartsCount
[Section titled “entity.GetPartsCount”](#entitygetpartscount)
entity.GetPartsCount() -> number
Returns the count of BaseParts across all tracked entities’ characters.
```lua
local n = entity.GetPartsCount()
```
## Visibility & models
[Section titled “Visibility & models”](#visibility--models)
### entity.SetVisibilityFilter
[Section titled “entity.SetVisibilityFilter”](#entitysetvisibilityfilter)
entity.SetVisibilityFilter(opts: table) -> ()
Tunes which Workspace parts count as occluders for visibility checks (minSize, maxTransparency, requireCanCollide, maxScan, maxOccluders, rebuildPeriod, fastInterval, discoveryInterval, nearRadius); fields omitted from opts keep their current value.
```lua
entity.SetVisibilityFilter({ minSize = 1.0, requireCanCollide = true })
```
### entity.SetVisibilityBone
[Section titled “entity.SetVisibilityBone”](#entitysetvisibilitybone)
entity.SetVisibilityBone(name: string) -> ()
Sets the character bone used as the target point for IsVisible-style checks, default Head, alias-resolved per rig by the bone cache.
```lua
entity.SetVisibilityBone("UpperTorso")
```
### entity.SetVisibilityMode
[Section titled “entity.SetVisibilityMode”](#entitysetvisibilitymode)
entity.SetVisibilityMode(mode: "bone" | "any") -> ()
Selects whether visibility passes only when the single SetVisibilityBone target has line of sight (“bone”) or when any body point does (“any”, the default); errors on any other string.
```lua
entity.SetVisibilityMode("bone")
```
### entity.GetVisibilityStats
[Section titled “entity.GetVisibilityStats”](#entitygetvisibilitystats)
entity.GetVisibilityStats() -> { registrySize: number, evictions: number, discoveryWalked: number, containerCount: number }
Returns counters describing the occluder registry state: current size, cumulative evictions, container count, and the most recent discovery-tick walked-node count.
```lua
local stats = entity.GetVisibilityStats()
```
### entity.AddModel
[Section titled “entity.AddModel”](#entityaddmodel)
entity.AddModel(key: string, data: table) -> ()
Registers (or replaces) a custom entity under key from a data table requiring a Character Instance field, with optional PrimaryPart, Name, Team, Health, and MaxHealth fields.
```lua
entity.AddModel("dummy1", { Character = model, Name = "Dummy", Health = 100, MaxHealth = 100 })
```
### entity.EditModel
[Section titled “entity.EditModel”](#entityeditmodel)
entity.EditModel(key: string, data: table) -> ()
Merges the provided fields into an existing custom-entity registration, preserving unspecified fields; a no-op if key is absent.
```lua
entity.EditModel("dummy1", { Health = 50 })
```
### entity.RemoveModel
[Section titled “entity.RemoveModel”](#entityremovemodel)
entity.RemoveModel(key: string) -> boolean
Removes a custom-entity registration and returns whether it existed.
```lua
local removed = entity.RemoveModel("dummy1")
```
### entity.ClearModels
[Section titled “entity.ClearModels”](#entityclearmodels)
entity.ClearModels() -> ()
Drops all custom-entity registrations.
```lua
entity.ClearModels()
```
## Player properties
[Section titled “Player properties”](#player-properties)
### Player.Name
[Section titled “Player.Name”](#playername)
Player.Name -> string
The player’s username.
```lua
print(p.Name)
```
### Player.DisplayName
[Section titled “Player.DisplayName”](#playerdisplayname)
Player.DisplayName -> string
The player’s display name.
```lua
print(p.DisplayName)
```
### Player.UserId
[Section titled “Player.UserId”](#playeruserid)
Player.UserId -> number
The player’s numeric user ID.
```lua
print(p.UserId)
```
### Player.Team
[Section titled “Player.Team”](#playerteam)
Player.Team -> string
The name of the player’s team.
```lua
print(p.Team)
```
### Player.IsEnemy
[Section titled “Player.IsEnemy”](#playerisenemy)
Player.IsEnemy -> boolean
True if the player is on an opposing team to the local player.
```lua
if p.IsEnemy then end
```
### Player.IsLocal
[Section titled “Player.IsLocal”](#playerislocal)
Player.IsLocal -> boolean
True if this handle refers to the local player.
```lua
if p.IsLocal then end
```
### Player.IsCustom
[Section titled “Player.IsCustom”](#playeriscustom)
Player.IsCustom -> boolean
True if this is a custom entity registered via entity.AddModel rather than a real Roblox player.
```lua
if p.IsCustom then end
```
### Player.IsR15
[Section titled “Player.IsR15”](#playerisr15)
Player.IsR15 -> boolean
True if the player’s character rig is R15; false means R6.
```lua
if p.IsR15 then end
```
### Player.Health
[Section titled “Player.Health”](#playerhealth)
Player.Health -> number
The player’s current Humanoid health.
```lua
print(p.Health)
```
### Player.MaxHealth
[Section titled “Player.MaxHealth”](#playermaxhealth)
Player.MaxHealth -> number
The player’s Humanoid MaxHealth.
```lua
print(p.MaxHealth)
```
### Player.IsAlive
[Section titled “Player.IsAlive”](#playerisalive)
Player.IsAlive -> boolean
True if the player’s Humanoid is currently alive.
```lua
if p.IsAlive then end
```
### Player.Position
[Section titled “Player.Position”](#playerposition)
Player.Position -> Vector3
The world position of the player’s HumanoidRootPart.
```lua
print(p.Position)
```
### Player.Velocity
[Section titled “Player.Velocity”](#playervelocity)
Player.Velocity -> Vector3
The player’s derived world velocity, computed from position deltas across frames since the engine exposes none directly.
```lua
print(p.Velocity)
```
### Player.Character
[Section titled “Player.Character”](#playercharacter)
Player.Character -> Instance?
The player’s character model Instance, or nil if the player has no character.
```lua
local char = p.Character
```
### Player.TeamColor
[Section titled “Player.TeamColor”](#playerteamcolor)
Player.TeamColor -> Color3
The color associated with the player’s team.
```lua
print(p.TeamColor)
```
### Player.BoundingBox
[Section titled “Player.BoundingBox”](#playerboundingbox)
Player.BoundingBox -> {x: number, y: number, w: number, h: number}
The player’s on-screen bounding box as a table of x, y, w, h fields.
```lua
local box = p.BoundingBox; print(box.x, box.y, box.w, box.h)
```
### Player.IsVisible
[Section titled “Player.IsVisible”](#playerisvisible)
Player.IsVisible -> boolean
True if the player currently has clear line of sight per the configured visibility mode, memoized across frames.
```lua
if p.IsVisible then end
```
### Player.Visibility
[Section titled “Player.Visibility”](#playervisibility)
Player.Visibility -> number
Tri-state line of sight: 1 clear, 2 behind an opaque occluder, 3 behind glass only.
```lua
if p.Visibility == 3 then end
```
## Player methods
[Section titled “Player methods”](#player-methods)
### Player:GetDistanceFromLocal
[Section titled “Player:GetDistanceFromLocal”](#playergetdistancefromlocal)
Player:GetDistanceFromLocal() -> number
Returns the studs distance between this player and the local player, or -1 if the local player is unavailable.
```lua
local d = p:GetDistanceFromLocal()
```
### Player:GetBonePosition
[Section titled “Player:GetBonePosition”](#playergetboneposition)
Player:GetBonePosition(name: string) -> Vector3?
Returns the world position of a named bone/body part, or nil if it cannot be resolved.
```lua
local pos = p:GetBonePosition("Head")
```
### Player:GetBoneSize
[Section titled “Player:GetBoneSize”](#playergetbonesize)
Player:GetBoneSize(name: string) -> Vector3?
Returns the size of a named bone/body part, or nil if it cannot be resolved.
```lua
local sz = p:GetBoneSize("Head")
```
### Player:GetBoneRotation
[Section titled “Player:GetBoneRotation”](#playergetbonerotation)
Player:GetBoneRotation(name: string) -> {number, \[9]}?
Returns the row-major 3x3 rotation matrix of a named bone as a 9-element array, or nil if it cannot be resolved.
```lua
local rot = p:GetBoneRotation("Head")
```
### Player:GetBoneInstance
[Section titled “Player:GetBoneInstance”](#playergetboneinstance)
Player:GetBoneInstance(name: string) -> Instance?
Returns the Instance for a named bone/body part, or nil if it cannot be resolved.
```lua
local inst = p:GetBoneInstance("Head")
```
### Player:IsBoneVisible
[Section titled “Player:IsBoneVisible”](#playerisbonevisible)
Player:IsBoneVisible(name: string) -> boolean?
Returns whether a specific named bone has clear line of sight to the camera, or nil if the bone does not exist on this rig or the check could not run this frame.
```lua
if p:IsBoneVisible("Head") then end
```
## Part handles
[Section titled “Part handles”](#part-handles)
### Part:GetPartPosition
[Section titled “Part:GetPartPosition”](#partgetpartposition)
Part:GetPartPosition() -> Vector3?
Returns the part’s world position, or nil if it cannot be read.
```lua
local pos = part:GetPartPosition()
```
### Part:GetPartSize
[Section titled “Part:GetPartSize”](#partgetpartsize)
Part:GetPartSize() -> Vector3?
Returns the part’s size, or nil if it cannot be read.
```lua
local size = part:GetPartSize()
```
### Part:GetPartRotation
[Section titled “Part:GetPartRotation”](#partgetpartrotation)
Part:GetPartRotation() -> {number}?
Returns the part’s rotation as a row-major 3x3 matrix (9 numbers), or nil if it cannot be read.
```lua
local r = part:GetPartRotation()
```
### Part:GetPartInstance
[Section titled “Part:GetPartInstance”](#partgetpartinstance)
Part:GetPartInstance() -> Instance?
Returns the underlying Instance for the part handle, or nil.
```lua
local inst = part:GetPartInstance()
```
### Part:GetPartAddress
[Section titled “Part:GetPartAddress”](#partgetpartaddress)
Part:GetPartAddress() -> number?
Returns the raw memory address backing the part, or nil.
```lua
local addr = part:GetPartAddress()
```
Note
`entity.GetPlayers`, `entity.GetLocalPlayer`, `entity.GetClosestPlayer`, and `entity.GetClosestToCursor` return opaque `Player` handles; `entity.GetParts` returns `Part` handles. A handle points at one entry in the cache, so once that player or part leaves the map its reads return `nil` rather than erroring; re-query each frame instead of holding a handle across frames. Reading an unknown key off a handle also returns `nil`.
# events
> Event registration and dispatch for scripts to hook engine/game lifecycle moments via cheat.Register.
Event registration and dispatch for scripts to hook engine/game lifecycle moments via cheat.Register.
### onUpdate
[Section titled “onUpdate”](#onupdate)
cheat.Register("onUpdate", function() ... end)
Fires every engine frame tick, the fast per-frame update loop.
```lua
cheat.Register("onUpdate", function()
-- runs every frame
end)
```
### onSlowUpdate
[Section titled “onSlowUpdate”](#onslowupdate)
cheat.Register("onSlowUpdate", function() ... end)
Fires on a slower, throttled update cadence for less time-sensitive polling work.
```lua
cheat.Register("onSlowUpdate", function()
-- runs on a throttled cadence
end)
```
### onPaint
[Section titled “onPaint”](#onpaint)
cheat.Register("onPaint", function() ... end)
Fires once per rendered overlay frame, for draw-related script logic.
```lua
cheat.Register("onPaint", function()
-- runs once per overlay paint
end)
```
### newPlace
[Section titled “newPlace”](#newplace)
cheat.Register("newPlace", function() ... end)
Fires when the game’s DataModel resolves to a new place, e.g. after a server hop or teleport.
```lua
cheat.Register("newPlace", function()
print("joined a new place")
end)
```
### characterAdded
[Section titled “characterAdded”](#characteradded)
cheat.Register("characterAdded", function() ... end)
Fires when the local player’s Character instance appears. Detection is polled and only runs while a handler is registered for this event.
```lua
cheat.Register("characterAdded", function()
print("character spawned")
end)
```
### characterRemoving
[Section titled “characterRemoving”](#characterremoving)
cheat.Register("characterRemoving", function() ... end)
Fires when the local player’s Character instance is about to be removed, detected via polled detection.
```lua
cheat.Register("characterRemoving", function()
print("character despawning")
end)
```
### shutdown
[Section titled “shutdown”](#shutdown)
cheat.Register("shutdown", function() ... end)
Fires when the external tool is shutting down, for cleanup work. A shutdown handler on its own does not keep a script resident.
```lua
cheat.Register("shutdown", function()
print("cleaning up")
end)
```
### cheat.Register
[Section titled “cheat.Register”](#cheatregister)
cheat.Register(eventName: string, handler: function): void
Registers a handler function to be called whenever the named event fires; unknown event names raise a Lua error.
```lua
cheat.Register("onUpdate", function()
-- handler body
end)
```
### cheat.GetWindowSize
[Section titled “cheat.GetWindowSize”](#cheatgetwindowsize)
cheat.GetWindowSize(): (width: number, height: number)
Returns the current game camera viewport size in pixels, or (0, 0) if it cannot be resolved.
```lua
local w, h = cheat.GetWindowSize()
print(w, h)
```
Note
Event names are fired by `cheat.Register`, not called directly. A handler that errors on roughly 2000 consecutive dispatches is auto-disabled, and a single success resets the count, so a burst of errors during a place hop heals itself. `cheat.Register` and `cheat.GetWindowSize` are the only callable methods on the `cheat` table; every other name on this page is an event identifier.
# file
> Sandboxed filesystem access confined to the Conduit workspace directory.
Sandboxed filesystem access confined to the Conduit workspace directory.
### file.read
[Section titled “file.read”](#fileread)
file.read(path: string) -> string?, string?
Reads the full contents of a file as a string, returning nil on failure to open, or nil plus an error message if the file exceeds the 64 MiB read limit.
```lua
local data = file.read("config.txt")
```
### file.write
[Section titled “file.write”](#filewrite)
file.write(path: string, data: string) -> boolean
Overwrites (or creates) a file with the given binary-safe string data, creating parent directories as needed.
```lua
file.write("out.txt", "hello")
```
### file.append
[Section titled “file.append”](#fileappend)
file.append(path: string, data: string) -> boolean
Appends binary-safe string data to the end of a file, creating it if it does not exist.
```lua
file.append("log.txt", "line\n")
```
### file.createfile
[Section titled “file.createfile”](#filecreatefile)
file.createfile(path: string) -> boolean
Creates an empty file at the given path if it does not already exist, without truncating an existing one.
```lua
file.createfile("marker.txt")
```
### file.mkdir
[Section titled “file.mkdir”](#filemkdir)
file.mkdir(path: string) -> boolean
Creates a directory, including any missing parent directories.
```lua
file.mkdir("saves/profile1")
```
### file.isfile
[Section titled “file.isfile”](#fileisfile)
file.isfile(path: string) -> boolean
Returns true if the path exists and is a regular file.
```lua
if file.isfile("config.txt") then end
```
### file.isdir
[Section titled “file.isdir”](#fileisdir)
file.isdir(path: string) -> boolean
Returns true if the path exists and is a directory.
```lua
if file.isdir("saves") then end
```
### file.listdirs
[Section titled “file.listdirs”](#filelistdirs)
file.listdirs(path: string) -> table\
Lists subdirectories directly inside the given directory, as paths relative to the workspace root.
```lua
for _, d in ipairs(file.listdirs(".")) do print(d) end
```
### file.listobjects
[Section titled “file.listobjects”](#filelistobjects)
file.listobjects(path: string) -> table\
Lists all entries (files and directories) directly inside the given directory, as paths relative to the workspace root.
```lua
for _, o in ipairs(file.listobjects(".")) do print(o) end
```
### file.listfiles
[Section titled “file.listfiles”](#filelistfiles)
file.listfiles(path: string) -> table\
Lists regular files directly inside the given directory, as paths relative to the workspace root.
```lua
for _, f in ipairs(file.listfiles(".")) do print(f) end
```
Note
All paths are relative and confined to a per-user workspace directory (\~/.config/conduit/workspace); absolute paths and paths that escape via .. or symlinks raise a Lua error. list order is filesystem iteration order, not sorted.
# geometry
> Reads a BasePart's collision mesh geometry (triangles, shape, world-space snapshot) and takes a snapshot of nearby resident terrain.
Reads a BasePart’s collision mesh geometry (triangles, shape, world-space snapshot) and takes a snapshot of nearby resident terrain.
### geometry.PartTriangles
[Section titled “geometry.PartTriangles”](#geometryparttriangles)
geometry.PartTriangles(part: Instance) -> { verts: {Vector3}, tris: {{number,number,number}}, cframe: CFrame, size: Vector3 } | nil
Returns the part’s collision mesh in part-local space as a vertex list and 1-based triangle index list, along with its CFrame and Size, or nil if the part has no readable geometry.
```lua
local mesh = geometry.PartTriangles(workspace.Baseplate)
if mesh then print(#mesh.verts, #mesh.tris) end
```
### geometry.PartSnapshot
[Section titled “geometry.PartSnapshot”](#geometrypartsnapshot)
geometry.PartSnapshot(part: Instance) -> MeshHandle | nil
Builds a fresh MeshHandle of the part’s collision mesh transformed into world space at its current CFrame, useful for feeding draw\.Wireframe or occlusion checks.
```lua
local snap = geometry.PartSnapshot(workspace.Baseplate)
if snap then draw.Wireframe(snap) end
```
### geometry.PartShape
[Section titled “geometry.PartShape”](#geometrypartshape)
geometry.PartShape(part: Instance) -> number | nil
Returns the part’s Enum.PartType value as an integer (0 Ball, 1 Block, 2 Cylinder, 3 Wedge, 4 CornerWedge), or nil if it could not be read.
```lua
local shape = geometry.PartShape(workspace.Ball)
print(shape) -- 0
```
### geometry.TerrainSnapshot
[Section titled “geometry.TerrainSnapshot”](#geometryterrainsnapshot)
geometry.TerrainSnapshot(options: { radius: number?, mc: boolean? }?) -> MeshHandle | nil
Returns a dual-contour mesh of the resident Terrain within radius studs of the active Camera (default radius 512, default mc true), or nil if there is no active Camera or engine.
```lua
local terrain = geometry.TerrainSnapshot({ radius = 256 })
if terrain then draw.Wireframe(terrain) end
```
Note
`geometry` owns just these methods. The world-to-screen projection helpers live under [`rendering`](/reference/rendering/), and the raycast helpers under [`physics`](/reference/physics/).
# globals
> Bare Roblox-style globals available to every script: the game root instance, the task scheduler, legacy spawn/wait globals, tick, and the Enum table.
Bare Roblox-style globals available to every script: the game root instance, the task scheduler, legacy spawn/wait globals, tick, and the Enum table.
### game
[Section titled “game”](#game)
game : Instance (DataModel)
The root DataModel instance. Use it like any other Instance: `game:GetService(...)`, `game:FindFirstChild(...)`, or index its children directly with `game.Workspace`.
```lua
local ws = game:GetService("Workspace")
print(game.Name)
```
### task.spawn
[Section titled “task.spawn”](#taskspawn)
task.spawn(fn: function, ...: any) -> thread
Creates a new coroutine from fn, resumes it immediately with the given args, and returns the underlying thread.
```lua
task.spawn(function(a) print("spawned", a) end, 42)
```
### task.defer
[Section titled “task.defer”](#taskdefer)
task.defer(fn: function, ...: any) -> thread
Creates a new coroutine from fn and schedules it to resume on the next scheduler pump rather than immediately.
```lua
task.defer(function() print("runs next tick") end)
```
### task.delay
[Section titled “task.delay”](#taskdelay)
task.delay(seconds: number, fn: function, ...: any) -> thread
Creates a new coroutine from fn and schedules it to resume after at least seconds have elapsed.
```lua
task.delay(2, function() print("2s later") end)
```
### task.wait
[Section titled “task.wait”](#taskwait)
task.wait(seconds: number?) -> number
Yields the current coroutine until at least seconds (default 0) have elapsed, then resumes it with the actual elapsed time.
```lua
local elapsed = task.wait(1)
print("waited", elapsed)
```
### task.cancel
[Section titled “task.cancel”](#taskcancel)
task.cancel(thread: thread) -> ()
Removes a pending scheduled task (from spawn/defer/delay/wait) matching the given thread so it never resumes.
```lua
local t = task.delay(5, print, "never")
task.cancel(t)
```
### wait
[Section titled “wait”](#wait)
wait(seconds: number?) -> number
Legacy global alias for task.wait; yields the calling coroutine until seconds have elapsed and returns the elapsed time.
```lua
wait(0.5)
print("half a second passed")
```
### spawn
[Section titled “spawn”](#spawn)
spawn(fn: function, ...: any) -> thread
Legacy global alias for task.spawn; creates and immediately resumes a new coroutine running fn.
```lua
spawn(function() print("legacy spawn") end)
```
### tick
[Section titled “tick”](#tick)
tick() -> number
Returns the current Unix time as a floating point number of seconds with microsecond precision.
```lua
local t0 = tick()
print("now", t0)
```
### Enum
[Section titled “Enum”](#enum)
Enum.\.\ : EnumItem
Global table of Roblox-mirror enums. Each `Enum.Type.Name` is an `EnumItem` exposing `.Name`, `.Value`, and `.EnumType`.
```lua
print(Enum.Material.Plastic.Name, Enum.Material.Plastic.Value)
part.Material = Enum.Material.Neon
```
Note
`task.wait` and `wait` yield the running script and resume it on a later frame. A one-shot `run` is capped at 30 seconds of wall time; resident, event-driven scripts have no cap. Coroutines started with `task.spawn`, `task.defer`, or `task.delay` stay alive until they finish or error, and an error prints `[task error]` to the run output. Only the `Enum` global is covered here; its individual members are data rather than methods, so they live under [`datatypes`](/reference/datatypes/).
# http
> HTTP request helpers (http.* namespace) plus the Roblox-mirror HttpService global for GET/POST, JSON encode/decode, GUID generation and URL encoding.
## `http`
[Section titled “http”](#http)
HTTP request helpers (http.\* namespace) plus the Roblox-mirror HttpService global for GET/POST, JSON encode/decode, GUID generation and URL encoding.
### http.Request
[Section titled “http.Request”](#httprequest)
http.Request(options: {Url: string, \[Uri]: string, \[Method]: string, \[Body]: string, \[Headers]: table}) -> {Success: boolean, StatusCode: number, StatusMessage: string, Body: string, Headers: table}
Performs an HTTP request described by an options table and returns a Roblox-style response table.
```lua
local res = http.Request({Url = "https://example.com/api", Method = "POST", Body = "{}", Headers = {["Content-Type"] = "application/json"}})
print(res.StatusCode, res.Body)
```
### http.Get
[Section titled “http.Get”](#httpget)
http.Get(url: string) -> string
Issues an HTTP GET request and returns the raw response body.
```lua
local body = http.Get("https://example.com")
```
### http.Post
[Section titled “http.Post”](#httppost)
http.Post(url: string, body: string?, contentType: string?) -> string
Issues an HTTP POST request with an optional body and Content-Type header (default application/json), returning the raw response body.
```lua
local body = http.Post("https://example.com/api", "{\"x\":1}", "application/json")
```
### HttpService:JSONEncode
[Section titled “HttpService:JSONEncode”](#httpservicejsonencode)
HttpService:JSONEncode(value: any) -> string
Encodes a Lua value as a JSON string.
```lua
local json = HttpService:JSONEncode({a = 1, b = "two"})
```
### HttpService:JSONDecode
[Section titled “HttpService:JSONDecode”](#httpservicejsondecode)
HttpService:JSONDecode(json: string) -> any
Decodes a JSON string into a Lua value (table, string, number, boolean or nil).
```lua
local data = HttpService:JSONDecode("{\"a\":1}")
```
### HttpService:GenerateGUID
[Section titled “HttpService:GenerateGUID”](#httpservicegenerateguid)
HttpService:GenerateGUID(wrapInCurlyBraces: boolean?) -> string
Generates a random version-4 UUID string, optionally wrapped in curly braces (defaults to true, matching Roblox).
```lua
local id = HttpService:GenerateGUID(false)
```
### HttpService:GetAsync
[Section titled “HttpService:GetAsync”](#httpservicegetasync)
HttpService:GetAsync(url: string) -> string
Issues an HTTP GET request and returns the raw response body. Also callable as `HttpGet` or `HttpGetAsync`.
```lua
local body = HttpService:GetAsync("https://example.com")
```
### HttpService:PostAsync
[Section titled “HttpService:PostAsync”](#httpservicepostasync)
HttpService:PostAsync(url: string, body: string?, contentType: string?) -> string
Issues an HTTP POST request with an optional body and Content-Type header (default application/json), returning the raw response body. Also callable as `HttpPost` or `HttpPostAsync`.
```lua
local body = HttpService:PostAsync("https://example.com/api", "{}")
```
### HttpService:UrlEncode
[Section titled “HttpService:UrlEncode”](#httpserviceurlencode)
HttpService:UrlEncode(str: string) -> string
Percent-encodes a string for safe use in a URL.
```lua
local enc = HttpService:UrlEncode("a b&c")
```
### HttpGet
[Section titled “HttpGet”](#httpget-1)
HttpGet(url: string) -> string
Alias for HttpService:GetAsync, recognized on any instance exposing it.
```lua
local body = game:HttpGet("https://example.com")
```
### HttpGetAsync
[Section titled “HttpGetAsync”](#httpgetasync)
HttpGetAsync(url: string) -> string
Alias for HttpService:GetAsync.
```lua
local body = game:HttpGetAsync("https://example.com")
```
### HttpPost
[Section titled “HttpPost”](#httppost-1)
HttpPost(url: string, body: string) -> string
Alias for HttpService:PostAsync.
```lua
local res = game:HttpPost(url, data)
```
### HttpPostAsync
[Section titled “HttpPostAsync”](#httppostasync)
HttpPostAsync(url: string, body: string) -> string
Alias for HttpService:PostAsync.
```lua
local res = game:HttpPostAsync(url, data)
```
Note
Requests are locked to `http`/`https` for both the initial URL and any redirects. The `HttpGet`, `HttpGetAsync`, `HttpPost`, and `HttpPostAsync` names work as aliases for `GetAsync`/`PostAsync`, so anything exposing them behaves just like `HttpService`. The [`server`](#server) helpers below are a separate namespace.
## `server`
[Section titled “server”](#server)
Helpers for building Roblox launch URLs, listing public game servers, and joining a place or a specific server by relaunching the game client.
### server.MakeLaunchUrl
[Section titled “server.MakeLaunchUrl”](#servermakelaunchurl)
server.MakeLaunchUrl(placeId: number, jobId: string?) -> string
Builds a roblox://experiences/start launch URL for a place, optionally targeting a specific server job id.
```lua
local url = server.MakeLaunchUrl(123974602339071, "job-guid-here")
print(url)
```
### server.FetchPublic
[Section titled “server.FetchPublic”](#serverfetchpublic)
server.FetchPublic(placeId: number, cursor: string?, sortOrder: string?) -> table
Fetches a page of public servers for a place from the Roblox games API and returns the decoded JSON as a table (up to 100 per page; pass the returned nextPageCursor as cursor to page further). sortOrder “Asc” lists the emptiest servers first, “Desc” the fullest; the default order is fullest-first, so ask for “Asc” when you want low-population servers.
```lua
local page = server.FetchPublic(123974602339071, nil, "Asc")
for _, s in ipairs(page.data) do
print(s.id, s.playing .. "/" .. s.maxPlayers)
end
```
### server.Join
[Section titled “server.Join”](#serverjoin)
server.Join(placeId: number, jobId: string?)
Switches the running client to a place, or to a specific server when a job id (gameInstanceId) is given. Sober hands a roblox:// URI to its existing instance instead of teleporting, so Join cold-launches: it closes Sober, waits for the instance to exit, then reopens the deep link. The engine Conduit was attached to dies during the switch, so the dmdaemon re-acquires the relaunched client and running scripts rebind game on the new session.
```lua
-- join any public server for a place
server.Join(123974602339071)
-- join a specific server (job id from server.FetchPublic)
local page = server.FetchPublic(123974602339071, nil, "Asc")
server.Join(123974602339071, page.data[1].id)
```
Note
`server` is a plain global table. Call `server.MakeLaunchUrl(...)` and friends directly; they are not Instance methods.
# input
> Reads physical keyboard/mouse state from raw evdev devices and injects synthetic key/mouse events via a virtual uinput device, gated to when Sober is the focused window.
Reads physical keyboard/mouse state from raw evdev devices and injects synthetic key/mouse events via a virtual uinput device, gated to when Sober is the focused window.
## Read state
[Section titled “Read state”](#read-state)
### input.Available
[Section titled “input.Available”](#inputavailable)
input.Available() -> boolean
Returns true if at least one physical keyboard or mouse evdev device was discovered.
```lua
if input.Available() then print("input devices found") end
```
### input.Poll
[Section titled “input.Poll”](#inputpoll)
input.Poll()
Polls all discovered evdev devices once, updating held-key state and press/release edges.
```lua
input.Poll()
```
### input.Mouse1Down
[Section titled “input.Mouse1Down”](#inputmouse1down)
input.Mouse1Down() -> boolean
Returns true while the left mouse button is physically held down and Sober is focused.
```lua
if input.Mouse1Down() then print("LMB held") end
```
### input.Mouse2Down
[Section titled “input.Mouse2Down”](#inputmouse2down)
input.Mouse2Down() -> boolean
Returns true while the right mouse button is physically held down and Sober is focused.
```lua
if input.Mouse2Down() then print("RMB held") end
```
### input.Mouse3Down
[Section titled “input.Mouse3Down”](#inputmouse3down)
input.Mouse3Down() -> boolean
Returns true while the middle mouse button is physically held down and Sober is focused.
```lua
if input.Mouse3Down() then print("MMB held") end
```
### input.Mouse1Pressed
[Section titled “input.Mouse1Pressed”](#inputmouse1pressed)
input.Mouse1Pressed() -> boolean
Returns true once for the frame the left mouse button transitioned to pressed, consuming the edge.
```lua
if input.Mouse1Pressed() then print("LMB clicked") end
```
### input.Mouse2Pressed
[Section titled “input.Mouse2Pressed”](#inputmouse2pressed)
input.Mouse2Pressed() -> boolean
Returns true once for the frame the right mouse button transitioned to pressed, consuming the edge.
```lua
if input.Mouse2Pressed() then print("RMB clicked") end
```
### input.Mouse3Pressed
[Section titled “input.Mouse3Pressed”](#inputmouse3pressed)
input.Mouse3Pressed() -> boolean
Returns true once for the frame the middle mouse button transitioned to pressed, consuming the edge.
```lua
if input.Mouse3Pressed() then print("MMB clicked") end
```
### input.Mouse1Released
[Section titled “input.Mouse1Released”](#inputmouse1released)
input.Mouse1Released() -> boolean
Returns true once for the frame the left mouse button transitioned to released, consuming the edge.
```lua
if input.Mouse1Released() then print("LMB released") end
```
### input.Mouse2Released
[Section titled “input.Mouse2Released”](#inputmouse2released)
input.Mouse2Released() -> boolean
Returns true once for the frame the right mouse button transitioned to released, consuming the edge.
```lua
if input.Mouse2Released() then print("RMB released") end
```
### input.Mouse3Released
[Section titled “input.Mouse3Released”](#inputmouse3released)
input.Mouse3Released() -> boolean
Returns true once for the frame the middle mouse button transitioned to released, consuming the edge.
```lua
if input.Mouse3Released() then print("MMB released") end
```
### input.IsRobloxActive
[Section titled “input.IsRobloxActive”](#inputisrobloxactive)
input.IsRobloxActive() -> boolean
Polls input and returns true if Sober is currently the focused window.
```lua
if input.IsRobloxActive() then input.KeyPress("w") end
```
### input.IsKeyPressed
[Section titled “input.IsKeyPressed”](#inputiskeypressed)
input.IsKeyPressed(key: string|number) -> boolean
Returns true if the given key (key name string or raw Linux keycode) is currently held down and Sober is focused.
```lua
if input.IsKeyPressed("w") then print("W held") end
```
### input.IsKeyJustPressed
[Section titled “input.IsKeyJustPressed”](#inputiskeyjustpressed)
input.IsKeyJustPressed(key: string|number) -> boolean
Returns true once per physical key press, consuming the edge, use for toggles rather than held state.
```lua
if input.IsKeyJustPressed("e") then print("toggled") end
```
### input.IsMouse1Pressed
[Section titled “input.IsMouse1Pressed”](#inputismouse1pressed)
input.IsMouse1Pressed() -> boolean
Returns true while the left mouse button is currently held down and Sober is focused.
```lua
if input.IsMouse1Pressed() then print("LMB down") end
```
### input.IsMouse2Pressed
[Section titled “input.IsMouse2Pressed”](#inputismouse2pressed)
input.IsMouse2Pressed() -> boolean
Returns true while the right mouse button is currently held down and Sober is focused.
```lua
if input.IsMouse2Pressed() then print("RMB down") end
```
## Keyboard output
[Section titled “Keyboard output”](#keyboard-output)
### input.KeyPress
[Section titled “input.KeyPress”](#inputkeypress)
input.KeyPress(key: string|number)
Sends a synthetic key-down event for the given key via the virtual input device.
```lua
input.KeyPress("space")
```
### input.KeyRelease
[Section titled “input.KeyRelease”](#inputkeyrelease)
input.KeyRelease(key: string|number)
Sends a synthetic key-up event for the given key via the virtual input device.
```lua
input.KeyRelease("space")
```
### keyboard.IsPressed
[Section titled “keyboard.IsPressed”](#keyboardispressed)
keyboard.IsPressed(key: string|number): boolean
Returns whether the given key is currently held down, false if Sober is not focused.
```lua
if keyboard.IsPressed("space") then print("jumping") end
```
### keyboard.Press
[Section titled “keyboard.Press”](#keyboardpress)
keyboard.Press(key: string|number, holdMs: number?)
Synthetically presses a key down, optionally auto-releasing it after holdMs milliseconds (capped at 5000).
```lua
keyboard.Press("w")
keyboard.Press("e", 200)
```
### keyboard.Release
[Section titled “keyboard.Release”](#keyboardrelease)
keyboard.Release(key: string|number)
Synthetically releases a key that is currently held down.
```lua
keyboard.Release("w")
```
### keyboard.Click
[Section titled “keyboard.Click”](#keyboardclick)
keyboard.Click(key: string|number, holdMs: number?)
Presses and releases a key, holding for holdMs milliseconds (default 15, capped at 5000).
```lua
keyboard.Click("f")
```
## Mouse output
[Section titled “Mouse output”](#mouse-output)
### input.Mouse1Press
[Section titled “input.Mouse1Press”](#inputmouse1press)
input.Mouse1Press()
Sends a synthetic left mouse button down event.
```lua
input.Mouse1Press()
```
### input.Mouse1Release
[Section titled “input.Mouse1Release”](#inputmouse1release)
input.Mouse1Release()
Sends a synthetic left mouse button up event.
```lua
input.Mouse1Release()
```
### input.Mouse1Click
[Section titled “input.Mouse1Click”](#inputmouse1click)
input.Mouse1Click()
Sends a synthetic left mouse click, press followed by a short delay then release.
```lua
input.Mouse1Click()
```
### input.Mouse2Press
[Section titled “input.Mouse2Press”](#inputmouse2press)
input.Mouse2Press()
Sends a synthetic right mouse button down event.
```lua
input.Mouse2Press()
```
### input.Mouse2Release
[Section titled “input.Mouse2Release”](#inputmouse2release)
input.Mouse2Release()
Sends a synthetic right mouse button up event.
```lua
input.Mouse2Release()
```
### input.Mouse2Click
[Section titled “input.Mouse2Click”](#inputmouse2click)
input.Mouse2Click()
Sends a synthetic right mouse click, press followed by a short delay then release.
```lua
input.Mouse2Click()
```
### input.MouseScroll
[Section titled “input.MouseScroll”](#inputmousescroll)
input.MouseScroll(amount: number)
Sends a synthetic mouse wheel scroll event of the given amount.
```lua
input.MouseScroll(-1)
```
### input.MouseMoveRel
[Section titled “input.MouseMoveRel”](#inputmousemoverel)
input.MouseMoveRel(dx: number, dy: number)
Sends a synthetic relative mouse movement of the given device pixel delta.
```lua
input.MouseMoveRel(10, 0)
```
### input.MouseMoveAbs
[Section titled “input.MouseMoveAbs”](#inputmousemoveabs)
input.MouseMoveAbs(x: number, y: number) -> nil
Moves the mouse toward an absolute screen position by computing and sending a relative delta from the engine’s current cursor location, may need repeat calls to converge under pointer acceleration.
```lua
input.MouseMoveAbs(500, 300)
```
### mouse.IsClicked
[Section titled “mouse.IsClicked”](#mouseisclicked)
mouse.IsClicked(button: number) -> boolean
Returns true if the given mouse button is currently held down and Roblox is focused.
```lua
if mouse.IsClicked(1) then print("left button held") end
```
### mouse.Press
[Section titled “mouse.Press”](#mousepress)
mouse.Press(button: number) -> ()
Synthesizes a button-down event for the given mouse button.
```lua
mouse.Press(1)
```
### mouse.Release
[Section titled “mouse.Release”](#mouserelease)
mouse.Release(button: number) -> ()
Synthesizes a button-up event for the given mouse button.
```lua
mouse.Release(1)
```
### mouse.Click
[Section titled “mouse.Click”](#mouseclick)
mouse.Click(button: number, holdMs: number?) -> ()
Presses and releases the given mouse button, holding for an optional duration in milliseconds (default 15ms, clamped to 5000ms).
```lua
mouse.Click(1, 50)
```
### mouse.Scroll
[Section titled “mouse.Scroll”](#mousescroll)
mouse.Scroll(amount: number) -> ()
Emits a relative mouse wheel scroll event of the given amount.
```lua
mouse.Scroll(-1)
```
## Focus
[Section titled “Focus”](#focus)
### input.SetRobloxInput
[Section titled “input.SetRobloxInput”](#inputsetrobloxinput)
input.SetRobloxInput(enabled: boolean)
Enables or disables whether synthetic key/mouse press events are sent to Sober, releases always still go through.
```lua
input.SetRobloxInput(false)
```
Note
Key names are either a lowercase string (`"w"`, `"space"`, `"f1"`, `"lctrl"`, and so on) or a raw Linux keycode number. Mouse buttons are addressed by number, matching the `Mouse1`/`Mouse2`/`Mouse3` helpers. Press and click events only reach the game while Sober is the focused window and `input.SetRobloxInput` is on (the default); release events always go through, so a key can never stick down when you alt-tab. The `input`, `mouse`, and `keyboard` tables read and drive the same underlying state, so mixing them is fine.
# memory
> Raw process-memory access into the attached Roblox engine (reads, writes, scanning, region mapping, watch helpers).
Raw process-memory access into the attached Roblox engine (reads, writes, scanning, region mapping, watch helpers).
## Attach & addresses
[Section titled “Attach & addresses”](#attach--addresses)
### memory.IsEnabled
[Section titled “memory.IsEnabled”](#memoryisenabled)
memory.IsEnabled() -> boolean
Returns true if Conduit is attached to a running engine.
```lua
if memory.IsEnabled() then print("attached") end
```
### memory.GetBase
[Section titled “memory.GetBase”](#memorygetbase)
memory.GetBase() -> number
Returns the base address of the engine module.
```lua
local base = memory.GetBase()
```
### memory.IsValid
[Section titled “memory.IsValid”](#memoryisvalid)
memory.IsValid(address: number) -> boolean
Returns true if the given address is currently readable in the engine process.
```lua
if memory.IsValid(addr) then print("readable") end
```
### memory.AddressOf
[Section titled “memory.AddressOf”](#memoryaddressof)
memory.AddressOf(instance: Instance) -> number?
Returns the native memory address backing a Roblox Instance, or nil if unresolved.
```lua
local addr = memory.AddressOf(workspace)
```
## Reading
[Section titled “Reading”](#reading)
### memory.Read
[Section titled “memory.Read”](#memoryread)
memory.Read(address: number, count: number) -> string?
Reads a raw byte buffer of up to 1 MiB from the given address, returned as a Lua string; nil on failed read.
```lua
local bytes = memory.Read(addr, 16)
```
### memory.ReadPointer
[Section titled “memory.ReadPointer”](#memoryreadpointer)
memory.ReadPointer(address: number) -> number?
Reads an 8-byte pointer value at the given address; nil on failed read.
```lua
local ptr = memory.ReadPointer(addr)
```
### memory.ReadString
[Section titled “memory.ReadString”](#memoryreadstring)
memory.ReadString(address: number, isCxxString: boolean, maxLen: number?, exact: boolean?) -> string?
Reads a string at the address, either as a C++ std::string (isCxxString true) or a raw buffer truncated at the first null unless exact is true.
```lua
local s = memory.ReadString(addr, false, 64)
```
### memory.ReadU8
[Section titled “memory.ReadU8”](#memoryreadu8)
memory.ReadU8(address: number) -> number?
Reads an unsigned 8-bit integer at the given address.
```lua
local v = memory.ReadU8(addr)
```
### memory.ReadI8
[Section titled “memory.ReadI8”](#memoryreadi8)
memory.ReadI8(address: number) -> number?
Reads a signed 8-bit integer at the given address.
```lua
local v = memory.ReadI8(addr)
```
### memory.ReadU16
[Section titled “memory.ReadU16”](#memoryreadu16)
memory.ReadU16(address: number) -> number?
Reads an unsigned 16-bit integer at the given address.
```lua
local v = memory.ReadU16(addr)
```
### memory.ReadI16
[Section titled “memory.ReadI16”](#memoryreadi16)
memory.ReadI16(address: number) -> number?
Reads a signed 16-bit integer at the given address.
```lua
local v = memory.ReadI16(addr)
```
### memory.ReadU32
[Section titled “memory.ReadU32”](#memoryreadu32)
memory.ReadU32(address: number) -> number?
Reads an unsigned 32-bit integer at the given address, returned as a Lua number (not coerced to int).
```lua
local v = memory.ReadU32(addr)
```
### memory.ReadI32
[Section titled “memory.ReadI32”](#memoryreadi32)
memory.ReadI32(address: number) -> number?
Reads a signed 32-bit integer at the given address.
```lua
local v = memory.ReadI32(addr)
```
### memory.ReadF32
[Section titled “memory.ReadF32”](#memoryreadf32)
memory.ReadF32(address: number) -> number?
Reads a 32-bit float at the given address.
```lua
local v = memory.ReadF32(addr)
```
### memory.ReadF64
[Section titled “memory.ReadF64”](#memoryreadf64)
memory.ReadF64(address: number) -> number?
Reads a 64-bit double at the given address.
```lua
local v = memory.ReadF64(addr)
```
### memory.ReadBool
[Section titled “memory.ReadBool”](#memoryreadbool)
memory.ReadBool(address: number) -> boolean?
Reads a single byte at the given address and returns it as a boolean; nil on failed read.
```lua
local flag = memory.ReadBool(addr)
```
## Writing
[Section titled “Writing”](#writing)
### memory.Write
[Section titled “memory.Write”](#memorywrite)
memory.Write(address: number, data: string) -> boolean
Writes a raw byte buffer (up to 1 MiB) to the given address.
```lua
memory.Write(addr, "\1\2\3")
```
### memory.WriteString
[Section titled “memory.WriteString”](#memorywritestring)
memory.WriteString(address: number, data: string) -> boolean
Writes a raw byte buffer (up to 1 MiB) to the given address; identical behavior to memory.Write.
```lua
memory.WriteString(addr, "hello")
```
### memory.WriteU8
[Section titled “memory.WriteU8”](#memorywriteu8)
memory.WriteU8(address: number, value: number) -> boolean
Writes an unsigned 8-bit integer at the given address.
```lua
memory.WriteU8(addr, 1)
```
### memory.WriteI8
[Section titled “memory.WriteI8”](#memorywritei8)
memory.WriteI8(address: number, value: number) -> boolean
Writes a signed 8-bit integer at the given address.
```lua
memory.WriteI8(addr, -1)
```
### memory.WriteU16
[Section titled “memory.WriteU16”](#memorywriteu16)
memory.WriteU16(address: number, value: number) -> boolean
Writes an unsigned 16-bit integer at the given address.
```lua
memory.WriteU16(addr, 1000)
```
### memory.WriteI16
[Section titled “memory.WriteI16”](#memorywritei16)
memory.WriteI16(address: number, value: number) -> boolean
Writes a signed 16-bit integer at the given address.
```lua
memory.WriteI16(addr, -1000)
```
### memory.WriteU32
[Section titled “memory.WriteU32”](#memorywriteu32)
memory.WriteU32(address: number, value: number) -> boolean
Writes an unsigned 32-bit integer at the given address.
```lua
memory.WriteU32(addr, 100)
```
### memory.WriteI32
[Section titled “memory.WriteI32”](#memorywritei32)
memory.WriteI32(address: number, value: number) -> boolean
Writes a signed 32-bit integer at the given address.
```lua
memory.WriteI32(addr, -100)
```
### memory.WriteF32
[Section titled “memory.WriteF32”](#memorywritef32)
memory.WriteF32(address: number, value: number) -> boolean
Writes a 32-bit float at the given address.
```lua
memory.WriteF32(addr, 1.5)
```
### memory.WriteF64
[Section titled “memory.WriteF64”](#memorywritef64)
memory.WriteF64(address: number, value: number) -> boolean
Writes a 64-bit double at the given address.
```lua
memory.WriteF64(addr, 1.5)
```
### memory.WriteBool
[Section titled “memory.WriteBool”](#memorywritebool)
memory.WriteBool(address: number, value: boolean) -> boolean
Writes a single byte (0 or 1) representing a boolean at the given address.
```lua
memory.WriteBool(addr, true)
```
## Scanning
[Section titled “Scanning”](#scanning)
### memory.ScanInstances
[Section titled “memory.ScanInstances”](#memoryscaninstances)
memory.ScanInstances(vtableAddress: number) -> {number}
Scans the engine for live instances matching the given vtable address and returns their addresses.
```lua
local hits = memory.ScanInstances(vt)
```
### memory.ScanVtable
[Section titled “memory.ScanVtable”](#memoryscanvtable)
memory.ScanVtable(vtableAddress: number) -> {number}
Alias for memory.ScanInstances.
```lua
local hits = memory.ScanVtable(vt)
```
### memory.Scan
[Section titled “memory.Scan”](#memoryscan)
memory.Scan(start: number, length: number, value: number, type: string?) -> {number}
Scans a memory region of up to 64 MiB for occurrences of a typed value (u8/i8/u16/i16/u32/i32/u64/i64/f32/f64, default u32) and returns matching addresses.
```lua
local hits = memory.Scan(base, 0x100000, 100, "i32")
```
### memory.AobScan
[Section titled “memory.AobScan”](#memoryaobscan)
memory.AobScan(start: number, length: number, pattern: string) -> {number}
Scans a memory region of up to 64 MiB for a byte pattern (hex tokens with ? or \* wildcards) and returns matching addresses.
```lua
local hits = memory.AobScan(base, 0x100000, "48 8B ?? ?? 89")
```
### memory.ScanSignature
[Section titled “memory.ScanSignature”](#memoryscansignature)
memory.ScanSignature(start: number, length: number, pattern: string) -> {number}
Alias for memory.AobScan.
```lua
local hits = memory.ScanSignature(base, 0x100000, "48 8B ??")
```
## Watch & map
[Section titled “Watch & map”](#watch--map)
### memory.WatchAccess
[Section titled “memory.WatchAccess”](#memorywatchaccess)
memory.WatchAccess(address: number, len: number?, rw: number?, timeout: number?) -> table?, string?
Arms a hardware watchpoint (requires root/kernel module) and blocks until the engine accesses the address, returning the faulting RIP and general-purpose registers, or nil plus an error string on timeout or arm failure.
```lua
local info = memory.WatchAccess(addr, 8, 3, 5)
if info then print(info.rip) end
```
### memory.MapRegion
[Section titled “memory.MapRegion”](#memorymapregion)
memory.MapRegion(base: number, len: number, mode: string?) -> boolean
Maps a memory region of up to 256 MiB into the kernel-shared read path for fast repeated access; mode is “stable” (default) or “heap”.
```lua
memory.MapRegion(base, 0x1000, "stable")
```
### memory.MapZap
[Section titled “memory.MapZap”](#memorymapzap)
memory.MapZap() -> ()
Clears the currently mapped region’s cached contents.
```lua
memory.MapZap()
```
### memory.UnmapRegion
[Section titled “memory.UnmapRegion”](#memoryunmapregion)
memory.UnmapRegion() -> ()
Unmaps the currently mapped memory region.
```lua
memory.UnmapRegion()
```
### memory.IsMapped
[Section titled “memory.IsMapped”](#memoryismapped)
memory.IsMapped(address: number) -> boolean
Returns true if the given address falls within the currently mapped region.
```lua
if memory.IsMapped(addr) then print("mapped") end
```
### memory.Watch
[Section titled “memory.Watch”](#memorywatch)
memory.Watch(address: number, type: string?, callback: function, interval: number?) -> table
Polls a typed value at an address on an interval (default 0.1s) via a spawned task and invokes callback(newValue, oldValue) on change; returns a handle with a Stop method. Implemented in Lua on top of the typed Read functions, type is one of u8/i8/u16/i16/u32/i32/f32/f64/ptr/bool (default u32).
```lua
local w = memory.Watch(addr, "i32", function(new, old) print(new, old) end, 0.25)
w:Stop()
```
### memory.CreateWriteLoop
[Section titled “memory.CreateWriteLoop”](#memorycreatewriteloop)
memory.CreateWriteLoop(address: number, value: number | string, type: string?) -> WriteLoop
Registers a value to be written to the address every frame, holding it against the game. Returns a handle with Stop() and Set(value). type is one of u8/i8/u16/i16/u32/i32/u64/i64/f32/f64/bool/ptr/string (default u32).
```lua
local loop = memory.CreateWriteLoop(addr, 100, "f32")
loop:Set(120)
loop:Stop()
```
### memory.ImmediateWatch
[Section titled “memory.ImmediateWatch”](#memoryimmediatewatch)
memory.ImmediateWatch(address: number, type: string?, callback: function) -> Watch
Watches an address on the per-frame loop and calls callback(new, old) whenever the value changes. Returns a handle with Stop(). type is one of u8/i8/u16/i16/u32/i32/u64/i64/f32/f64/bool/ptr (default u32).
```lua
local w = memory.ImmediateWatch(addr, "i32", function(new, old) print(new, old) end)
w:Stop()
```
Note
All addresses are Lua numbers (doubles) representing engine-process virtual addresses; memory.\* requires Conduit to be attached to a running engine (see memory.IsEnabled), otherwise calls error with “memory: no engine”. Read/Write are capped at 1 MiB per call; Scan/AobScan are capped at 64 MiB per region. ScanSignature and ScanVtable are plain aliases of AobScan and ScanInstances respectively.
# mesh
> Read mesh geometry (vertices and faces) for MeshParts, from cached URLs or by resolving a MeshPart instance.
Read mesh geometry (vertices and faces) for MeshParts, from cached URLs or by resolving a MeshPart instance.
### mesh.List
[Section titled “mesh.List”](#meshlist)
mesh.List() -> {string, ...}
Returns an array of all mesh content URLs currently known in the engine’s mesh cache.
```lua
for _, url in ipairs(mesh.List()) do
print(url)
end
```
### mesh.Get
[Section titled “mesh.Get”](#meshget)
mesh.Get(urlOrId: string) -> {url: string, vertices: {{x: number, y: number, z: number}, ...}, faces: {{number, number, number}, ...}} | nil
Fetches a mesh snapshot by exact cache URL, or by numeric asset id which matches any cached URL containing id=; returns nil if not found.
```lua
local m = mesh.Get("rbxassetid://123456789")
if m then
print(#m.vertices, #m.faces)
end
```
### mesh.OfPart
[Section titled “mesh.OfPart”](#meshofpart)
mesh.OfPart(part: Instance) -> {url: string, vertices: {{x: number, y: number, z: number}, ...}, faces: {{number, number, number}, ...}} | nil
Resolves the MeshId URL of a MeshPart instance and returns its mesh snapshot, or nil if the URL is empty or not in the cache.
```lua
local part = workspace.SomeMeshPart
local m = mesh.OfPart(part)
if m then
print(m.url)
end
```
### mesh.PartUrl
[Section titled “mesh.PartUrl”](#meshparturl)
mesh.PartUrl(part: Instance) -> string
Returns the raw resolved mesh content URL of a MeshPart instance, or an empty string if it has none; useful to distinguish a missing URL from a URL not yet in the cache when mesh.OfPart returns nil.
```lua
local url = mesh.PartUrl(workspace.SomeMeshPart)
if url == "" then
print("no mesh url")
end
```
Note
All four functions require the target to be a MeshPart (checked via is\_a) for mesh.OfPart and mesh.PartUrl, otherwise they raise a Lua argument error. mesh.List and mesh.Get depend on offsets being derived (sudo conduit-ext mesh-derive) and MeshContentProvider being reachable; they return empty/nil results otherwise rather than erroring.
# physics
> Bounded-cost geometric queries and Workspace raycasting against BasePart collision shapes.
Bounded-cost geometric queries and Workspace raycasting against BasePart collision shapes.
### physics.RaycastBox
[Section titled “physics.RaycastBox”](#physicsraycastbox)
physics.RaycastBox(origin: Vector3, direction: Vector3, cframe: CFrame, size: Vector3) -> RaycastResult | nil
Casts a ray segment from origin along direction against a single oriented box and returns a RaycastResult (Position, Normal, Distance, Instance=nil, Material=Plastic) on hit or nil on miss.
```lua
local hit = physics.RaycastBox(Vector3.new(0,10,0), Vector3.new(0,-20,0), part.CFrame, part.Size)
if hit then print(hit.Position) end
```
### physics.PointInBox
[Section titled “physics.PointInBox”](#physicspointinbox)
physics.PointInBox(point: Vector3, cframe: CFrame, size: Vector3) -> boolean
Returns true if point lies inside the oriented box defined by cframe and size.
```lua
local inside = physics.PointInBox(hrp.Position, part.CFrame, part.Size)
```
### physics.PointInRegion3
[Section titled “physics.PointInRegion3”](#physicspointinregion3)
physics.PointInRegion3(point: Vector3, region: Region3) -> boolean
Returns true if point lies inside the axis-aligned bounds of a Region3.
```lua
local inside = physics.PointInRegion3(hrp.Position, region)
```
### physics.Raycast
[Section titled “physics.Raycast”](#physicsraycast)
physics.Raycast(\[self: Instance,] origin: Vector3, direction: Vector3, \[ignoreList: {Instance}]) -> RaycastResult | nil
Depth-first walks Workspace up to the configured instance budget and returns the closest BasePart hit along the ray as a RaycastResult, or nil on miss, rate limit, or when disabled; blocking and unsafe to call from a per-frame paint or update callback.
```lua
local result = physics.Raycast(Vector3.new(0,50,0), Vector3.new(0,-100,0), {character})
if result then print(result.Instance, result.Position) end
```
### physics.RaycastBudget
[Section titled “physics.RaycastBudget”](#physicsraycastbudget)
physics.RaycastBudget(n: number) -> ()
Sets the maximum number of Workspace instances examined per physics.Raycast call, clamped to at least 1.
```lua
physics.RaycastBudget(4000)
```
### physics.RaycastEnabled
[Section titled “physics.RaycastEnabled”](#physicsraycastenabled)
physics.RaycastEnabled(enabled: boolean) -> ()
Enables or disables physics.Raycast; while disabled every call returns nil immediately.
```lua
physics.RaycastEnabled(false)
```
### physics.RaycastRate
[Section titled “physics.RaycastRate”](#physicsraycastrate)
physics.RaycastRate(castsPerSecond: number) -> ()
Caps how often physics.Raycast may fire per second, dropping over-rate calls as a miss (nil); a value of 0 or less removes the cap.
```lua
physics.RaycastRate(30)
```
Note
physics.Raycast only tests BasePart instances (excluding Terrain) and reports Material as Plastic when the engine’s Material getter is unavailable. RaycastBudget/RaycastEnabled/RaycastRate tune the bounded Workspace walk to avoid crashing Sober with a broad memory sweep. For a non-blocking cached alternative that is safe to call every frame, see [raycast](/reference/raycast/).
# raycast
> Non-blocking line-of-sight and cast queries served from the cached collidable world, safe to call every frame.
Non-blocking line-of-sight and cast queries served from the cached collidable world, safe to call every frame.
Unlike [physics.Raycast](/reference/physics/), which does a live blocking walk of Workspace, the `raycast` library answers from a cached snapshot of static collidable geometry that Conduit keeps refreshed in the background. Every function here is cheap enough to call from an `onPaint` or `onUpdate` callback.
### raycast.cast
[Section titled “raycast.cast”](#raycastcast)
raycast.cast(origin: Vector3, direction: Vector3, \[distance: number]) -> RaycastResult | nil
Casts a ray from origin along direction against the cached collidable world and returns the nearest hit as a RaycastResult (Position, Normal, Distance, Instance, Material), or nil when nothing is hit. Pass distance to cap the ray at that many studs; omit it and the ray extends to the length of direction. direction is not normalized for you, so pass a unit vector when you want distance to mean studs.
```lua
local hit = raycast.cast(camera.CFrame.Position, camera.CFrame.LookVector, 500)
if hit then print(hit.Instance, hit.Position) end
```
### raycast.between
[Section titled “raycast.between”](#raycastbetween)
raycast.between(origin: Vector3, target: Vector3) -> RaycastResult | nil
Casts a ray from origin to target and returns the nearest hit between them as a RaycastResult, or nil when the segment is clear. The ray stops at target, so this is the segment form of cast.
```lua
local hit = raycast.between(myHead, enemyHead)
if not hit then print("clear line to target") end
```
### raycast.visible
[Section titled “raycast.visible”](#raycastvisible)
raycast.visible(origin: Vector3, target: Vector3) -> boolean
Returns true when the straight line from origin to target is unobstructed. This is the terrain-aware sightline test: it accounts for terrain, opaque parts, and glass, where cast and between test collidable parts only. Use it for wall checks when you only need a yes or no answer.
```lua
if raycast.visible(myHead, enemyTorso) then
-- enemyTorso is in the open
end
```
### raycast.update
[Section titled “raycast.update”](#raycastupdate)
raycast.update() -> ()
Forces the cached collidable world to re-read every tracked part now, throttled to once per second. The cache refreshes on its own, so you only need this when the world just changed (a door opened, a wall was removed) and you must query the new state this frame. Calls made within a second of the last refresh are ignored.
```lua
openTheGate()
raycast.update()
local hit = raycast.between(a, b)
```
### raycast.ready
[Section titled “raycast.ready”](#raycastready)
raycast.ready() -> boolean
Returns true once the collidable-world cache has finished its initial build and is serving. Before this, cast and between return nil and visible returns true, because nothing is yet known to occlude. Gate aim or trigger logic on ready() so an early frame after a join or place change is not treated as a clear shot.
```lua
cheat.Register("onUpdate", function()
if not raycast.ready() then return end
-- visibility answers are trustworthy from here
end)
```
Note
cast and between serve static collidable geometry (parts filtered by CanCollide and minimum size, terrain excluded). For a terrain-aware sightline use raycast.visible; for a live cast against every BasePart use [physics.Raycast](/reference/physics/). Material reports Plastic until the engine’s Material value is resolved for this build.
# rendering
> World-to-screen projection, viewport control, and convex hull helpers for drawing overlays.
World-to-screen projection, viewport control, and convex hull helpers for drawing overlays.
### rendering.WorldToScreen
[Section titled “rendering.WorldToScreen”](#renderingworldtoscreen)
rendering.WorldToScreen(worldPos: Vector3, viewport: Vector2?) -> (screenPos: Vector2, onScreen: boolean, depth: number)
Projects a world space point to screen space using the active camera, optionally overriding the viewport size for this call.
```lua
local pos, onScreen, depth = rendering.WorldToScreen(Vector3.new(0, 5, 0))
if onScreen then print(pos.X, pos.Y, depth) end
```
### rendering.IsOnScreen
[Section titled “rendering.IsOnScreen”](#renderingisonscreen)
rendering.IsOnScreen(worldPos: Vector3) -> boolean
Returns true if the given world space point projects inside the current viewport bounds and is in front of the camera.
```lua
if rendering.IsOnScreen(part.Position) then
-- draw something
end
```
### rendering.MassProject
[Section titled “rendering.MassProject”](#renderingmassproject)
rendering.MassProject(points: {Vector3}) -> {\[integer]: {Position: Vector2, OnScreen: boolean, Depth: number}}
Projects a batch of world space points in one call, returning a table of screen results in the same order, entries with invalid Vector3 values are skipped.
```lua
local results = rendering.MassProject({Vector3.new(0,0,0), Vector3.new(10,0,0)})
for i, r in results do print(i, r.Position, r.OnScreen, r.Depth) end
```
### rendering.SetViewport
[Section titled “rendering.SetViewport”](#renderingsetviewport)
rendering.SetViewport(width: number, height: number)
Sets the fallback viewport size used when the Camera’s ViewportSize property cannot be read, values less than or equal to zero are ignored.
```lua
rendering.SetViewport(2560, 1440)
```
### rendering.GetViewport
[Section titled “rendering.GetViewport”](#renderinggetviewport)
rendering.GetViewport() -> Vector2
Returns the currently configured fallback viewport size as a Vector2.
```lua
local vp = rendering.GetViewport()
print(vp.X, vp.Y)
```
### rendering.ConvexHull2D
[Section titled “rendering.ConvexHull2D”](#renderingconvexhull2d)
rendering.ConvexHull2D(points: {Vector2}) -> {\[integer]: Vector2}
Computes the 2D convex hull of a set of screen space points using Andrew’s monotone chain algorithm, returning the hull vertices in counter-clockwise order.
```lua
local hull = rendering.ConvexHull2D({Vector2.new(0,0), Vector2.new(10,0), Vector2.new(5,10)})
for i, v in hull do print(v.X, v.Y) end
```
### rendering.ConvexHull3D
[Section titled “rendering.ConvexHull3D”](#renderingconvexhull3d)
rendering.ConvexHull3D(points: {Vector3}) -> {\[integer]: {Vector3, Vector3, Vector3}}
Computes the 3D convex hull of a set of world space points using an incremental algorithm, returning an array of triangular faces, each a 3-element array of Vector3 corners, degenerate input returns an empty table.
```lua
local faces = rendering.ConvexHull3D(pointCloud)
for i, tri in faces do print(tri[1], tri[2], tri[3]) end
```
Note
camera\_state() is TTL-cached for \~4ms internally, so repeated projection calls within the same frame are cheap. WorldToScreen’s onScreen check requires depth > 0 (in front of camera) and both screen coordinates within \[0, viewport].
# roblox
> The roblox namespace and the game global expose Conduit's read-only-DataModel-plus-writable-property Instance API, mirroring Roblox's game/Instance surface over the external Luau VM.
The roblox namespace and the game global expose Conduit’s read-only-DataModel-plus-writable-property Instance API, mirroring Roblox’s game/Instance surface over the external Luau VM.
## roblox namespace
[Section titled “roblox namespace”](#roblox-namespace)
### roblox.GetInstances
[Section titled “roblox.GetInstances”](#robloxgetinstances)
roblox.GetInstances() -> {Instance}
Returns every Instance currently reachable in the DataModel tree, capped at 100000 nodes.
```lua
for _, inst in roblox.GetInstances() do
print(inst:GetFullName())
end
```
### roblox.GetNilInstances
[Section titled “roblox.GetNilInstances”](#robloxgetnilinstances)
roblox.GetNilInstances() -> {Instance}
Returns Instances found via a GC scan whose Parent is nil, i.e. objects that exist but are detached from the DataModel tree.
```lua
local orphans = roblox.GetNilInstances()
print(#orphans)
```
### roblox.FindFirst
[Section titled “roblox.FindFirst”](#robloxfindfirst)
roblox.FindFirst(className: string) -> Instance?
Finds the first Instance of the given class name via a GC walk, so it works even for instances not reachable from game’s tree.
```lua
local cam = roblox.FindFirst("Camera")
```
## Instance properties
[Section titled “Instance properties”](#instance-properties)
### Instance.Name
[Section titled “Instance.Name”](#instancename)
Instance.Name -> string
The instance’s Name, read from the engine via indexing.
```lua
print(workspace.Name)
```
### Instance.ClassName
[Section titled “Instance.ClassName”](#instanceclassname)
Instance.ClassName -> string
The instance’s class name.
```lua
print(part.ClassName)
```
### Instance.Parent
[Section titled “Instance.Parent”](#instanceparent)
Instance.Parent -> Instance?
The instance’s parent, or nil at the DataModel root.
```lua
local p = part.Parent
```
### Instance.Address
[Section titled “Instance.Address”](#instanceaddress)
Instance.Address -> number
The raw userspace pointer backing the instance, as a number.
```lua
local addr = part.Address
```
## Tree navigation
[Section titled “Tree navigation”](#tree-navigation)
### Instance:GetChildren
[Section titled “Instance:GetChildren”](#instancegetchildren)
Instance:GetChildren() -> {Instance}
Returns a fresh array of the instance’s direct children.
```lua
for _, child in ipairs(workspace:GetChildren()) do print(child.Name) end
```
### Instance:FindFirstChild
[Section titled “Instance:FindFirstChild”](#instancefindfirstchild)
Instance:FindFirstChild(name: string, recursive: boolean?) -> Instance?
Returns the first direct child (or, if recursive is true, first descendant) matching name, or nil.
```lua
local hrp = character:FindFirstChild("HumanoidRootPart")
```
### Instance:FindFirstChildOfClass
[Section titled “Instance:FindFirstChildOfClass”](#instancefindfirstchildofclass)
Instance:FindFirstChildOfClass(className: string) -> Instance?
Returns the first direct child whose ClassName matches; workspace:FindFirstChildOfClass(“Camera”) is routed through a cached singleton lookup instead of a child walk.
```lua
local humanoid = character:FindFirstChildOfClass("Humanoid")
```
### Instance:GetDescendants
[Section titled “Instance:GetDescendants”](#instancegetdescendants)
Instance:GetDescendants(cap: number?) -> {Instance}
Returns every descendant in pre-order, capped at cap nodes (default 200000, 0 means unlimited); the cap argument is a bridge extension not present on real Roblox Instances.
```lua
local all = workspace:GetDescendants()
```
### Instance:GetFullName
[Section titled “Instance:GetFullName”](#instancegetfullname)
Instance:GetFullName() -> string
Returns the dot-separated path from the DataModel down to this instance.
```lua
print(part:GetFullName())
```
### Instance:IsAncestorOf
[Section titled “Instance:IsAncestorOf”](#instanceisancestorof)
Instance:IsAncestorOf(other: Instance) -> boolean
Returns true if this instance is an ancestor of other.
```lua
if workspace:IsAncestorOf(part) then print("in workspace") end
```
### Instance:IsDescendantOf
[Section titled “Instance:IsDescendantOf”](#instanceisdescendantof)
Instance:IsDescendantOf(ancestor: Instance) -> boolean
Returns true if ancestor is an ancestor of this instance; implemented as the reverse of IsAncestorOf.
```lua
if part:IsDescendantOf(workspace) then print("in workspace") end
```
### Instance:WaitForChild
[Section titled “Instance:WaitForChild”](#instancewaitforchild)
Instance:WaitForChild(name: string, timeout: number?) -> Instance?
Polls for a direct child named name every 30ms until found, until timeout elapses (default 5s, clamped to at most 30s), or until the engine closes; returns nil on timeout instead of hanging forever like live Roblox.
```lua
local hrp = character:WaitForChild("HumanoidRootPart", 10)
```
### Instance:IsInvalidInstance
[Section titled “Instance:IsInvalidInstance”](#instanceisinvalidinstance)
Instance:IsInvalidInstance() -> boolean
Returns true if the underlying engine object is no longer valid (destroyed or unreadable).
```lua
if part:IsInvalidInstance() then return end
```
### Instance:IsA
[Section titled “Instance:IsA”](#instanceisa)
Instance:IsA(className: string) -> boolean
Returns true if the instance’s class matches or inherits from className.
```lua
if part:IsA("BasePart") then print(part.Size) end
```
### Instance:FindFirstChildWhichIsA
[Section titled “Instance:FindFirstChildWhichIsA”](#instancefindfirstchildwhichisa)
Instance:FindFirstChildWhichIsA(className: string) -> Instance?
Returns the first direct child whose class matches or inherits from className, or nil.
```lua
local part = model:FindFirstChildWhichIsA("BasePart")
```
### Instance:FindFirstAncestor
[Section titled “Instance:FindFirstAncestor”](#instancefindfirstancestor)
Instance:FindFirstAncestor(name: string) -> Instance?
Walks up to 256 parents looking for one named name, or returns nil.
```lua
local model = part:FindFirstAncestor("MyModel")
```
### Instance:FindFirstAncestorOfClass
[Section titled “Instance:FindFirstAncestorOfClass”](#instancefindfirstancestorofclass)
Instance:FindFirstAncestorOfClass(className: string) -> Instance?
Walks up to 256 parents looking for an exact ClassName match, or returns nil.
```lua
local ws = part:FindFirstAncestorOfClass("Workspace")
```
### Instance:FindFirstAncestorWhichIsA
[Section titled “Instance:FindFirstAncestorWhichIsA”](#instancefindfirstancestorwhichisa)
Instance:FindFirstAncestorWhichIsA(className: string) -> Instance?
Walks up to 256 parents looking for one whose class matches or inherits from className, or returns nil.
```lua
local model = part:FindFirstAncestorWhichIsA("Model")
```
## Services & players
[Section titled “Services & players”](#services--players)
### Instance:GetService
[Section titled “Instance:GetService”](#instancegetservice)
Instance:GetService(className: string) -> Instance?
Searches the receiver’s direct children for one whose ClassName matches; called as game:GetService(name) it behaves like the real service lookup, but unlike Roblox it never creates a missing service, it just returns nil.
```lua
local players = game:GetService("Players")
```
### Instance:FindService
[Section titled “Instance:FindService”](#instancefindservice)
Instance:FindService(className: string) -> Instance?
Identical implementation to GetService in this bridge (both are non-creating finds); kept as a separate name for source compatibility.
```lua
local rs = game:FindService("ReplicatedStorage")
```
### Instance:GetPlayers
[Section titled “Instance:GetPlayers”](#instancegetplayers)
Instance:GetPlayers() -> {Instance}
Returns the direct children that are Player instances; normally called on the Players service.
```lua
for _, plr in ipairs(game:GetService("Players"):GetPlayers()) do print(plr.Name) end
```
### Instance:GetPlayerByUserId
[Section titled “Instance:GetPlayerByUserId”](#instancegetplayerbyuserid)
Instance:GetPlayerByUserId(userId: number) -> Instance?
Returns the child Player whose UserId matches, or nil; normally called on the Players service.
```lua
local plr = players:GetPlayerByUserId(123456)
```
### Instance:GetPlayerFromCharacter
[Section titled “Instance:GetPlayerFromCharacter”](#instancegetplayerfromcharacter)
Instance:GetPlayerFromCharacter(character: Instance) -> Instance?
Returns the child Player whose Name matches the given character model’s Name, or nil; normally called on the Players service.
```lua
local plr = players:GetPlayerFromCharacter(workspace.SomeCharacter)
```
## Attributes & properties
[Section titled “Attributes & properties”](#attributes--properties)
### Instance:GetAttribute
[Section titled “Instance:GetAttribute”](#instancegetattribute)
Instance:GetAttribute(name: string) -> (number | boolean | string | Vector3 | Vector2 | Color3)?
Returns the value of attribute name, or nil if the attribute doesn’t exist or its type isn’t one of the supported types.
```lua
local hp = npc:GetAttribute("MaxHP")
```
### Instance:GetAttributes
[Section titled “Instance:GetAttributes”](#instancegetattributes)
Instance:GetAttributes() -> {\[string]: (number | boolean | string | Vector3 | Vector2 | Color3)}
Returns a table of every attribute whose type is supported; attributes of unsupported types are silently skipped.
```lua
for name, value in pairs(npc:GetAttributes()) do print(name, value) end
```
### Instance:SetAttribute
[Section titled “Instance:SetAttribute”](#instancesetattribute)
Instance:SetAttribute(name: string, value: number | boolean | Vector3 | Vector2 | Color3) -> ()
Writes value into an attribute that already exists; errors if the attribute isn’t present (new attributes can’t be created from outside) or if value’s type doesn’t match the attribute’s existing type.
```lua
npc:SetAttribute("MaxHP", 150)
```
### Instance:GetProperties
[Section titled “Instance:GetProperties”](#instancegetproperties)
Instance:GetProperties() -> {string}
Returns the names of the instance’s readable properties (not their values); many properties use virtual getters that can’t be read generically.
```lua
for _, prop in ipairs(part:GetProperties()) do print(prop) end
```
### Instance:GetPlayingAnimationTracks
[Section titled “Instance:GetPlayingAnimationTracks”](#instancegetplayinganimationtracks)
Instance:GetPlayingAnimationTracks() -> {Instance}
Returns the AnimationTrack instances currently active on this instance’s Animator (or on self if self is already an Animator).
```lua
for _, track in ipairs(humanoid:GetPlayingAnimationTracks()) do print(track.Name) end
```
## Geometry & projection
[Section titled “Geometry & projection”](#geometry--projection)
### Instance:GetPivot
[Section titled “Instance:GetPivot”](#instancegetpivot)
Instance:GetPivot() -> CFrame
Returns the instance’s CFrame if it’s a BasePart, or the center of its descendants’ bounding box (identity rotation) otherwise; errors if a Model has no BaseParts.
```lua
local cf = model:GetPivot()
```
### Instance:GetBoundingBox
[Section titled “Instance:GetBoundingBox”](#instancegetboundingbox)
Instance:GetBoundingBox() -> (CFrame, Vector3)
Returns an axis-aligned CFrame at the center of, and the size of, the world-space bounding box over every BasePart descendant (Terrain excluded); errors if none are found.
```lua
local cf, size = model:GetBoundingBox()
```
### Instance:GetExtentsSize
[Section titled “Instance:GetExtentsSize”](#instancegetextentssize)
Instance:GetExtentsSize() -> Vector3
Returns just the size component of GetBoundingBox; errors if no BaseParts are found under the instance.
```lua
local size = model:GetExtentsSize()
```
### Instance:Raycast
[Section titled “Instance:Raycast”](#instanceraycast)
Instance:Raycast(origin: Vector3, direction: Vector3, ignoreList: {Instance}?) -> RaycastResult?
Depth-first walks Workspace (same underlying call as physics.Raycast) and returns the closest BasePart hit, or nil on miss, rate limit, or when raycasting is disabled; blocking, so unsafe to call from a per-frame paint or update callback.
```lua
local hit = workspace:Raycast(Vector3.new(0,50,0), Vector3.new(0,-100,0), {character})
```
### Instance:WorldToScreenPoint
[Section titled “Instance:WorldToScreenPoint”](#instanceworldtoscreenpoint)
Instance:WorldToScreenPoint(worldPos: Vector3) -> (Vector3, boolean)
Projects worldPos through the active Camera, returning a Vector3 of screen X, Y and depth, plus whether the point is within the viewport; errors if there is no active Camera.
```lua
local screen, onScreen = workspace.CurrentCamera:WorldToScreenPoint(part.Position)
```
### Instance:WorldToViewportPoint
[Section titled “Instance:WorldToViewportPoint”](#instanceworldtoviewportpoint)
Instance:WorldToViewportPoint(worldPos: Vector3) -> (Vector3, boolean)
Alias of WorldToScreenPoint; identical implementation.
```lua
local screen, onScreen = workspace.CurrentCamera:WorldToViewportPoint(part.Position)
```
### Instance:GetMouseLocation
[Section titled “Instance:GetMouseLocation”](#instancegetmouselocation)
Instance:GetMouseLocation() -> Vector2
Returns the current mouse cursor position; callable on any Instance since it ignores self.
```lua
local pos = game:GetMouseLocation()
```
Note
`game` is itself an Instance (its `ClassName` is `DataModel`), so every method above is callable on it directly, for example `game:GetService("Players")`, `game:FindFirstChild("Workspace")`, or `game:GetDescendants()`.
Note
You can read a property without calling a method for it. `.Name`, `.ClassName`, and `.Parent` come straight from the engine, `.Address` gives the raw pointer as a number, and any other name resolves to a live property read (numbers, strings, booleans, `Instance`, `Color3`, `Vector2`, `Vector3`, `CFrame`, `UDim2`). If the name is not a property, it falls back to a child lookup, so `game.Workspace` and `part.SomeChild` resolve without `FindFirstChild`. `FindService` and `WorldToViewportPoint` are aliases for `GetService` and `WorldToScreenPoint`. The `HttpService` helpers (`GetAsync`, `PostAsync`, `JSONEncode`, `JSONDecode`, `GenerateGUID`, `UrlEncode`) are reachable on any Instance but documented under [`http`](/reference/http/).
# settings
> Persistent key-value store for script/tool settings, backed by a JSON file in the user's config directory.
Persistent key-value store for script/tool settings, backed by a JSON file in the user’s config directory.
### settings.Set
[Section titled “settings.Set”](#settingsset)
settings.Set(key: string, value: any): ()
Sets a key to any Lua value in the settings table and persists it to disk immediately.
```lua
settings.Set("debug_logs", true)
```
### settings.Get
[Section titled “settings.Get”](#settingsget)
settings.Get(key: string, default: any?): any
Returns the stored value for key, or the given default if the key is absent or nil.
```lua
local speed = settings.Get("walk_speed", 16)
```
### settings.Has
[Section titled “settings.Has”](#settingshas)
settings.Has(key: string): boolean
Returns true if key exists in the settings table with a non-nil value.
```lua
if settings.Has("debug_logs") then print("set") end
```
### settings.Remove
[Section titled “settings.Remove”](#settingsremove)
settings.Remove(key: string): boolean
Deletes key from the settings table, persists the change, and returns whether the key had been present.
```lua
local existed = settings.Remove("old_key")
```
### settings.Keys
[Section titled “settings.Keys”](#settingskeys)
settings.Keys(): {string}
Returns an array table of all keys currently in the settings table.
```lua
for _, k in settings.Keys() do print(k) end
```
### settings.All
[Section titled “settings.All”](#settingsall)
settings.All(): {\[string]: any}
Returns a shallow copy of the entire settings table.
```lua
local all = settings.All()
```
### settings.Clear
[Section titled “settings.Clear”](#settingsclear)
settings.Clear(): ()
Empties the settings table and persists the empty state to disk.
```lua
settings.Clear()
```
### settings.Save
[Section titled “settings.Save”](#settingssave)
settings.Save(): ()
Explicitly writes the current settings table to disk; redundant with the auto-persist done by Set/Remove/Clear but kept as a defensive flush point.
```lua
settings.Save()
```
### settings.Load
[Section titled “settings.Load”](#settingsload)
settings.Load(): ()
Reloads the settings table from disk, discarding any in-memory changes not yet persisted.
```lua
settings.Load()
```
### settings.Path
[Section titled “settings.Path”](#settingspath)
settings.Path(): string
Returns the absolute filesystem path to the settings JSON store.
```lua
print(settings.Path())
```
Note
Backing file is /.config/conduit/settings.json, resolved via SUDO\_USER/HOME. The ‘debug\_logs’ key is mirrored into a C++ bool (settings\_debug\_logs) read by other subsystems. Writes are idempotent: identical content is not rewritten to disk.
# utility
> Executor/engine-meta helpers: identity, clipboard, notifications, FastFlags, and script bytecode tools (decode, disassemble, decompile, hash, compile).
Executor/engine-meta helpers: identity, clipboard, notifications, FastFlags, and script bytecode tools (decode, disassemble, decompile, hash, compile).
## Executor info
[Section titled “Executor info”](#executor-info)
### IdentifyExecutor
[Section titled “IdentifyExecutor”](#identifyexecutor)
utility.IdentifyExecutor() -> string name, string version
Returns the executor identity string and version, always “Conduit”, “1.0.0”.
```lua
local name, version = utility.IdentifyExecutor()
print(name, version)
```
### GetExecutorName
[Section titled “GetExecutorName”](#getexecutorname)
utility.GetExecutorName() -> string
Returns just the executor name, “Conduit”.
```lua
print(utility.GetExecutorName())
```
### GetBase
[Section titled “GetBase”](#getbase)
utility.GetBase() -> number | nil
Returns the base address of the attached Roblox engine process, or nil if not attached.
```lua
local base = utility.GetBase()
if base then print(string.format("0x%x", base)) end
```
## Clipboard & notify
[Section titled “Clipboard & notify”](#clipboard--notify)
### SetClipboard
[Section titled “SetClipboard”](#setclipboard)
utility.SetClipboard(text: string) -> boolean
Copies the given string to the system clipboard, returns whether it succeeded.
```lua
utility.SetClipboard("hello world")
```
### ToClipboard
[Section titled “ToClipboard”](#toclipboard)
utility.ToClipboard(text: string) -> boolean
Alias of SetClipboard, copies the given string to the system clipboard.
```lua
utility.ToClipboard("hello world")
```
### Notify
[Section titled “Notify”](#notify)
utility.Notify(\[title: string,] text: string)
Prints a notification to stdout, taking an optional title, since the external has no in-game toast.
```lua
utility.Notify("Conduit", "Script loaded")
```
## Fast flags
[Section titled “Fast flags”](#fast-flags)
### GetFFlag
[Section titled “GetFFlag”](#getfflag)
utility.GetFFlag(name: string) -> boolean | number | string | nil
Reads the current live value of a Roblox FastFlag by name (FFlag, FInt, FLog, or FString), returns nil if unknown or unattached.
```lua
local v = utility.GetFFlag("DebugRenderSkeleton")
print(v)
```
### SetFFlag
[Section titled “SetFFlag”](#setfflag)
utility.SetFFlag(name: string, value: boolean | number | string) -> boolean
Writes a new value to a live Roblox FastFlag by name, returns whether the write succeeded.
```lua
utility.SetFFlag("DebugRenderSkeleton", true)
```
### SetFFlags
[Section titled “SetFFlags”](#setfflags)
utility.SetFFlags(flags: {\[string]: boolean | number | string}) -> number set, number unknown, number failed
Applies a table of FastFlag name to value pairs in one call, returns counts of flags set, unknown, and failed.
```lua
local set, unknown, failed = utility.SetFFlags({DebugRenderSkeleton = true, FIntFoo = 5})
print(set, unknown, failed)
```
## Scripts & bytecode
[Section titled “Scripts & bytecode”](#scripts--bytecode)
### GetScriptBytecode
[Section titled “GetScriptBytecode”](#getscriptbytecode)
utility.GetScriptBytecode(script: Instance) -> string | nil
Reads and decodes the raw Luau bytecode retained by a script Instance, returns nil if it has none.
```lua
local bc = utility.GetScriptBytecode(script)
if bc then print(#bc) end
```
### DecodeScriptBytecode
[Section titled “DecodeScriptBytecode”](#decodescriptbytecode)
utility.DecodeScriptBytecode(blob: string) -> string | nil
Decodes a raw compressed bytecode blob into raw Luau bytecode, returns nil on decode failure.
```lua
local bc = utility.DecodeScriptBytecode(compressedBlob)
```
### Disassemble
[Section titled “Disassemble”](#disassemble)
utility.Disassemble(target: string | Instance) -> string | nil
Produces a Luau bytecode disassembly listing, accepting either raw already-decoded bytecode or a script Instance.
```lua
local listing = utility.Disassemble(script)
print(listing)
```
### Decompile
[Section titled “Decompile”](#decompile)
utility.Decompile(target: string | Instance) -> string | nil
Reconstructs Lua source from bytecode via the vendored Fission decompiler, accepting raw bytecode or a script Instance, returns nil only when no bytecode is retained.
```lua
local src = utility.Decompile(script)
print(src)
```
### GetScriptHash
[Section titled “GetScriptHash”](#getscripthash)
utility.GetScriptHash(target: string | Instance) -> string | nil
Returns a SHA-384 hex hash of the script’s bytecode, Conduit’s own hash rather than a Roblox-identical one.
```lua
local hash = utility.GetScriptHash(script)
print(hash)
```
### DumpString
[Section titled “DumpString”](#dumpstring)
utility.DumpString(source: string) -> string
Compiles a Lua source string into Luau bytecode, the inverse of Decompile, raises an error on a compile failure.
```lua
local bc = utility.DumpString("print('hi')")
```
Note
`tick()` is a bare Roblox-mirror global rather than a `utility` method, so it is documented under [`globals`](/reference/globals/).
# vm
> Raw Luau GC access for scanning, reading, and writing game-VM GC objects by key.
Raw Luau GC access for scanning, reading, and writing game-VM GC objects by key.
### GetGc
[Section titled “GetGc”](#getgc)
vm.GetGc(name: string | {string}?) -> {table}
With a key name or array of key names, does a by-key lookup and returns an array of entries with key, value, type, and addr fields. With no arguments, walks the whole GC heap and returns an array of entries with address, type, and typename fields for real GC-page objects.
```lua
local entries = vm.GetGc("Health")
for _, e in entries do print(e.key, e.value, e.type, e.addr) end
```
### SetGc
[Section titled “SetGc”](#setgc)
vm.SetGc(targets: table) -> number
Rescans the GC for entries matching the given key/value targets and writes each matching scalar in place, returning the count of successful writes.
```lua
local written = vm.SetGc({ Health = 100 })
print(written)
```
### ApplyGc
[Section titled “ApplyGc”](#applygc)
vm.ApplyGc(cache: {table}, targets: table) -> number
Writes the given key/value targets into the addresses already present in a table previously returned by vm.GetGc, without rescanning the GC heap.
```lua
local cache = vm.GetGc("Health")
local written = vm.ApplyGc(cache, { Health = 100 })
print(written)
```
Note
SetGc rescans the entire GC heap on every call and is slower than caching results with GetGc and then repeatedly calling ApplyGc on that cache. A target’s type must match the entry’s type or the write is skipped.