Yuari Docs

Documentation

Everything you need to write scripts for the Yuari External — a full Luau VM with instance, HTTP, drawing, filesystem and memory APIs.

How the VM works

Yuari External is not executor it does not hook any functions. Instead it emulates them externally, which makes it completely undetected, but also means it has no direct access to internal Roblox API functions.

  • Sandboxed environment — the base, table, string, math, utf8, coroutine and os libraries are loaded, but dangerous os.execute / os.exit are stripped.
  • Game bridge — instances are read directly from game memory. The globals game and workspace are live proxies that refresh each time the VM (re)initializes.
  • Event pumping — RunService / UserInputService / player signals are pumped from the external tick loop, so Heartbeat, InputBegan, PlayerAdded, CharacterAdded and friends all work from scripts.
  • Task scheduler — wait, spawn, delay and defer run on the VM's own scheduler thread.
  • Bytecode compat — loadstring / loadfile apply a Luau compatibility pass before compiling, so most popular scripts run unmodified.
Simple. The external emulates them externally, which makes it completely undetected.

Settings & toggles

Two optional toggles in the External's Options menu unlock additional functions. Both are off by default.

SettingUnlocks
Allow Unsafe LuaU Direct process memory access: memory_read, memory_write. Calling them while disabled raises "Unsafe Luau must be enabled".
Hybrid Luau Input-based game interaction: fireclickdetector, fireproximityprompt, firetouchinterest / firetouchtransmitter. Calling them while disabled raises "Hybrid Luau must be enabled".
Focus gate. Hybrid functions only fire while the Roblox window is focused, and the target must be resolvable on screen. Input injection is blocked while the game is not the active window.

Core functions

Globals available in every script. The full standard Luau library set (string, table, math, utf8, coroutine, os minus execute/exit) is also available.

print(...) / printl(...) / warn(...) / error(...) / errorl(...)

Write to the executor's output console. print-family logs at info level, warn at warning level, error-family at error level. printl and errorl are aliases.

identifyexecutor() → name, version

Returns "yuari" and the current version string.

local name, version = identifyexecutor()
print(name, version) -- yuari, 0.1
wait(seconds?) → yields

Yields the current thread for seconds (default 0.03). Resumes on the VM scheduler.

spawn(fn)

Runs fn immediately on a new coroutine. Errors are logged, not propagated.

tick() → number

Seconds elapsed since the VM started (a monotonic timer, not the Unix epoch).

typeof(value) → string

Type name for any value. VM userdata report as "Vector3", "Vector2", "CFrame", "Color3", "RBXScriptConnection" or "Drawing"; everything else uses standard Luau type names.

newproxy(addMeta?) → userdata

Creates a plain userdata, optionally with an empty metatable — same behaviour as Roblox.

gcinfo() → number (KB)

Approximate memory in use by the external VM, in kilobytes.

unpack(...) → ...

Alias of table.unpack.

notify(message, title?, duration?)

Shows a message in the executor console. title defaults to "Yuari", duration to 3 seconds.

GetPingValue() → number

Ping compatibility shim (currently returns 0).

getgamename() → string

Name of the current place (reads the Workspace name), or "Unknown".

base64encode(str) / base64decode(str) → string

Standard Base64 helpers.

task library

The Roblox-style task scheduler, backed by the external VM's own tick loop.

task.wait(seconds?) → yields

Yields for seconds (default 0.03).

task.spawn(fn)

Runs fn on a new thread immediately.

task.delay(seconds, fn) → thread handle

Schedules fn to run after seconds. Returns a handle usable with task.cancel.

task.defer(fn)

Runs fn as soon as the current thread yields.

task.cancel(thread)

Cancels a thread or a task.delay handle.

Instances

game (the DataModel) and workspace are instance proxies backed by live game memory. Property reads and method calls go straight to Roblox's own objects.

Globals & creation

game / workspace → Instance

Live proxies to the DataModel and Workspace. game.PlaceId, game.GameId and game.JobId are supported.

Instance.new(className, parent?) → Instance?

Creates an instance through Roblox's own class registry (with a creatability check) and optionally parents it. Returns nil and logs a reason on failure (class not found, not creatable, etc.).

