Browse documentation

SDK / Beta

Player Identity

Show the current player's username, image or emoji avatar, and Premium badge.

Install SDK v4

Vendor the exact official artifact at 3jsgames-sdk/v4/3jsgames.js and load it before your game script. SDK v3 remains supported for existing games.

<script src="./3jsgames-sdk/v4/3jsgames.js"></script>
Engagement integrity. The unchanged SDK performs the player-ready handshake and reports the first qualifying pointer, touch, keyboard, or gamepad interaction to the trusted parent. An iframe load by itself is never counted as a play.

Public API

ThreeJSGames.player.getProfile() takes no arguments and resolves with { username: string, avatar: { type: "image" | "emoji", value: string }, isPremium: boolean }. An emoji selection takes precedence over a stored image, matching the public profile. The default avatar is 🎮.

Add an element with id="player-card" to your lobby, scoreboard or HUD, then render the signed-in player with this example. Use the current SDK artifact for the expanded fields.

try {
  const player = await ThreeJSGames.player.getProfile();
  const card = document.createElement("div");
  const avatar = document.createElement("span");
  if (player.avatar.type === "image") {
    const image = document.createElement("img");
    image.crossOrigin = "anonymous"; // Also supports canvas/WebGL HUDs.
    image.alt = player.username + " avatar";
    image.width = image.height = 32;
    image.onerror = () => { avatar.textContent = "🎮"; };
    image.src = player.avatar.value;
    avatar.append(image);
  } else {
    avatar.textContent = player.avatar.value;
  }
  const name = document.createElement("span");
  name.textContent = player.username;
  card.append(avatar, name);
  if (player.isPremium) {
    const badge = document.createElement("span");
    badge.textContent = "Premium";
    badge.setAttribute("aria-label", "Premium player");
    card.append(badge);
  }
  document.querySelector("#player-card").replaceChildren(card);
} catch (error) {
  if (error.code === "AUTH_REQUIRED") {
    // Player is signed out. Keep gameplay working as a guest.
  } else {
    // Player Identity is unavailable. Keep gameplay working.
  }
}
Public presentation only. Username is globally unique but may change. Never use it as authorization, a permanent immutable ID, or a durable database key.

Privacy

The method returns only the public username, normalized avatar and public Premium flag. It does not expose internal user IDs, email, tokens, provider details or private account metadata, and it cannot look up another player. Image URLs hide internal storage paths, and images are served without original file metadata.

Freshness and compatibility

Profile and avatar objects are frozen, read-only snapshots. Each call reads the current public profile without caching. Fetch on entering a lobby or on an explicit refresh; never poll every frame. Image requests also read the current avatar. If an image fails to load, show 🎮.

isPremium comes from the server-owned public profile state and has no SDK setter. Use it for a badge, never authorization. Client-authored multiplayer state is not a verified source of another player's Premium status.

Existing code using player.username works unchanged. Previously vendored SDK v3 and v4 artifacts retain their exact username-only response and remain accepted for uploads.

Stable errors

  • AUTH_REQUIRED — the player is signed out.
  • PLAYER_UNAVAILABLE — identity or the platform bridge is unavailable.
  • INVALID_GAME_CONTEXT or CONTEXT_EXPIRED — reload the embedded game.
  • RATE_LIMITED — retry later.
  • REQUEST_TIMEOUT — the request timed out.

Standalone games must catch unavailable errors and keep gameplay functional.