Lua VM Documentation
Magic's external Lua scripting environment — Roblox-like API, Drawing overlay, coroutine scheduler, and bundled UI libraries.
Introduction
Magic includes a built-in Lua VM that runs externally — scripts are not injected into Roblox. The VM emulates a familiar Roblox-like API using external memory reads and an overlay renderer.
Open the Lua VM tab in the Magic menu to write and execute scripts. Output appears in the script console. Up to 6 script tabs are supported.
Quick Start
Drawing example
Execution Model
Scripts use real Lua coroutines. The VM steps every frame, processing deferred tasks and firing RunService signals.
| API | Description |
|---|---|
task.spawn(fn) | Start a new coroutine |
task.wait(sec?) | Yield current coroutine (default 0) |
task.defer(fn) | Defer function to next frame |
wait(sec) | Alias for task.wait |
tick() | VM runtime clock in seconds |
RunService signals: Heartbeat, RenderStepped, Stepped — each supports :Connect(fn) and :Disconnect().
Globals
Environment
| Global | Description |
|---|---|
game | DataModel instance |
workspace | Workspace instance |
print / warn / error | Script console output |
typeof(val) | Luau-style type name |
loadstring(src) | Compile Lua source to function |
os.clock() | Seconds since VM start |
Input
| Global | Description |
|---|---|
isrbxactive() | True if Roblox window is foreground |
iskeypressed(vk) | Windows virtual key held (e.g. 0x23 = End) |
ismouse1pressed() | Left mouse button |
ismouse2pressed() | Right mouse button |
setrobloxinput(bool) | Toggle Roblox input passthrough |
setclipboard(text) | Copy to Windows clipboard |
Memory (advanced)
| Global | Description |
|---|---|
getbase() | Roblox module base address |
memory_read(type, addr) | Read: int, float, double, byte, uintptr_t, string |
memory_write(type, addr, val) | Write: int, float, double, byte, uintptr_t |
Types
Vector3
Vector3.new(x,y,z), Vector3.zero, constants one, xAxis, yAxis, zAxis. Operators: + - * /. Methods: :Dot(), :Cross(), :Lerp(), :Distance().
Vector2
Vector2.new(x,y) — properties .X, .Y.
Color3
Color3.new(r,g,b) (0–1), Color3.fromRGB(r,g,b) (0–255), Color3.fromHSV(h,s,v).
CFrame
CFrame.new(), CFrame.Angles(rx,ry,rz). Properties: Position, LookVector, RightVector, UpVector. Methods: :Inverse(), :PointToWorldSpace(v3).
game & Instance
Instance methods:
| Method | Description |
|---|---|
:FindFirstChild(name) | Find child by name |
:FindFirstChildOfClass(class) | Find child by class |
:GetChildren() | Array of children |
:GetDescendants() | All descendants |
:IsA(class) | Class check |
:GetService(name) | Get Roblox service |
:HttpGet(url) | HTTP GET request |
:HttpPost(url, body) | HTTP POST request |
:GetMouse() | Mouse object (on Player) |
:IsDescendantOf(inst) | Hierarchy check |
Properties: Name, ClassName, Parent, Position, Size, CFrame, Health, Character, CurrentCamera, ViewportSize, FieldOfView, GameId, PlaceId, WalkSpeed, JumpPower.
Services
Players
.LocalPlayer, .PlayerAdded, .PlayerRemoving, :GetPlayers()
RunService
.Heartbeat, .RenderStepped, .Stepped
UserInputService
.InputBegan, .InputEnded
HttpService
:JSONEncode(table), :JSONDecode(string), :GenerateGUID()
Mouse
.X, .Y — cursor in Roblox client coordinates
Drawing API
Properties: Visible, Transparency, ZIndex, Color, Position, Size, From, To, Filled, Thickness, Radius, Text, Font, FontSize, Center, Outline, Data (Image PNG bytes).
Drawing.Fonts: UI, System, SystemBold, Minecraft, Monospace, Pixel, Fortnite.
Call obj:Remove() to destroy a drawing object.
Filesystem
All paths are relative to resources/scripts/ (sandboxed).
| Function | Description |
|---|---|
writefile(path, data) | Write file |
readfile(path) | Read file |
makefolder(path) | Create directory |
isfile(path) | Check if file exists |
delfile(path) | Delete file |
listfiles(folder) | List files in folder |
UI Libraries
Wabi UI Library
Obsidian Library
API & Limitations
Legacy API
Older C-style globals still work. Prefer the modern API documented above.
get_workspace(), get_camera(), world_to_screen(), teleport_local(), set_walkspeed(), camera_get_cframe(), and similar — see in-client editor autocomplete.
Limitations
Not supported vs real Roblox:
- No Instance.new() or replication
- No ScreenGui / Roblox UI hierarchy
- No require() of Roblox modules
- No full os / io libraries
- CFrame API is partial
- JSON encode/decode is basic