Quickstart
Add a single script tag to your game’s HTML, then await Glaze.init() before calling anything else. The SDK is exposed globally as Glaze (on window.Glaze). TypeScript types ship alongside the script.
<script src="https://glazegames.com/sdk/v3/glaze.js"></script>
<script>
async function boot() {
// 1. Connect to the platform (or fall back to the local simulator).
const env = await Glaze.init();
console.log('Glaze ready:', env.stage); // 'live' | 'qa' | 'local'
// 2. Tell the platform your splash is done and play has started.
Glaze.game.loadingStop();
Glaze.game.gameplayStart();
}
boot();
</script>Modules at a glance
| Module | What it does |
|---|---|
Glaze.game | Loading, gameplay and happy-moment events; invite links |
Glaze.ads | Midgame and rewarded ads, adblock detection |
Glaze.banner | Display banners inside your own DOM |
Glaze.user | Current player, sign-in prompt, auth listener, JWT |
Glaze.data | Cross-device key/value cloud saves |
Glaze.leaderboards | Submit scores, read boards and the player entry |
Glaze.achievements | Unlock and list achievements |
Glaze.purchases | Products, purchases and restore |
Glaze.screen | Fullscreen and orientation lock |
Glaze.analytics | Fire-and-forget custom events |
Glaze.config | Remote / A-B flags with a local default |
Every module call returns a Promise. Calling any method before init() resolves throws — always await Glaze.init() first.
Glaze.init()
Performs the handshake with the Glaze embed page. If no Glaze parent answers within ~1.5s (i.e. you’re running locally), the SDK transparently enters simulator mode and resolves anyway. It’s safe to call init() more than once — the same promise is reused.
const env = await Glaze.init();
// env: SdkEnvironment
// sdkVersion: string
// locale: string // e.g. 'en-US'
// stage: 'qa' | 'live' | 'local' // 'local' === simulator
// host: string
// userAccountAvailable: boolean
Glaze.version; // 'glaze-v3'
Glaze.isSimulator; // true when running outside the platform
Glaze.environment; // the SdkEnvironment, or null before init| Field | Type | Meaning |
|---|---|---|
sdkVersion | string | SDK build identifier |
locale | string | Player locale, e.g. 'en-US' |
stage | 'qa' | 'live' | 'local' | 'local' means the simulator |
host | string | Host the game is running on |
userAccountAvailable | boolean | Whether player accounts are available |
Game lifecycle events
These events let the platform time ads, measure engagement, and decide when prompts are least disruptive. Fire them honestly — they affect how ads behave and your QA pass.
Glaze.game.loadingStart(); // assets started loading (optional)
Glaze.game.loadingStop(); // loading done — REQUIRED once ready to play
Glaze.game.gameplayStart(); // a round/level started
Glaze.game.gameplayStop(); // a round/level ended (pause, death, menu)
// Signal a moment of delight (boss killed, level beaten). The platform
// uses these to time non-intrusive prompts.
Glaze.game.happytime();
// Invite / deep links. Build a shareable link with custom params, then
// read them back when a friend opens the game.
const link = await Glaze.game.inviteLink({ room: 'abc123' });
const room = Glaze.game.getInviteParam('room'); // 'abc123' | nullCall loadingStop() exactly once when the game is interactive, and bracket each round with gameplayStart() / gameplayStop().
Ads
Two ad types: 'midgame' (interstitial, e.g. on death or level end) and 'rewarded' (the player opted in for a reward). Mute and pause your game in adStarted, and resume in adFinished / adError.
// Rewarded ad — only grant the reward when it actually finished.
await Glaze.ads.requestAd('rewarded', {
adStarted: () => pauseAndMute(),
adFinished: () => { resume(); grantCoins(100); },
adError: (err) => { resume(); console.warn(err.code); },
});
// Interstitial between rounds.
const { shown } = await Glaze.ads.requestAd('midgame');
// Detect ad blockers so you can adjust your economy / messaging.
const blocked = await Glaze.ads.hasAdblock(); // booleanFor rewarded ads, the promise rejects (and adError fires with code user-cancelled) if the player skips — so never grant the reward in a .catch(). Don’t request ads back-to-back; gate them behind real game moments.
User & authentication
Read the signed-in Glaze player, prompt them to sign in, and listen for auth changes. For server-authoritative features, mint a short-lived JWT with getUserToken() and verify it on your backend.
// Is a player-account system available in this context?
const available = await Glaze.user.isUserAccountAvailable();
// Current player (or null if not signed in).
const user = await Glaze.user.getUser();
// user: { id: string, username: string, avatarUrl: string | null }
// Prompt sign-in; resolves with the user (or null if dismissed).
const signedIn = await Glaze.user.showAuthPrompt();
// React to sign-in / sign-out anywhere in your game.
function onAuth(u) { updateProfileUi(u); }
Glaze.user.addAuthListener(onAuth);
Glaze.user.removeAuthListener(onAuth);Verifying the player on your backend
getUserToken() returns a short-lived JWT. Send it to your server and verify the signature against the public keys at https://glazegames.com/sdk/v3/jwks.json before trusting the player’s identity.
const token = await Glaze.user.getUserToken();
await fetch('/my-api/sync', {
method: 'POST',
headers: { Authorization: 'Bearer ' + token },
});
// Server: verify against https://glazegames.com/sdk/v3/jwks.jsonCloud saves (data)
A simple key/value store that follows the player across devices. Values are JSON-serializable. In the simulator, saves are written to localStorage under a glaze.sim. namespace.
await Glaze.data.setItem('progress', { level: 7, coins: 320 });
const progress = await Glaze.data.getItem('progress');
// -> { level: 7, coins: 320 } (or null if unset)
await Glaze.data.removeItem('progress');
await Glaze.data.clear(); // wipe all of this game's saved keysLeaderboards
Submit a score to a named board and read it back. Boards support global or friends scope and alltime / daily / weekly periods.
// Submit a score (optionally with metadata). Returns the new rank.
const { rank } = await Glaze.leaderboards.submitScore('highscores', 9001, {
combo: 12,
});
// Read a board.
const { entries } = await Glaze.leaderboards.getLeaderboard('highscores', {
scope: 'global', // or 'friends'
period: 'weekly', // 'alltime' | 'daily' | 'weekly'
limit: 25,
});
// entries: { rank, username, score, meta? }[]
// Where does the current player sit?
const me = await Glaze.leaderboards.getPlayerEntry('highscores');Achievements
Unlock achievements by id and read the full unlocked set back at any time.
await Glaze.achievements.unlock('first-win');
const unlocked = await Glaze.achievements.getAll();
// -> ['first-win', ...]Purchases
List available products, run a purchase, and restore prior purchases. Prices are reported in micros (one-millionth of a currency unit) alongside a display label.
const products = await Glaze.purchases.getAvailableProducts();
// products: { id, name, priceLabel, priceMicros, currency }[]
const purchase = await Glaze.purchases.purchase('remove-ads');
// purchase: { productId, purchasedAt, token }
const owned = await Glaze.purchases.getPurchases();Purchases are unavailable in the simulator — purchase() rejects with code unsupported so you can test the error path.
Screen
Request fullscreen and lock orientation for the player’s session.
await Glaze.screen.requestFullscreen();
await Glaze.screen.exitFullscreen();
// 'portrait' | 'landscape' | 'any'
await Glaze.screen.lockOrientation('landscape');Analytics
Fire a custom event with optional properties. This is fire-and-forget (no promise) and is a no-op until init() has resolved.
Glaze.analytics.track('level_complete', { level: 7, time: 42.3 });Config
Read a remote / A-B flag with a required local default. The default is returned when no remote value exists (and always in the simulator), so your game never blocks on config.
const dropRate = await Glaze.config.get('rare_drop_rate', 0.05);
const theme = await Glaze.config.get('event_theme', 'default');Simulator & devtools
When the SDK can’t reach a Glaze parent (i.e. you’re developing locally), it enters simulator mode automatically — no config needed. Ads play a placeholder overlay, cloud saves go to localStorage, a test player (TestPlayer) can sign in, and stage is 'local'. This means you can build and test the entire integration before uploading anything.
A small Glaze SDK · SIM badge appears in the corner. Click it, or call the API below, to open the on-screen devtools panel — trigger ads, sign in a test player, and dump cloud saves.
Glaze.debug.show(); // open the devtools panel
Glaze.isSimulator; // true when simulating
Glaze.environment.stage; // 'local' in the simulatorQA requirements
Before a build passes review, confirm each of the following:
- You await
Glaze.init()before any other SDK call. game.loadingStop()fires exactly once when the game becomes playable.- Each round is bracketed with
gameplayStart()/gameplayStop(). - Audio mutes and gameplay pauses during ads (
adStarted) and resumes after (adFinished/adError). - Rewarded rewards are granted only in
adFinished, never on skip / error. - The game loads and is playable on both mobile (touch) and desktop, and scales to its container.
- No console errors on load, no broken assets, and no mature content.
Partner program & ads
The SDK is optional. A game embedded from your own hosting under the Glaze Partner Program is listed for free, credited to your studio, and you keep 100% of the ads inside your own game. Revenue share on the ads Glaze shows around the player is not offered yet; it will be announced when payouts are live.
Simulator mode is available for testing ad callbacks without serving a real advertisement.
Ready to publish? Submit your game through the Partner Program form, or revisit the platform overview.
