Migrate from CrazyGames
The CrazyGames shim exposes the CrazyGames HTML5 SDK v3 (window.CrazyGames.SDK) on top of Gamealia. Most games only swap one script tag.
1. Swap the script
<!-- before -->
<script src="https://sdk.crazygames.com/crazygames-sdk-v3.js"></script>
<!-- after -->
<script src="https://gamealia.app/sdk/crazygames.js"></script>
gamealia init --write (or gamealia_integrate_sdk) does it for you, and the MCP prompt migrate-from-crazygames walks your assistant through the whole migration. The shim includes the Gamealia SDK, so window.Gamealia is there too: you can move calls over one by one.
Older SDK versions (v1, v2) are not covered: port those calls to v3 or to the Gamealia SDK (the integration prints a TODO). If you import @crazygames/crazygames-sdk from npm, load the shim with a script tag instead.
2. Check the policy
CrazyGames allows some things Gamealia does not: remove in-game purchases (Xsolla), "remove ads" offers, other ad networks and your own login. See Game requirements.
Method mapping
| CrazyGames SDK v3 | On Gamealia |
|---|---|
SDK.init() | Gamealia.init(), then loads the saved data for SDK.data |
SDK.environment, getEnvironment() | always "crazygames", so your existing branches keep working |
SDK.game.loadingStart() / loadingStop() | Gamealia.game.loadingStart() / loadingStop() |
SDK.game.sdkGameLoadingStart() / sdkGameLoadingStop() | same as above |
SDK.game.gameplayStart() / gameplayStop() | Gamealia.game.gameplayStart() / gameplayStop() |
SDK.game.happytime() | Gamealia.game.happyTime() |
SDK.ad.requestAd("midgame", callbacks) | Gamealia.ad.requestMidgame(); adStarted, then adFinished, or adError with code unfilled |
SDK.ad.requestAd("rewarded", callbacks) | Gamealia.ad.requestRewarded(); adFinished only when rewarded |
SDK.ad.hasAdblock | always false |
SDK.banner.* | no-ops that report success (the portal shows its own banner) |
SDK.game.inviteLink(params) | the same portal link as Gamealia.room.inviteLink(code) (/game/<slug>?room=<code>). The code is roomId, roomName, room, id or code (else the first param) and must be 1-32 of A-Z a-z 0-9 _ -; other params do not travel. "" before init() resolves or for an invalid code |
SDK.game.showInviteButton(params) | Gamealia.room.showInvite(code); returns the link |
SDK.game.getInviteParam(key) / inviteParams | for a player who joined from a link: the room code under roomId, roomName and room |
SDK.game.settings.muteAudio, addSettingsChangeListener(cb) | follows the portal's mute / unmute (ads, hidden tab, the mute button); listeners get the new settings |
SDK.game.addJoinRoomListener(cb) | the roomJoin event, as { roomId } |
SDK.user.getUser() | Gamealia.user.get() as { __dangerousUserId, username, profilePictureUrl } |
SDK.user.getUserToken() | Gamealia.user.getToken() ("" for guests); verify it with the Gamealia JWKS, see Player accounts |
SDK.user.showAuthPrompt() | Gamealia.user.requestLogin() |
SDK.user.addAuthListener(cb) | Gamealia.user.onChange() |
SDK.user.isUserAccountAvailable | true |
SDK.user.getSystemInfo(), systemInfo | locale and device from Gamealia; countryCode is always "US" |
SDK.data.getItem/setItem/removeItem/clear | Cloud save; values are kept as strings, like localStorage |
SDK.user.listFriends() | an empty list |
SDK.user.showAccountLinkPrompt() | { response: "no" } |
SDK.store.isAvailable | false (no purchases in v1) |
SDK.user.getXsollaUserToken() | null, with a warning |
SDK.user.submitScore, game.reportGameCompletedPercentage, game.setGameContext, game.clearGameContext, game.updateRoom, game.leftRoom, analytics.trackOrder, game.hideInviteButton | accepted and ignored (one console warning each) |
SDK.data.getItem reads from a copy loaded during SDK.init(): await init() before reading.
Your backend
If your server verified CrazyGames tokens, switch it to Gamealia's: ES256 with the Gamealia JWKS, sub as the player id. See Player accounts.