Migrating from gamee-js

Every breaking change between gamee-js and gamee-sdk, with the mapping tables.

gamee-sdk is a ground-up rewrite of gamee-js. The wire protocol with the GAMEE platform is preserved, but the JavaScript API is breaking — there is no compatibility shim. This guide walks you through every change a game has to make when moving off the legacy gamee-js.

The two reference tables at the bottom — methods and events — are the lookup you’ll come back to.

1. Swap the install#

Drop the legacy gamee-js script tag (whichever URL you currently load it from), then follow the install page — it covers the zip download, the package.json link, the <script> tag flow, and the local-monorepo variant. The rest of this guide assumes you’ve completed those steps and can import { gamee } from '@gamee/sdk'.

2. Initialize#

gamee-js

gamee.gameInit('twoButton', {}, ['saveState', 'rewardedAds'], function () {
  console.log('ready');
});

gamee-sdk

await gamee.init({ capabilities: ['saveState', 'rewardedAds'] });
console.log('ready');
  • No controller type, no controller options.
  • Returns a Promise that resolves with the platform’s response (locale, country, save state, mission data, …) — see GameInitResponse.
  • Capability list is validated; unknown values throw VALIDATION synchronously.
  • init() is one-shot — see Methods → init is one-shot.

3. Do I need async/await everywhere?#

Short answer: no.

Fire-and-forget calls — updateScore, gameReady, gameStart, gameOver, gameSaveState, updateMissionProgress, logEvent, requestPause — can stay synchronous. They return a Promise<void> you can ignore:

gamee.updateScore({ score: 100, playTime: 30, checksum: 'sum' });
gamee.gameOver({ saveStateData: { highScore: 100 } });

Data-returning calls need await (or .then) — there is no other way to get the value:

const { videoPlayed } = await gamee.showRewardedVideo();
if (videoPlayed) grantReward();

These calls took a callback in gamee-js, so the async thinking is identical — only the syntax changed.

4. Events#

gamee-js

gamee.onPause = function () {
  game.pause();
};
// or
gamee.emitter.addEventListener('pause', function (ev) {
  game.pause();
  ev.detail.callback();
});

gamee-sdk

gamee.on('pause', () => game.pause());

const off = gamee.on('resume', () => game.resume());
off(); // unsubscribe
  • All events are typed.
  • start receives { resetState?, gameSeed? } directly as its argument — no more ev.detail.
  • The SDK auto-acks every event; you don’t call ev.detail.callback() anymore.
  • Subscribe before gameReady() — see Events → subscribe first.

See the events page for the full payload reference.

5. Callbacks → Promises#

Every gamee-js method that took a callback returns a Promise in gamee-sdk.

gamee-js

gamee.showRewardedVideo(function (err, data) {
  if (data?.videoPlayed) grantReward();
});

gamee-sdk

const { videoPlayed } = await gamee.showRewardedVideo();
if (videoPlayed) grantReward();

6. Controllers are gone#

gamee-sdk is fullscreen-only. The gamee.controller.* subsystem (OneButton, TwoButtons, FourArrows, FiveButtons, SixButtons, Joystick, JoystickWithButton, Slider, Touch, …) no longer exists. Wire input directly:

window.addEventListener('keydown', (e) => {
  if (e.code === 'Space') player.fire();
  if (e.code === 'ArrowLeft') player.left();
  if (e.code === 'ArrowRight') player.right();
});

document.addEventListener('touchstart', (e) => {
  const touch = e.touches[0];
  player.moveTo(touch.clientX / window.innerWidth);
});

The controller-replacement table at the bottom maps every old controller to its DOM equivalent.

7. Errors#

gamee-sdk introduces GameeError with typed .code values. Every failure mode is one of seven codes — see the error handling page for the full catalog.

import { GameeError } from '@gamee/sdk';

try {
  await gamee.gameSaveState({ level: 3 });
} catch (err) {
  if (err instanceof GameeError && err.code === 'CAPABILITY_MISSING') {
    // declare 'saveState' in init()
  }
}
const sdk = Gamee.createSdk({
  allowedOrigins: ['https://games.gameeapp.com'],
});

Without allowedOrigins, the SDK uses '*' and logs a warning on first use. See config.

9. Drop the loading-progress reporting#

gamee.gameLoadingProgress(pct) is gone — render your own loading UI inside the canvas / DOM. The platform no longer cares about progress callbacks.


Reference#

Method map#

