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

-- Hello World print("Magic Lua VM loaded!") print("PlaceId:", game.PlaceId) game:GetService("RunService").Heartbeat:Connect(function() -- runs every frame end)

Drawing example

local box = Drawing.new("Square") box.Filled = false box.Thickness = 1 box.Color = Color3.fromRGB(255, 77, 173) box.Visible = true task.spawn(function() while true do box.Position = Vector2.new(100, 100) box.Size = Vector2.new(80, 120) task.wait(0) end end)

Execution Model

Scripts use real Lua coroutines. The VM steps every frame, processing deferred tasks and firing RunService signals.

APIDescription
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

GlobalDescription
gameDataModel instance
workspaceWorkspace instance
print / warn / errorScript console output
typeof(val)Luau-style type name
loadstring(src)Compile Lua source to function
os.clock()Seconds since VM start

Input

GlobalDescription
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)

GlobalDescription
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:

MethodDescription
: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

local obj = Drawing.new("Square") -- Line, Circle, Text, Triangle, Image

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).

FunctionDescription
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

local UILib = load_uilib() local window = UILib:CreateWindow({ Title = "My Script" }) local tab = window:AddTab("Main") tab:AddSection("Settings"):AddToggle("Toggle", { Default = true }) task.spawn(function() while true do UILib:Step(); task.wait(0) end end)

Obsidian Library

local Library = load_obsidian() local window = Library:CreateWindow({ Title = "Obsidian" }) window:AddTab("Main"):AddLeftGroupbox("General"):AddToggle("Test", { Default = true }) Library:Init()

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