Add waves.ac to your experience
Server-authoritative anti-cheat you install once. The SDK runs in a server Script only, never on the client, and streams signed events to the backend where verdicts are computed.
- 1Link your Roblox accountSign up, then connect the Roblox account that owns your experience. That account is your hard identity across the platform.
- 2Create a gameAdd your universe in the console. You get a signed game token and an HMAC secret used to authenticate ingest.
- 3Drop in the SDKAdd the WavesSDK module to ServerScriptService and call Waves.start with your game token + account number.
- 4Watch in shadow modeNothing is enforced yet. Detections stream into the console so you can calibrate against real traffic first.
- 5Flip to enforceWhen the numbers earn your trust, flip individual modules to enforce. Bans go out through Roblox’s official Ban API with evidence attached.
1. Install the SDK
Add the WavesSDK module to ServerScriptService and start it with your game token and account number.
-- ServerScriptService/Waves.server.luau
-- The model ships with a WavesLoader script. The ENTIRE configuration is one
-- line: paste the Install Key shown when you created the game on the dashboard.
local INSTALL_KEY = "WVK1.xxxxxxxx.xxxxxxxx.xxxxxxxx"
-- (That is genuinely it. Equivalent manual form, if you ever need it:)
local Waves = require(script.Parent.WavesSDK)
Waves.start(INSTALL_KEY)
-- Report the signals the guard modules collect. The SDK signs + batches these;
-- verdicts are computed server-side on waves.ac, never on the client.
Waves.report(player, "movement", {
position = root.Position,
velocity = root.AssemblyLinearVelocity,
})2. Validate your plan (optional)
Your account number is a private key that ties a running server to your subscription. The SDK validates it automatically, but you can call the endpoint yourself:
-- Validate the server's plan on boot (optional; the SDK does this for you).
local ok = HttpService:RequestAsync({
Url = "https://api.waves.ac/v1/validate-account",
Method = "POST",
Headers = { ["Content-Type"] = "application/json" },
Body = HttpService:JSONEncode({ accountNumber = "XXXXXXXXXX" }),
})
local data = HttpService:JSONDecode(ok.Body)
-- data = { valid = true, plan = "surge" }Never share your account number or game token. Sharing a paid plan key results in a permanent ban for both accounts.
Shadow first, always
Every integration starts in shadow mode: detections are logged with full evidence but nothing is enforced. Calibrate in the console, then flip individual modules to enforce on your terms. Zero false-positive automated bans is a hard rule; anything uncertain is downgraded to a flag for human review.