The developer docs are written in English and Spanish. You are reading the English version.

SDK reference

The Gamealia SDK is window.Gamealia. Load it in index.html before your game scripts:

<script src="https://gamealia.app/sdk/v1.js"></script>

The SDK is not published to npm. The CrazyGames and Poki shims (/sdk/crazygames.js, /sdk/poki.js) include it too, so a page loads exactly one of the three files.

How calls behave

  • Promises that never reject. Every async call resolves, with a safe fallback on failure (for example { shown: false, rewarded: false } for an ad, null for a user). You never need try/catch around the SDK.
  • Init first. Call Gamealia.init() once at startup. Every other call waits for it (and starts it if you did not), so the order is always right, but call it yourself first: the autotest's sdk_init check requires init to be the first SDK message.
  • Timeouts. Inside the portal, a call that gets no answer resolves its fallback after 15 s; ads and requestLogin wait up to 120 s. init() waits up to 5 s for the portal, then falls back to the mock.
  • Mock mode. When the page is not inside the portal (your dev server, a file you opened, the standalone site of your game), the SDK runs a local mock, described for each method below. Add ?gamealia_debug=1 to the URL for a small panel that logs every SDK call.

Types

interface InitResult {
  environment: "gamealia" | "preview" | "autotest" | "mock";
  locale: string;          // the player's portal language, e.g. "es", "en", "pt-BR", "ja"
  gameId: string;          // your game's id ("local" in the mock)
  user: PublicUser | null; // null for guests
  joinRoom: string | null; // the room code the player was invited to
  device: "mobile" | "desktop";
}
interface PublicUser { id: string; username: string; avatarUrl: string | null }
interface AdResult { shown: boolean; rewarded: boolean }
interface RoomInfo { code: string; name: string; players: number; max: number; inProgress: boolean }
type EventType = "adStart" | "adEnd" | "userChange" | "roomJoin" | "pause" | "resume" | "mute" | "unmute";

PublicUser.id is per game: the same player has a different id in every game, so games cannot match players with each other. environment is "preview" in the developer's and the reviewer's preview, "autotest" during the autotest and "gamealia" on the live portal.

Lifecycle

Gamealia.init(): Promise<InitResult>

The first call, once, at startup. Calling it again returns the same promise.

const { locale, user, device, joinRoom } = await Gamealia.init();
setLanguage(locale.startsWith("es") ? "es" : "en");

Mock: environment: "mock", gameId: "local", locale from the browser languages, user: null (until requestLogin), joinRoom from ?gamealia_join=CODE, device "mobile" when the window is narrower than 768 px or has touch.

Gamealia.peekInit(): InitResult | null

The init result once init() has finished, else null. Synchronous, for code that cannot wait.

Gamealia.game.loadingStart(): Promise<void>

Loading started. Optional.

Gamealia.game.loadingStop(): Promise<void>

Required. The game is loaded and ready to play. The autotest fails if it does not arrive within 15 s of the page load.

Gamealia.game.gameplayStart(): Promise<void> / Gamealia.game.gameplayStop(): Promise<void>

Real play starts (first input, level start, unpause) and stops (game over, pause menu, level end, an ad). They feed the stats and the friends' presence; the autotest warns when gameplayStart does not follow the first input.

Gamealia.game.happyTime(): Promise<void>

A big moment: a win, a record, a level cleared.

All game.* calls do nothing visible in the mock (they show up in the debug panel).

Ads

See Ads for the rules and frequency.

Gamealia.ad.requestMidgame(): Promise<AdResult>

An interstitial ad break at a natural pause. Resolves when the break is over (or was skipped), with shown: true only when an ad played. The portal may skip it (frequency cap, ads off, no fill): then it resolves { shown: false, rewarded: false } right away.

Gamealia.ad.requestRewarded(): Promise<AdResult>

A rewarded ad the player chose to watch. Give the reward only when rewarded is true.

const { rewarded } = await Gamealia.ad.requestRewarded();
if (rewarded) lives++;

Mock (both): a full-screen "Mock ad" overlay for 2 s, adStart and adEnd events, then { shown: true, rewarded: true } for a rewarded ad and { shown: true, rewarded: false } for a midgame.

