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#

gamee-js — drop the legacy script tag (whichever URL you currently load it from).

gamee-sdk — the recommended path

  1. Download the prebuilt SDK from the GitLab build folder:

    https://gitlab.gamee.io/gamee/gamee-sdk/build

    The contents live at the top level — ESM, CJS, IIFE bundles plus .d.ts files — so you don’t need to dig through packages/sdk/dist/. It’s the same payload, surfaced one folder up for convenience.

  2. Drop the unpacked folder somewhere your project can reference (e.g. vendor/gamee-sdk/) and point package.json at it:

    {
      "dependencies": {
        "@gamee/sdk": "file:./vendor/gamee-sdk"
      }
    }
  3. Install, then import as a normal dependency:

    npm install
    import { gamee } from '@gamee/sdk';

No network dependency at runtime, the build is reproducible, and your editor picks up the bundled types automatically. If you need a <script> tag flow instead, the IIFE bundle (dist/gamee-sdk.iife.js) still attaches a Gamee global — see install for the full set of options.

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() may only be called once per SDK instance. Use createSdk() to re-init in tests.

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 calling gameReady() or you may miss the first start.

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.getPlatform()
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)
platformExtraLifeRemoved — listen to the useExtraLife event directly
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#

Five 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.
platformExtraLife capabilityListen to the useExtraLife event directly.
gamee.controller.*Games are fullscreen — wire DOM input yourself.

Switch to a desktop

The GAMEE SDK emulator and docs are built for screens wider than 1280 px. Open this page on a laptop or desktop browser to get the full experience.

If you're already on a wide screen, drag your window wider and this banner will disappear.