local part = Instance.new("Part", workspace)
part.Name = "MyPart"
part.Position = Vector3.new(0, 10, 0)

Methods

:GetChildren() / :GetDescendants() → {Instance}

Direct children, or the full descendant tree.

:FindFirstChild(name) / :FindFirstChildOfClass(class) / :FindFirstChildWhichIsA(class)

First matching child, or nil.

:FindFirstAncestorOfClass(class) / :FindFirstAncestorWhichIsA(class)

First matching ancestor, or nil.

:WaitForChild(name, timeout?) → Instance?

Yields until the child exists (or times out).

:IsA(className) / :IsDescendantOf(ancestor) → boolean

Class checks understand common hierarchies (BasePart, Model, GuiObject, ValueBase, LuaSourceContainer, Tool, …).

:GetAttribute(name) / :SetAttribute(name, value) / :GetAttributes() → value / table

Reads/writes instance attributes.

:GetFullName() → string

Dotted path, e.g. "Workspace.Map.Spawn".

:GetService(className) → Instance?

Finds a top-level service by class name.

:GetPlayers() → {Player}

All current players (from the Players service).

:GetPropertyChangedSignal(property) → RBXScriptSignal

Fires when the given property changes.

:WorldToViewportPoint(vector) / :WorldToScreenPoint(vector) → Vector3, boolean

Projects a world position through the camera. Returns (x, y, depth) in screen space plus true when on screen.

local cam = workspace.CurrentCamera
local pos, visible = cam:WorldToViewportPoint(target.Position)
if visible then
    print(math.floor(pos.X), math.floor(pos.Y), pos.Z)
end
:GetPivot() → CFrame

Pivot of a Model (uses its PrimaryPart).

:Destroy()

Removes the instance by unparenting it.

:EquipTool(tool) / :UnequipTools()

Equips a Tool on a character through the game's own bound functions.

:Fire()

Fires a BindableEvent (any arguments) or a ProximityPrompt (defaults the player argument to the local player).

Properties

ClassReadableWritable
AnyName, ClassName, Parent, AddressParent (set to nil to unparent)
DataModelPlaceId, GameId, JobId, Workspace—
PlayersLocalPlayer—
PlayerCharacter, DisplayName, UserId, Team, Mouse, GetMouse()—
WorkspaceCurrentCamera—
BasePartPosition, CFramePosition, CFrame, Size, Transparency, Anchored, Velocity/AssemblyLinearVelocity, CanCollide, Color
HumanoidHealthHealth, MaxHealth, WalkSpeed, JumpPower, JumpHeight
LightingBrightness, ClockTime, FogStart, FogEnd, GlobalShadows, Ambient, OutdoorAmbient, FogColorsame as readable
CameraFieldOfViewFieldOfView
Value objectsValue (Bool, Int, Number, String, Object, Vector3)Value

Signals exposed on instances

InstanceSignal
AnyChildAdded, ChildRemoved, DescendantAdded
PlayersPlayerAdded, PlayerRemoving
PlayerCharacterAdded
BindableEventEvent
RemoteEvent / UnreliableRemoteEventOnClientEvent
ProximityPromptTriggered

Hybrid interaction functions

These require the Hybrid Luau toggle and a focused game window.

Hybrid Luau
fireclickdetector(clickDetectorOrPart, distance?, event?)

Synthesizes a click at the detector's on-screen position. event may be "MouseClick" (default), "RightMouseClick", "MouseHoverEnter" or "MouseHoverLeave". Accepts either the ClickDetector or its parent BasePart. The cursor is restored afterwards.

Hybrid Luau
fireproximityprompt(prompt)

Triggers a ProximityPrompt by simulating the hold interaction on its parent part.

Hybrid Luau
firetouchinterest(part, mover?, touch?) / firetouchtransmitter(...)

Simulates a Touched event by briefly moving the local character's HumanoidRootPart (or a custom mover) onto part. Pass false/0 as the third argument for a no-op (untequal) touch. firetouchtransmitter is an alias.

Data types

Roblox-style value types implemented as VM userdata, with full operator overloading and typeof support.

Vector3

