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
-
Download the prebuilt SDK from the GitLab
buildfolder:https://gitlab.gamee.io/gamee/gamee-sdk/buildThe contents live at the top level — ESM, CJS, IIFE bundles plus
.d.tsfiles — so you don’t need to dig throughpackages/sdk/dist/. It’s the same payload, surfaced one folder up for convenience. -
Drop the unpacked folder somewhere your project can reference (e.g.
vendor/gamee-sdk/) and pointpackage.jsonat it:{ "dependencies": { "@gamee/sdk": "file:./vendor/gamee-sdk" } } -
Install, then import as a normal dependency:
npm installimport { 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
VALIDATIONsynchronously. init()may only be called once per SDK instance. UsecreateSdk()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.
startreceives{ resetState?, gameSeed? }directly as its argument — no moreev.detail.- The SDK auto-acks every event; you don’t call
ev.detail.callback()anymore. - Subscribe before calling
gameReady()or you may miss the firststart.
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()
}
}
8. Lock down origins on web (recommended for production)#
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-js | gamee-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-js | gamee-sdk |
|---|---|
gamee.onPause = fn | gamee.on('pause', fn) |
gamee.emitter.addEventListener('start', fn) | gamee.on('start', (data) => …) — typed payload |
ev.detail.gameSeed / ev.detail.replay | data.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, unmute | Same names. Same semantics. Typed payloads. |
useExtraLife | Same name. Same semantics. |
avatarAnimation, avatarUpdate | Same names. Typed payloads. |
miningEventUpdate | Same name. Typed payload. |
submit | Same name. |
ghostShow / ghostHide | Removed — capability ghostMode dropped |
Capability map#
gamee-js | gamee-sdk |
|---|---|
saveState | saveState (unchanged) |
rewardedAds | rewardedAds (unchanged) |
logEvents | logEvents (unchanged) |
missions | missions (unchanged) |
gems | gems (unchanged) |
platformExtraLife | Removed — listen to the useExtraLife event directly |
ghostMode | Removed |
replay | Removed |
playerData | Removed |
socialData | Removed |
Controllers → native input#
gamee-js controller | gamee-sdk replacement |
|---|---|
OneButton (Space) | keydown on e.code === 'Space' |
TwoButtons / TwoActionButtons | keydown on ArrowLeft / ArrowRight (or KeyA / KeyD) |
TwoArrowsOneButton | The two-button pattern + Space |
FourButtons / FourArrows | keydown on ArrowUp/Down/Left/Right |
FiveButtons / SixButtons | Arrows + Space + ControlLeft (or other action keys you pick) |
Joystick / JoystickWithButton | pointermove / touch handling; compute normalized x, y yourself |
Slider | pointermove on a fixed bar |
Touch | touchstart / 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:
| Removed | Why |
|---|---|
gamee.share() | Was an unimplemented stub in gamee-js. |
gamee.requestSocial() / socialData | Deprecated in gamee-js; not carried over. |
gamee.requestPlayerData() / playerData | No platform support. |
gamee.requestPlayerReplay() / replay | Replay/ghost feature retired. |
gamee.requestPlayerSaveState() | Cross-player save loading retired. |
ghostShow / ghostHide / ghostMode | Replay/ghost feature retired. |
gamee.requestBattleData() | Read initResponse.gameContext === 'battle' and friends instead. |
gamee.gameLoadingProgress() | Render your own loading UI in the canvas. |
platformExtraLife capability | Listen to the useExtraLife event directly. |
gamee.controller.* | Games are fullscreen — wire DOM input yourself. |