gamee-jsgamee-sdk
gamee.gameInit(type, opts, caps, cb)await gamee.init({ capabilities })
gamee.gameLoadingProgress(pct)Removed — render your own loading UI
gamee.gameReady()gamee.gameReady()
gamee.gameStart()gamee.gameStart()
gamee.gameOver(replay, save, rewards, cb)gamee.gameOver({ saveStateData?, rewardIds? })
gamee.gameSave(data, shareFlag, cb)gamee.gameSaveState(data) — cap: saveState
gamee.getPlatform()gamee.platform (now a getter property)
gamee.updateScore(score, time, sum, meta, cb)gamee.updateScore({ score, playTime?, checksum?, metadata? }) (or updateScore(score))
gamee.updateMissionProgress(n)gamee.updateMissionProgress(progress) — cap: missions
gamee.purchaseItemWithGems(details, cb)await gamee.purchaseItemWithGems(details) — cap: gems
gamee.requestPause(cb?)gamee.requestPause()
gamee.logEvent(name, value)gamee.logEvent({ name, value? }) (or logEvent(name)) — cap: logEvents
gamee.requestBattleData(cb)Removed — read initResponse.gameContext instead
gamee.requestPlayerReplay(uid, cb)Removed — capability replay dropped
gamee.requestPlayerSaveState(uid, cb)Removed
gamee.loadRewardedVideo(cb)await gamee.loadRewardedVideo() — cap: rewardedAds
gamee.showRewardedVideo(cb)await gamee.showRewardedVideo() — cap: rewardedAds
gamee.requestPlayerData(cb, uid?)Removed — capability playerData dropped
gamee.share(details, cb)Removed — was an unimplemented stub in gamee-js
gamee.requestSocial(cb)Removed — capability socialData dropped

Event map#

gamee-jsgamee-sdk
gamee.onPause = fngamee.on('pause', fn)
gamee.emitter.addEventListener('start', fn)gamee.on('start', (data) => …) — typed payload
ev.detail.gameSeed / ev.detail.replaydata.gameSeed (the replay field is gone)
ev.detail.callback()Removed — the SDK auto-acks
gamee.emitter.removeEventListener('pause', fn)off() (returned by on()) or gamee.off('pause', fn)
start, pause, resume, mute, unmuteSame names. Same semantics. Typed payloads.
useExtraLifeSame name. Same semantics.
avatarAnimation, avatarUpdateSame names. Typed payloads.
miningEventUpdateSame name. Typed payload.
submitSame name.
ghostShow / ghostHideRemoved — capability ghostMode dropped

Capability map#

gamee-jsgamee-sdk
saveStatesaveState (unchanged)
rewardedAdsrewardedAds (unchanged)
logEventslogEvents (unchanged)
missionsmissions (unchanged)
gemsgems (unchanged)
platformExtraLifeplatformExtraLife (unchanged)
ghostModeRemoved
replayRemoved
playerDataRemoved
socialDataRemoved

Controllers → native input#

gamee-js controllergamee-sdk replacement
OneButton (Space)keydown on e.code === 'Space'
TwoButtons / TwoActionButtonskeydown on ArrowLeft / ArrowRight (or KeyA / KeyD)
TwoArrowsOneButtonThe two-button pattern + Space
FourButtons / FourArrowskeydown on ArrowUp/Down/Left/Right
FiveButtons / SixButtonsArrows + Space + ControlLeft (or other action keys you pick)
Joystick / JoystickWithButtonpointermove / touch handling; compute normalized x, y yourself
Sliderpointermove on a fixed bar
Touchtouchstart / touchmove / touchend; touch.clientX / window.innerWidth for normalized position

What’s gone#

Four gamee-js capabilities and several methods/events did not carry over. Either the platform stopped supporting the feature, or the API was an unimplemented stub. Quick rationale for each:

RemovedWhy
gamee.share()Was an unimplemented stub in gamee-js.
gamee.requestSocial() / socialDataDeprecated in gamee-js; not carried over.
gamee.requestPlayerData() / playerDataNo platform support.
gamee.requestPlayerReplay() / replayReplay/ghost feature retired.
gamee.requestPlayerSaveState()Cross-player save loading retired.
ghostShow / ghostHide / ghostModeReplay/ghost feature retired.
gamee.requestBattleData()Read initResponse.gameContext === 'battle' and friends instead.
gamee.gameLoadingProgress()Render your own loading UI in the canvas.
gamee.controller.*Games are fullscreen — wire DOM input yourself.