What is SUNC?
SUNC — short for Strict Unified Naming Convention — is the community standard that defines what functions a Roblox executor is expected to expose to scripts, and the exact names and signatures they're expected to use. It's the strict sibling of UNC (Unified Naming Convention): same idea, tighter conformance bar. This article explains what it is, why it exists, what it covers, and how to use the documentation at docs.sunc.su when you're building a script that has to run across multiple executors.
UNC, then SUNC
Before SUNC there was UNC — the Unified Naming Convention — which set out one canonical name per primitive (e.g. writefile, not write_file or WriteFile). UNC made multi-executor scripts possible, but it was lenient: an executor could pass UNC by having the functions present, even if their behaviour was subtly wrong.
SUNC tightens the bar. It uses the same names and the same surface area as UNC, but its conformance suite tests actual behaviour — correct return types, correct error cases, correct side effects, correct closure-type results. An executor with a high UNC score can still get a low SUNC score if its implementations cut corners. From a script author's point of view, SUNC is what you actually want: not just "the function exists," but "it works."
The documentation lives at docs.sunc.su and the test scripts run inside the executor itself. When you read "100% SUNC" in an executor's marketing, that's this score.
How the spec is organised
The functions in SUNC are grouped into libraries that mirror their purpose. Reading the table of contents in the docs, you see roughly this shape:
- Cache library — invalidate, replace, iscached, clonefunction
- Closures —
newcclosure,iscclosure,islclosure,checkcaller,clonefunction,hookfunction,hookmetamethod,loadstring - Crypt — base64 encode/decode, generatebytes, generatekey, encrypt, decrypt, hash
- Debug — getconstants, getconstant, setconstant, getupvalues, getupvalue, setupvalue, getprotos, getinfo, getstack
- Drawing — Drawing.new and all object types (Line, Text, Image, Circle, Square, Quad, Triangle)
- Filesystem — readfile, writefile, appendfile, listfiles, isfile, isfolder, makefolder, delfolder, delfile, loadfile, dofile
- Input — keypress, keyrelease, mouse1click, mousemoverel, etc.
- Instance / metatable — getrawmetatable, setrawmetatable, getnamecallmethod, setnamecallmethod, getconnections, gethiddenproperty, sethiddenproperty, fireproximityprompt, getnilinstances, etc.
- Reflection — getgenv, getrenv, getsenv, getreg, getloadedmodules, getrunningscripts, getscriptbytecode, getscriptclosure, getscripthash
- Misc — request, getclipboard, setclipboard, identifyexecutor, messagebox, getfps, queue_on_teleport
- WebSocket — WebSocket.connect with .Send / .OnMessage / .OnClose / .Close
We have dedicated articles digging into the bigger libraries (hooks, cache, drawing, debug, filesystem, crypt, websocket, instance utilities). The rest of this overview focuses on how the documentation is structured so you can navigate it on your own.
How an entry on docs.sunc.su looks
Every documented function follows the same template: signature, description, a list of parameters with types, the return value with its type, and a short worked example. Here is roughly what a typical page looks like, recreated:
function hookfunction(target: (...any) -> ...any, hook: (...any) -> ...any): (...any) -> ...any
-- Replaces 'target' with 'hook'. Returns the original function so the
-- hook can delegate to it. Both target and hook must be Lua-callable.(...any) -> ...anylocal original
original = hookfunction(print, function(...)
return original("[hooked]", ...)
end)
print("hello") --> [hooked] helloThree things to know about the format: types are written in Luau-style notation ((string, number) -> boolean), example snippets are minimal but complete, and any executor-specific behaviour is called out in a "Notes" paragraph at the bottom — that's where you find the gotchas.
Reading compliance scores
The SUNC score executors advertise is a percentage of the test suite they pass. The suite covers correctness of return types, error cases, edge cases, and side effects. A score of 100% means every documented function exists with the correct signature and the correct behaviour. Anything less means there are gaps — and the test output will tell you exactly which ones.
-- Run the SUNC test from inside the executor
loadstring(game:HttpGet("https://script.sunc.su/"))()When you run that, the output prints a pass/fail line for each function. Read the failures to learn what your executor doesn't do — that information is more useful than the headline percentage.
A worked example: a SUNC-only script
Here is the kind of small utility that benefits directly from SUNC: a tiny "does this executor have what I need?" gate that scripts can run at startup. Every function it calls is named per the standard.
local REQUIRED = {
"hookfunction",
"hookmetamethod",
"newcclosure",
"checkcaller",
"getrawmetatable",
"request",
"writefile",
}
local missing = {}
for _, name in REQUIRED do
if not getfenv()[name] then
table.insert(missing, name)
end
end
if #missing > 0 then
warn("Missing SUNC functions: " .. table.concat(missing, ", "))
return
end
print("Executor passes startup check.")On any modern executor with a decent SUNC score this prints "passes". On an older or partial executor it tells you exactly which surface area is missing, so you know what to shim before the rest of your script runs.
When to read the docs vs. when to read the source
SUNC is a contract, not an implementation. Two executors that both score 100% can still behave differently in places the standard doesn't pin down — for example, the exact format of a few error messages, or whether request follows redirects by default. When the documented contract is enough, stop there. When you're writing something that needs executor-specific quirks (anti-detection that depends on fingerprintable behaviour, for instance), you'll need to read the executor's own docs or source instead.
Companion articles
The libraries above are big enough that each has its own deep-dive guide on this site. Recommended next reads:
- The SUNC hookfunction deep dive — argument shapes, gotchas, and how it differs from
hookmetamethod. - SUNC closure internals —
newcclosure,iscclosure,islclosure,checkcaller. - The SUNC cache library — invalidating Roblox's instance cache and what that actually means under the hood.
- The SUNC Drawing API — every object type, every property, with examples.
- The SUNC debug library — constants, upvalues, protos, stack frames.
Ather is the lead developer behind Atherhub. He's been writing Luau and Roblox tooling for the better part of a decade, with a focus on the messy interface between game-script internals and the platforms that host them. Have feedback on this article? Drop it in the Discord.