Skip to main content
You start the SDK, read who is playing, and follow the page as players sign in, pause and mute. OpenGame handles sign-in. Your game reads the result through the SDK, without a key or a call to opengame.io.

Before you start

  • The team’s SDK tarball.
  • A static browser build. The quickstart covers the private CLI setup and deploying a preview.

Install and start the SDK

Install the tarball, then import og as the next example does.
Start the SDK, then report ready once the player can play:
main.js
og.init() waits 4 seconds for the OpenGame page, longer while the page is still identifying the player. It never throws when there is no platform. Outside OpenGame it resolves with a local mock, so the same build runs on your machine, on OpenGame and anywhere else.

Read the player

What each field holds depends on who is playing and where. Unless a row says otherwise, handle is null and signedIn is false. Pick the local player with og.init({ dev: { player: "signed-in" } }), or add ?og-dev-player=signed-in to the page address. guest and no-handle work the same way. Calling requestSignIn() locally switches to the signed-in player.
id is different in every game. The same person has one ID in your game and another in the next, so IDs cannot be joined across games. A guest who clears their browser data becomes a new guest.
Profile sharing starts off. A player can turn it on in OpenGame settings to send their handle, OG number, avatar and character outfit to games. With sharing off, handle and ogNumber are null, and avatar is null, even for a signed-in player. A public OpenGame profile does not mean the player agreed to share it inside a game. Games never receive an email address, the account’s real ID or a friends list. Use id as the key for anything you store about a player, and show handle when there is one. A name a guest types into your game is fine as a local label. It does not become their identity.

Read the player’s OG

When the player shares their profile, og.player.avatar holds the recipe for their OpenGame character. Check the avatar capability first. It is missing for guests, in private previews and when sharing is off.
When look is missing, use your game’s default character. The local signed-in player has a look and an outfit, so you can build a “Your OG” option before you upload. Draw the player’s OG explains the recipe format, building the model, each point of view from first person to the HUD, memory on phones, and what to do when a part is missing. @opengamehq/sdk/avatar names each part of the recipe for you.

Follow sign-in changes

A guest can sign in while playing, and a signed-in player can sign out. The game keeps running through both. Register a listener to update your HUD:
The listener runs once when you register it, with the current player, and again after every change. Call stop() to unsubscribe. Read current values from og.player. To offer sign-in from inside the game, for example beside a leaderboard:
The page opens its sign-in form, and your onChange listener receives the result.

Handle pause, mute and fullscreen

A frame cannot enter fullscreen on its own, so the SDK asks the page to do it. Browsers use Escape to leave fullscreen, so give your game a pause menu that does not depend on Escape.

Record your own events

  • Event names are lowercase letters, digits and underscores, start with a letter, and run to 48 characters.
  • Properties use only these keys: level, mode, difficulty, score, duration_ms, result, step, board, fps, heap_mb, sample_rate. Values are numbers, strings or booleans. A string longer than 120 characters is cut to that length.
  • The SDK drops, without an error, any other key, any other kind of value, a value that looks like an email address or a long number, a number outside the range its key allows, and any property that would take the properties past 1 KiB. The event is still recorded with what is left.
  • A name outside these rules returns invalid_event, and so does an event still over 1 KiB once those properties are dropped. Past 60 events a minute, or 200 since the page loaded, track returns rate_limited.
  • Once start-up is over, track returns unavailable when the page does not offer the analytics capability, the game has no session, or the SDK was disposed. Keep playing; the event is not recorded.
ok: true means the event is queued, not delivered. The SDK sends queued events every 10 seconds and when the page closes, and retries them while the page stays open. Closing the tab can lose events still in the queue. We count plays, sessions and playtime from the page around your game, so you do not track them. The Stats tab on your game’s settings page shows plays and playtime for complete UTC weeks, with daily rows. Your own events come from GET /api/v1/games/{id}/stats for the selected week. A day or group with fewer than 5 players is left out, to protect individual players.

Check what the page offers

Check og.capabilities before you show a feature, and hide the feature when its capability is missing.
  • Private previews leave out sign-in, profile fields and avatars.
  • A private preview offers multiplayer only when the release’s opengame.json sets multiplayer.mode to p2p. Check for the capability before using it.
  • A later platform can add capabilities this SDK version does not list.

Test both kinds of player

  1. Open the game locally as a guest, then again with ?og-dev-player=signed-in.
  2. Confirm your HUD works with a handle and with null.
  3. Confirm the first playable frame calls og.ready(), and that pause and mute reach the game.
  4. Repeat in a private preview to check the hosted runtime.
Local players are development data. They do not show whether a hosted account has shared its profile, so always read the current og.player fields and respond to onChange.

Fix a problem

og.player.id is null when the player is not identified yet, or in a single-player private preview, which has no player ID. Treat the player as an unnamed guest and wait for onChange.
They have profile sharing off, or have not chosen a handle yet. Show a fallback name, as the onChange example above does.
requestSignIn() returns unavailable when the page does not offer the identity capability here. Private previews never do. Check og.capabilities before you show a sign-in button.
track returns invalid_event when the name is outside the rules in record your own events, or when the event is too large even after the SDK drops properties. A key outside the list is dropped, not refused. It returns rate_limited after 60 events in the last minute, or 200 since the page loaded. Send fewer, and keep playing.

Where next

Add a leaderboard

Declare a board, submit scores and show the results.

Add multiplayer

Host rooms and let players join by code.

Read the SDK reference

Look up every export and its signature.

Read the limits

Look up the event size, rate and batching limits.