MemberDescription
Vector3.new(x?, y?, z?)Constructor (also callable directly: Vector3(1,2,3)). Copy-constructs from another Vector3.
.X .Y .ZComponents (also lowercase).
.MagnitudeLength of the vector.
.UnitNormalized copy (zero vector if length ≈ 0).
:Dot(other)Dot product.
:Cross(other)Cross product.
:Lerp(other, alpha)Linear interpolation.
Operators+ - * /, unary -, == (* also accepts a scalar).
ConstantsVector3.zero, .one, .xAxis, .yAxis, .zAxis

Vector2

MemberDescription
Vector2.new(x?, y?)Constructor.
.X .Y .MagnitudeComponents and length.
Operators+ - * / (* accepts a scalar).

Color3

MemberDescription
Color3.new(r?, g?, b?)Components in 0–1 range.
Color3.fromRGB(r, g, b)Components in 0–255 range.
.R .G .BComponents (also lowercase).
:ToRGB()Returns three integers 0–255.

CFrame

MemberDescription
CFrame.new(position?)From a Vector3, three numbers, or empty (identity).
CFrame.lookAt(from, to)Position + look-at rotation.
CFrame.Ales(x?, y?, z?)Euler-angles rotation CFrame.
.Position / .pPosition vector. .X .Y .Z also work.
.LookVector .RightVector .UpVectorRotation axes.
:PointToWorldSpace(v) / :PointToObjectSpace(v)Coordinate-space conversion.
:ToEulerAnglesXYZ()Euler angles.
Operatorscf * Vector3 (transform point), cf * CFrame (compose).

Drawing API

2D overlay primitives rendered by the external. Create objects with Drawing.new, update their properties, then set Visible = true.

Drawing.new(type) → Drawing

type is one of "Line", "Text", "Circle", "Square".

local box = Drawing.new("Square")
box.Position = Vector2.new(100, 100)
box.Size = Vector2.new(160, 220)
box.Color = Color3.fromRGB(120, 130, 255)
box.Thickness = 2
box.Visible = true
Drawing.clear()

Removes every drawing object at once.

cleardrawcache()

Flushes the render cache (all objects).

Drawing.Fonts

Font selector constants: UI (0), System (1), SystemBold (2), Minecraft (3), Monospace (4), Pixel (5), Fortnite (6), ProximaSoftBold (7).

Common properties (all types)

PropertyTypeDescription
VisiblebooleanWhether the object is drawn.
ColorColor3Object color.
Transparencynumber0 = opaque, 1 = invisible.
ThicknessnumberLine weight.
ZIndexnumberDraw order.
:Remove() / :Destroy()methodDeletes the object.

Type-specific properties

TypeProperties
LineFrom (Vector2), To (Vector2)
TextText, Position (Vector2), Size/FontSize, Font, Center (bool), Outline (bool)
CirclePosition (Vector2), Radius, Filled (bool), NumSides (read-only, 64)
SquarePosition (Vector2), Size (Vector2), Filled (bool), Corner/Rounding

Input & clipboard

OS-level input helpers and clipboard access. Mouse coordinates are client-relative to the Roblox window.

getmousepos() → x, y

Cursor position in client space.

isrbxactive() → boolean

Whether the Roblox window is focused.

iskeypressed(key) → boolean

Accepts a virtual-key code, a name ("space", "shift", "ctrl", "alt", "tab", "escape", "left", "right", "up", "down", "lmb", "rmb", "mmb", letters…), or an Enum.KeyCode item. Only reports true while the game is focused.

ismouse1pressed() / ismouse2pressed() → boolean

Left / right mouse button state (focus-gated).

keypress(virtualKey) / keyrelease(virtualKey)

Synthesize a key tap using Windows virtual-key codes.

mousemoveabs(x, y) / mousemoverel(dx, dy) / mousemoverel & mousescroll(notches)

Move the cursor absolutely (client coords) or relatively; mousescroll sends wheel notches.

mouse1press() / mouse1release() / mouse1click()

Left button control (click = press + release).

mouse2press() / mouse2release() / mouse2click()

Right button control.

setclipboard(text) / getclipboard() → string

Copy text to the Windows clipboard, or read it back (Unicode text supported).

setrobloxinput()

Input-routing compatibility shim (no-op).

