Player accounts

Players can sign in to Gamealia with Google. Your game can greet them by name, sync their saves (see Cloud save) and, when you run your own servers, know who they are without a login of its own.

Rules

  • Guests must be able to play. Never require sign-in to play.
  • No login of your own (Google, Facebook, email, Firebase Auth...). The reviewer rejects games that have one.
  • Call Gamealia.user.requestLogin() only from a button the player pressed, for example "Sign in to save your progress".

In the game

const { user } = await Gamealia.init();
showName(user ? user.username : "Guest");

Gamealia.user.onChange((u) => showName(u ? u.username : "Guest"));

saveButton.onclick = async () => {
  const u = await Gamealia.user.requestLogin(); // null when the player closed the sign-in
  if (u) showName(u.username);
};

user.id is stable for a player in your game only: each game sees a different id for the same person.

Your own backend: verify the token

When your game talks to your own server (leaderboards, multiplayer), send it a token instead of a user id the client could fake:

const token = await Gamealia.user.getToken(); // null for guests
await fetch("https://api.example.com/session", { method: "POST", headers: { Authorization: `Bearer ${token}` } });

The token is an ES256 JWT, valid for 5 minutes. Ask for a new one for each session or request rather than storing it. Its claims:

ClaimValue
isshttps://gamealia-api.tinchogon34.workers.dev
audyour game id (the gameId from init(), also shown in the developer portal)
subthe player's id in your game, the same as user.id
username, avatarUrlthe player's public profile
gameIdyour game id
iat, expissued at and expiry (5 min)

Verify it with the public keys at https://gamealia-api.tinchogon34.workers.dev/.well-known/jwks.json (cache them; the response allows one hour), and always check iss and aud: a token issued for another game must not work on your server.

Node.js

import { createRemoteJWKSet, jwtVerify } from "jose";

const JWKS = createRemoteJWKSet(new URL("https://gamealia-api.tinchogon34.workers.dev/.well-known/jwks.json"));

export async function gamealiaPlayer(token) {
  const { payload } = await jwtVerify(token, JWKS, {
    issuer: "https://gamealia-api.tinchogon34.workers.dev",
    audience: process.env.GAMEALIA_GAME_ID,
    algorithms: ["ES256"],
  });
  return { id: payload.sub, username: payload.username };
}

Python

import os
import jwt  # pip install "pyjwt[crypto]"

JWKS = jwt.PyJWKClient("https://gamealia-api.tinchogon34.workers.dev/.well-known/jwks.json")

def gamealia_player(token: str) -> dict:
    key = JWKS.get_signing_key_from_jwt(token)
    claims = jwt.decode(
        token,
        key.key,
        algorithms=["ES256"],
        issuer="https://gamealia-api.tinchogon34.workers.dev",
        audience=os.environ["GAMEALIA_GAME_ID"],
    )
    return {"id": claims["sub"], "username": claims["username"]}

Create or find the player in your database by sub and sign them in automatically: Gamealia players never register a second time in your game.

Declare your server's host in the listing's backendHosts (for example api.example.com or *.example.com, up to 10): the autotest warns about requests to hosts you did not declare.

In the mock

user.get() is null and getToken() always null. requestLogin() signs in a fake "Mock Player" so you can test the signed-in path; there is no mock token, so test your backend with a real game preview.