Repository navigation
Platforms
A melonJS game is a web page, so it runs anywhere a browser does. It can also go further: into native apps, into game portals that run it inside their own app, and into runtimes that have no web page at all. This section has a page for each.
| Platform | What it is | Where players find the game | Page |
|---|---|---|---|
| YouTube Playables | a game portal | the YouTube app and website | YouTube Playables |
| Facebook Instant Games | a game portal | the Facebook app, facebook.com/gaming, Messenger | Facebook Instant Games |
| WeChat Mini Games | a mini-game runtime, with an adapter standing in for the web page | the WeChat app | WeChat Mini Games |
| Capacitor | a native app wrapper | the App Store and Google Play | Capacitor |
| Cordova | a native app wrapper, older | the App Store and Google Play | Cordova |
| nx.js | a runtime for Nintendo Switch homebrew, with no web page | the Switch (homebrew) | Nintendo Switch (nx.js) |
| Web Workers | drawing from a worker thread | any browser | Web Workers |
Running with no web page, on nx.js or in a worker, needs melonJS 20.14 or later. WeChat Mini Games and the portal integrations below need melonJS 20.15 or later.
A game portal or a native wrapper decides things a browser tab leaves to the game: when the game is paused, where progress is saved, whether sound is on. melonJS has one way of handing each of these over, the same on every platform.
A portal's SDK is a script it hosts, loaded by index.html before the game. Don't bundle it with your game: portals check for that.
melonJS pauses a game when the player switches away. Two settings are involved:
-
Who reports it: the browser window, by default.
device.setFocusEvents(false)stops that, so the platform can report it instead, by emittingevent.BLURandevent.FOCUSfrom its own callbacks. -
What the game does about it: the application's
pauseOnBlur,stopOnBlurandresumeOnFocusflags. WithstopOnBlur, the game loop and the rendering stop, the music pauses, the sound effects are muted and held keys are released. On resume, melonJS undoes exactly that.
device.setFocusEvents(false);
app.stopOnBlur = true;
app.pauseOnBlur = false;
platform.onPause(() => event.emit(event.BLUR));
platform.onResume(() => event.emit(event.FOCUS));Turning the flags off instead would not work: they apply to the platform's events as well, so its pause would do nothing.
melonJS's save uses localStorage by default. save.setStorage() points it somewhere else:
-
For a cloud save, which loads and saves asynchronously (YouTube, Facebook),
save.createCloudStorage()makes the storage: load the save first, then hand over what was loaded and how to save it back. It keeps everything in memory, saves in the background one save at a time, andflush()saves at once.const cloud = save.createCloudStorage({ data: await platform.loadSave(), write: (items) => platform.writeSave(items), }); save.setStorage(cloud);
-
For a storage that answers straight away, such as a native wrapper's, hand
setStorage()its three calls:getItem,setItemandremoveItem.
WeChat needs neither: its adapter's localStorage is WeChat's own storage.
The game itself keeps using save as usual.
A platform with its own mute setting (YouTube) expects the game to follow it: audio.muteAll() and audio.unmuteAll() from its callback. Its mute then replaces any mute button of the game's own.
Portals often draw their own loading screen and want to know how far along the game is, or when it can be played:
-
event.LOADER_PROGRESSreports the loader's progress, from 0 to 1. -
event.GAME_AFTER_DRAWfires after each frame is drawn: the first one whilestate.LOADINGis current is the first frame of the loading screen. - A screen's
onResetEvent()is where the game becomes playable.
A portal's frame can start with no size at all and get its real size later, or change once the game starts. Start the application at a fixed size, let its scaling ("fit" or "flex") follow the frame, and call app.resize() if the frame changes without telling the page.
nx.js and Web Workers have no document: no page to put a canvas in. melonJS runs there from 20.14: give the application the canvas to draw to, with the canvas setting.
const app = new Application(1280, 720, {
canvas: theCanvas, // the runtime's display canvas
renderer: video.AUTO,
scale: 1,
});
await app.init();What changes without a page (sizing, Tiled maps, fonts, sound) is on each runtime's page.
WeChat Mini Games have no page either, but WeChat's adapter stands in for one, with a document, an Image and the on-screen canvas: see WeChat Mini Games.
Other portals, such as Poki or CrazyGames, have SDKs of the same kind: their own pause, save and ad calls. The pattern above should apply to them too, but their pages aren't written yet, since each SDK needs checking first.