HTTP

Full HTTP client powered by WinHTTP — no Roblox HttpService restrictions.

request(options) / http_request(options) → response table

Roblox-style request. Options: Url (required), Method (default "GET"), Body, Headers (table).

Returns { Success, StatusCode, Body, StatusMessage, Headers }.

local res = request({
    Url = "https://httpbin.org/get",
    Method = "GET",
    Headers = { ["User-Agent"] = "yuari" }
})

if res.Success then
    print(res.StatusCode, #res.Body)
end
httpget(url, headers?) / HttpGet(url, headers?) → body

GET a URL and return the response body as a string.

httppost(url, body, contentType?, headers?) → body

POST with an optional content type (default "application/json").

HttpService

Service-style wrapper: HttpService:GetAsync(url, headers?), HttpService:RequestAsync(options), HttpService:JSONEncode(value), HttpService:JSONDecode(string).

local json = HttpService:JSONEncode({ health = 100, name = "bot" })
local data = HttpService:JSONDecode('{"health": 100}')
print(data.health)

File system

All file functions are sandboxed to the executor workspace: %APPDATA%\YuariExt\Workspace. Paths outside the workspace (absolute paths, .. escapes) are rejected.

Limits. Allowed extensions: .txt .lua .luau .json .cfg .dat .ini. Max file size: 8 MB. Max path length: 1024 characters.
FunctionReturnsDescription
writefile(path, data)—Writes (creates parent folders automatically). Raises an error on invalid path/extension/size.
readfile(path)stringReads the whole file.
appendfile(path, data)—Appends to the file.
makefolder(path)—Creates a folder (recursive).
isfile(path)booleanTrue if the path is a regular file.
isfolder(path)booleanTrue if the path is a directory.
listfiles(path){string}Entries in a folder, sorted, as workspace-relative paths.
delfile(path)booleanDeletes a file.
delfolder(path)booleanDeletes a folder and everything inside it.
loadfile(path)function? , error?Compiles a file into a function (Luau compat pass applied). Returns nil, message on failure.
dofile(path)...Compiles and runs a file, returning its results.
writefile("configs/aim.json", HttpService:JSONEncode({ fov = 15 }))
print(readfile("configs/aim.json"))

for _, f in ipairs(listfiles("configs")) do
    print(f)
end

Scripts & decompiling

Tools for inspecting scripts inside the game — all reading from live game memory.

getscripts(root?) → {Instance}

Collects every script (LocalScript, Script, ModuleScript) in the tree under root — defaults to the whole DataModel. Capped at 8000 scripts.

getscriptbytecode(script) → string

Raw Luau bytecode of a script. Returns an empty string for non-scripts.

decompile(scriptOrBytecode) → string

Decompiles a script instance (or a raw bytecode string) back to Luau source.

for _, s in ipairs(getscripts()) do
    local src = decompile(s)
    if src and src:find("RemoteEvent") then
        print(s:GetFullName())
    end
end
getsenv(script) → table

Script environment accessor (compatibility shim).

getscripthash(script) → string

FNV-1a hash of the script's bytecode, as a decimal string ("0" when unavailable).

loadstring(source, chunkName?) → function

Compiles a string with the Luau compatibility pass applied. Like Roblox, syntax errors yield a function that raises the error when called.

local fn = loadstring("print('hello from a string')")
fn()
load(source, chunkName?)

Alias of loadstring.

getfenv(fn?) / setfenv(fn, table)

Environment get/set for functions, Roblox-style. getfenv() with no usable argument returns the global table.

Services

Lightweight service shims pumped by the external tick loop.

RunService.Heartbeat / RunService.RenderStepped / RunService.Stepped

Frame signals that fire every tick with the delta time. Use in a loop with task.wait().

RunService.Heartbeat:Connect(function(dt)
    -- runs every frame
end)
UserInputService.InputBegan / UserInputService.InputEnded

Fire with an input object { KeyCode = { Name, Value }, UserInputType = { Name } }.

UserInputService.GetMouseLocation() → Vector2

Cursor position in client space.

UserInputService.IsMouseButtonPressed(button) / IsKeyDown(key) → boolean

State queries — accepts the same key formats as iskeypressed.

VirtualInputManager.SendMouseButtonEvent(...) / SendMouseMoveEvent(...) / SendKeyEvent(...)

Virtual input shims for UI automation.

VirtualUser.CaptureController() / VirtualUser.ClickButton1(position)

Anti-AFK helpers. ClickButton1 takes a Vector2 or x, y.

TweenService.Create(...) → tween

Compatibility shim returning a table with Play, Cancel, Pause, Destroy and a Completed signal.

bit32

Full bit32 library: band, bor, bxor, bnot, lshift, rshift, arshift, lrotate, rrotate, extract, replace.

Enum.KeyCode / Enum.UserInputType

Virtual-key code tables for input functions.

  • KeyCode — Space, Tab, Escape, Return/Enter, Backspace, arrow keys, LeftShift/RightShift, LeftControl/RightControl, LeftAlt/RightAlt, letters A–Z, digits 0–9, F1–F12.
  • UserInputType — MouseButton1 (1), MouseButton2 (2), MouseButton3 (3), Keyboard (8), Touch (9), Gamepad1 (10).

Signals

All signals in the VM (RunService, UserInputService, instance events, tween Completed…) share the RBXScriptSignal API.

MemberDescription
:Connect(fn)Subscribes; returns a connection object with :Disconnect().
:Once(fn)Subscribes for a single fire.
:Wait()Yields until the signal fires; returns the fired arguments.
:Fire(...)Fires the signal manually (useful for BindableEvent-style patterns).
local conn
conn = workspace.ChildAdded:Connect(function(child)
    print("added:", child.Name)
    conn:Disconnect()
end)

local plr = game:GetService("Players").PlayerAdded:Wait()
print(plr.Name, "joined")

GC & memory scanning

These functions read the game's own Luau garbage collector structures from outside the process — a powerful way to find tables, values and scripts that normal APIs can't see. They work whether or not the game has an exploitable state.

getgc(includeTables?) → info table | iterator, table, 0

With no argument, returns GC statistics (same shape as getgc_info). With true, returns a generic-for iterator over every live table in the game's VM (up to 120,000 entries).

for _, tbl in getgc(true) do
    local v = rawget(tbl, "Money")
    if type(v) == "number" then
        print("found:", v)
    end
end
getgc_info() → table

Snapshot of the game's GC state: kb, gcstate, isrunning, pause, stepmul, pages, gray, grayagain, weak, total, by_type, samples, plus the addresses L and G as hex strings.

setgc(option, value?) → boolean | number | nil, error

Controls the game's collector directly: "stop" (freeze), "restart" (resume), "count" (total KB), "isrunning", "pause" / "setpause" (get/set, 0–1000), "stepmul" / "setstepmul" (get/set, 0–10000).

setgc("stop")      -- freeze the game's GC
print(setgc("count"))
setgc("restart")   -- resume
findgc(key | keys) / findgc(key, value) / findgc(nil, value) → {table}

Scans all game VMs for tables containing the given string key (or a list of keys), optionally matching a specific string value. Returns table proxies you can index directly. Returns nil, "no game lua state" when no state is found.

local hits = findgc("Leaderstats", "Cash")
for _, tbl in ipairs(hits) do
    print(tbl)
end
getrawkeys(table) → table

Dumps the raw string keys of a game table proxy (read from the hash nodes in memory), paired with their values.

rawget(table, key)

Overridden to work on game table proxies as well as normal tables.

gcprobe() → table

Advanced diagnostics: number of game VMs (vm_count), per-VM stats (G/L addresses, table counts, string-key samples) and ammo_vm — the index of the VM holding the tracked data. Mostly a debugging tool.

Raw memory access

Requires the Allow Unsafe LuaU toggle. Direct memory R/W can crash the game — use at your own risk.
Unsafe Luau
memory_read(type, address) → value?

Reads from the game process. type is one of "int", "float", "double", "byte", "string", "uintptr_t". Returns nil for a null address.

local v = memory_read("float", 0x1A2B3C4D)
print(v)
Unsafe Luau
memory_write(type, address, value)

Writes to the game process using the same type names as memory_read.

getbase() → integer

Base address of the Roblox module — handy as a starting point for offset math with memory_read.