onVerified is an optional callback passed to PlayWaveServer.init. It fires exactly once per player when the verification flow ends, regardless of whether the player is a PC cafe user.
Without this callback, distinguishing “verification finished but the player is not a cafe user” from “verification still in progress” required polling isPcCafeUser (since onPcCafe only fires for cafe users). onVerified closes that gap.
Signature
onVerified = function(player, isPcCafe, reason)
-- player: Player instance
-- isPcCafe: boolean — confirmed value (always false on failure paths)
-- reason: string — one of PlayWaveServer.VerifyReason values
end
- Fires exactly once per
PlayWaveClientReady event
isPcCafe is always a boolean
reason is one of the values defined in PlayWaveServer.VerifyReason (see below)
- Errors thrown inside the callback are caught with
pcall, logged as warnings, and do not break the verify flow
When it fires
onVerified is invoked from inside the PlayWaveClientReady handler — i.e. after the client’s PlayWaveClient script signals readiness to the server. The exact firing point depends on the branch taken:
| Branch | Firing point | reason | isPcCafe |
|---|
| Teleport resume | After POST /game/session/check response, on session registration | RESUMED (success) or RESUME_REJECTED (any 4xx/5xx/network failure) | success → inherited from origin / failure → false |
| Fresh OTT verification | After POST /game/session/verify response | VERIFIED (success) / REQUEST_FAILED (HTTP/network/decode error) / REJECTED (is_valid: false) | success → server response value / failure → false |
No OTT in LaunchData | Immediately, no HTTP call | NO_OTT | false |
OTT without playwave_ prefix | Immediately, no HTTP call | INVALID_PREFIX | false |
Firing order with onPcCafe
For PC cafe users on the success path (where both fire):
- Fresh OTT verification:
onPcCafe + client PC_CAFE event → onVerified
- Teleport resume:
onVerified → onPcCafe + client PC_CAFE event
The order between the two paths differs — do not depend on it. Use onVerified purely as a “verification flow ended” signal, and put PC-cafe-only side effects inside onPcCafe.
When it does NOT fire
TeleportInitFailed session restoration — the player is already verified before the teleport attempt, so re-firing would duplicate for the same player
PlayerRemoving — not a verification event
Verify reason values
The reason argument is one of the values defined on PlayWaveServer.VerifyReason:
| Reason | Meaning | isPcCafe |
|---|
VERIFIED | OTT verification succeeded | server response value |
RESUMED | Teleport resume passed /game/session/check | inherited from origin |
RESUME_REJECTED | Teleport resume failed server-side check (tampered, expired, etc.) | always false |
NO_OTT | Player joined without an OTT in LaunchData | always false |
INVALID_PREFIX | OTT did not start with the playwave_ prefix (treated as an unrelated token) | always false |
REQUEST_FAILED | verify HTTP / network / decode error | always false |
REJECTED | verify API returned is_valid: false | always false |
Usage example
local PlayWaveServer = require(script.PlayWaveServer)
local Reason = PlayWaveServer.VerifyReason
PlayWaveServer.init({
apiKey = apiKey,
apiUrl = apiUrl,
onPcCafe = function(player)
-- PC cafe-only benefits (fires only for cafe users)
end,
onVerified = function(player, isPcCafe, reason)
if reason == Reason.VERIFIED or reason == Reason.RESUMED then
-- Normal session — branch on isPcCafe
else
-- Verification did not produce a normal session
end
end,
})
Relationship with onPcCafe
| Outcome | onPcCafe | onVerified |
|---|
| Cafe user, verified | fires | fires (VERIFIED, isPcCafe=true) |
| Non-cafe user, verified | does not fire | fires (VERIFIED, isPcCafe=false) |
| Resume succeeds, cafe | fires | fires (RESUMED, isPcCafe=true) |
| Resume rejected | does not fire | fires (RESUME_REJECTED, isPcCafe=false) |
| No OTT / prefix mismatch / request error / rejected | does not fire | fires with that reason, isPcCafe=false |
onVerified is purely additive. Existing onPcCafe behavior is unchanged.
Notes
Even when RESUME_REJECTED indicates the server-side check for a teleport resume failed, the local session is left in place. The next heartbeat will return 404/410 and clean up automatically.