Gamealia.onAdStart(cb): () => void / Gamealia.onAdEnd(cb): () => void

Shortcuts for Gamealia.on("adStart", cb) and Gamealia.on("adEnd", cb). Pause the game and mute its audio between them. Each returns an unsubscribe function.

Players

See Player accounts for backends and tokens.

Gamealia.user.get(): Promise<PublicUser | null>

The signed-in player, or null for a guest. Mock: null until requestLogin().

Gamealia.user.getToken(): Promise<string | null>

A signed token (ES256 JWT, valid 5 minutes) that your own backend verifies to identify the player. null for guests. Mock: always null.

Gamealia.user.requestLogin(): Promise<PublicUser | null>

Asks the portal to show its sign-in. Resolves the player after they sign in, or null if they did not. Call it from a button the player pressed. Never build your own login. Mock: signs in the fake player { id: "mock-user", username: "Mock Player", avatarUrl: null } and fires userChange.

Gamealia.user.onChange(cb: (user: PublicUser | null) => void): () => void

The player signed in or out. Returns an unsubscribe function. The SDK has already dropped its cached save: call data.load() here (see Cloud save).

Saves

See Cloud save.

Gamealia.data.load(): Promise<{ ok: true; data } | { ok: false; error }>

All of the player's saved data for this game. Unlike getAll(), it tells "no save yet" ({ ok: true, data: {} }) apart from "could not load" ({ ok: false, error: "timeout" }). On ok: false, do not start a new save over the old one.

Gamealia.data.get(key: string): Promise<unknown>

A saved value, or null when there is none (or it could not be read).

Gamealia.data.set(key: string, value: unknown): Promise<boolean>

Saves a JSON-serializable value. Resolves false when it was not saved: the value is not JSON, the whole save would pass 1 MB (UTF-8 bytes of the whole save as one JSON object), or the portal refused it.

Gamealia.data.getAll(): Promise<Record<string, unknown>>

All the saved data ({} when there is none or it could not be read).

Gamealia.data.remove(key: string): Promise<void> / Gamealia.data.clear(): Promise<void>

Deletes one key, or the whole save of this game.

Mock: the data lives in this browser's localStorage under keys prefixed gml:local:.

Multiplayer

See Multiplayer.

Gamealia.room.getJoinCode(): string | null

The room code the player was invited to (from the invite link), or null. Synchronous; valid after init().

Gamealia.room.inviteLink(code: string): Promise<string>

A link that opens your game on the portal and joins room code (https://gamealia.app/game/<slug>?room=<code>). Mock: the current URL with ?gamealia_join=<code>. Codes are 1-32 characters of A-Z a-z 0-9 _ -.

Gamealia.room.showInvite(code: string): Promise<void>

Opens the portal's invite sheet (copy link, share) for room code.

Gamealia.room.publish(room: RoomInfo): Promise<void>

Lists the room in the portal's open rooms so others can join. The SDK repeats it every 15 s while the page is open; the portal drops a room it has not heard from in 30 s. Publishing another code replaces the previous room.

Gamealia.room.unpublish(): Promise<void>

Takes the room down (it is full, started, or closed) and stops the heartbeat.

Gamealia.presence.setStatus(text: string): Promise<void>

A short status of what the player is doing ("Level 3", "In the lobby"), shown to the player's friends next to the game they are playing. The portal strips control characters, cuts it to 64 characters and forwards at most one change every 2 s (a burst keeps the latest). An empty text clears it; it also clears when the player leaves the game. Mock: logged only.

Events

Gamealia.on(event: EventType, cb): () => void

Subscribes to an event and returns an unsubscribe function.

EventPayloadWhen
adStart / adEndnoneAround every ad break: pause and mute in between
userChangePublicUser | nullThe player signed in or out
roomJointhe room codeThe player joined a room from the portal while playing
pause / resumenoneThe portal tab was hidden or shown again
mute / unmutenoneTurn the game audio off / back on. The portal sends mute during ads, while the tab is hidden and when the player presses its mute button, and unmute when none of these applies any more. A game that starts while muted gets mute right after init()

Module exports

For code inside a bundle (the shims use them): createGamealia(window) makes a new SDK instance bound to a window and getGamealia(window) returns the page's singleton (window.Gamealia).