Getting started
Environment
- Lua 5.4 (external process, not Roblox Luau) —
the external state - Opened libs:
base,table,string,math,utf8,coroutine - Removed:
dofile,loadfile(nil). Noio/os/package/debug - Executor window:
gui/lua_window.cpp+gui/TextEditor/TextEditor.cpp(premium only). Freemium has freemium-gated executor.
Paste scripts into the spitari executor window (or load from file if your UI supports it). Do not run Studio LocalScripts (e.g. spitari_bridge_localscript.lua) in the cheat — they are for Roblox Studio only.
Premium vs freemium
| Premium | Freemium | |
|---|---|---|
| Executor | full Lua VM | limited — same VM but feature-gated env |
| Gate | none | Work.ink 12h gateway; GetFormattedTimeRemaining() shows expiry |
See Premium vs Freemium for file-level diff.
Globals you always have
game -- DataModel (Instance userdata, refreshed each execute via RefreshGlobals)
workspace -- Workspace (== game.Workspace)
print(...) -- → executor console (LogLevel::Print)
warn(...) -- → executor console (LogLevel::Warn)
identifyexecutor() -- "spitari", "0.1" (alias "spitari","0.1" for compat)
Minimal script
local Players = game:GetService("Players")
local lp = Players.LocalPlayer
print("hi", lp and lp.Name, identifyexecutor())
task.spawn(function()
while true do
task.wait(1)
local cam = workspace.CurrentCamera
print("fov", cam and cam.FieldOfView)
end
end)
Scheduler
Prefer task.* over bare wait / spawn (which are aliases):
| API | Notes | Source |
|---|---|---|
task.wait([t]) |
yield; default ~0.03s; implemented via ScheduleWait + g_waits |
LuaVM.cpp:schedule_wait, Tick() |
task.spawn(fn) |
returns thread; lua_resume inline |
l_spawn |
task.delay(t, fn) |
returns cancel token {idx,seq} |
g_delays |
task.defer(fn) |
next tick | l_defer |
task.cancel(token\|thread) |
stop delay or thread | l_cancel |
wait(t) |
alias of task.wait |
l_wait |
spawn(fn) |
alias of task.spawn |
l_spawn |
Tick runs on g_tick_th (SafeThread) at ~60Hz; g_waits drained by dt.
Services
game:GetService("RunService")
game:GetService("UserInputService")
game:GetService("TweenService") -- noop Create/Play
game:GetService("HttpService")
game:GetService("Players") -- real instance
game:GetService("Workspace") -- real / by class name
Fake services (also exposed as globals RunService, UserInputService, TweenService, HttpService):
| Service | Real? | Notes |
|---|---|---|
RunService |
fake | Heartbeat/RenderStepped/Stepped share one tick kind |
UserInputService |
fake | polls WindowInputState at 0x2C0 |
TweenService |
fake | Create:Play/Cancel/Pause/Destroy no-op; Completed never fires |
HttpService |
fake | wraps WinHTTP (request/HttpGet) |
HttpService |
fake | JSONEncode/Decode scalars only |
Players/Workspace/others |
real | DataModel child with matching ClassName or Name |
GetService is case-insensitive; falls through to DataModel child lookup.
Events (short)
signal:Connect(fn) / :Once(fn) / :Wait() / :Fire(...)
bindable:Fire(...)
prompt:Fire()
remote.OnClientEvent:Connect(fn) -- local Fire always; real server packets via SpitariTest.Bus on test place
Full table: Signals. Cheat-sheet: luascripts/api_reference.lua + luascripts/lua_vm_full_test.lua.
Memory & drawing (one-liners)
local addr = addrof(workspace.CurrentCamera)
print(string.format("cam @ 0x%x FOV=%g", addr, rdd(addr + 0x140)))
local line = Drawing.new("Line")
line.From = Vector2.new(10, 10); line.To = Vector2.new(200, 10); line.Visible = true
Next
- Premium vs Freemium
- Globals
- Instance
- Signals
- Limitations — read before porting big scripts
