Client Workflow
To play a game, a player's client authenticates on the Management API to get an identity session token, then lists the games available. When a player selects a game, the client mints an app-scoped token for that app — mintAppToken for a native/same-origin client, or the OAuth2 Authorization-Code + PKCE portal flow when the game runs at a different origin from the one that holds the session (a browser game on its own domain uses hosted sign-in on Studio). The session token is management-plane only and is rejected for gameplay; the app-scoped token is the credential the client uses against that app's Game API (it carries the app's gameApiUrl/gameApiWsUrl) to register with a Buddy server and play. App tokens are short-lived (~30 min) — refresh them with refreshAppToken to keep playing. See Portals & app-scoped tokens.
Our SDKs abstract this process. When initializing an SDK you provide the ONE GraphQL origin for the environment you are on — https://ck.prod.crowdedkingdoms.com/graphql in production; identity stays on a hub client, and a per-game client drives gameplay with its app-scoped token (client.portal). See CrowdyJS for browsers and Native & non-browser clients for Unreal/Unity, desktop, console, mobile, and custom native clients.
A game whose server code runs on ck-exec then connects to it: with the app-scoped token, execConnect returns a gateway and a connect token valid for 60 seconds, and the client opens a WebSocket to that gateway and calls the game's hubs over it. The SDKs do both (client.exec.connect in CrowdyJS, client.exec().connect in CrowdyCPP). See Connect from a game.
Gameplay rules belong on the server. See Best practices.