Skip to content

Upgrade Guide

Olivier Biot edited this page Aug 2, 2026 · 366 revisions

This page list the public APIs change between melonJS release. To be noted that we always provide backward compatibility as much as possible by providing method wrapping on public deprecated API(s).

Important: melonJS uses Semantic Versioning, which means that only MAJOR version (e.g. moving from 9.x.x to 10.x.x) will introduce breaking API changes. For any other MINOR or PATCH version, melonJS API provides seamless upgrade.

melonJS 2 (ES6) Version

Note: As the initial 10.0 version marks the release of melonJS2, that is now fully ES6 compliant, all deprecated API and method from previous "legacy" versions (9.x and lower) have been removed. If you are looking for the changelog for the legacy version see here, see as well here for a dedicated upgrading guide from Legacy version of melonJS to melonJS 2

Note: To keep our code base as clean as possible, deprecated API are being kept until the next N+2 version, for example when publishing a new major 17.x version of melonJS, all deprecated API in version 14.x and before will be removed.

19.x.x to 20.0.0 (upcoming — in development)

  • Application : starting a game is now two steps — construct the Application, then await app.init() — and calling init() is mandatory, not optional. init() is asynchronous because a WebGPU device cannot be acquired synchronously; it still resolves without suspending on the Canvas and WebGL backends. Renderer failures surface as a rejection of init(), no longer as a constructor throw. This applies just as much to code already using new Application(...) on 19.x — constructing the instance no longer builds the renderer or appends the canvas; add await app.init() right after construction, or the application displays nothing.
  • Application : app.destroy() is now terminal — a destroyed Application cannot be re-initialized (init() rejects afterwards); construct a new instance to start again. A repeated init() on a live app is a warned no-op.
  • Application : the pre-created bootstrap application and the legacy setting are removed. The exported me.game now names the most recently initialized Application — it never points at a half-built app, and it is undefined until the first init() resolves. Hold your own reference (const app = new Application(...)) instead of reaching for the global.
  • Renderer : custom renderer classes gained an argument-less async init() lifecycle hook that Application#init awaits after construction. Classes extending Renderer need no changes (the base class resolves immediately); a custom renderer that already had its own init() method should expect the engine to call it with no arguments.
  • video : video.init() is removed (deprecated since 18.3.0). Use the Application entry point:
// before
if (!me.video.init(640, 480, { parent: "screen", renderer: me.video.AUTO })) {
    alert("Your browser does not support HTML5 canvas.");
    return;
}

// after
try {
    const app = new me.Application(640, 480, { parent: "screen", renderer: me.video.AUTO });
    await app.init(); // mandatory — builds the renderer and appends the canvas
} catch {
    alert("Your browser does not support HTML5 canvas.");
    return;
}

Note the failure mode changed: video.init() returned false when the canvas could not be created, whereas app.init() rejects. catch the rejection if you were relying on the boolean.

  • video : video.renderer is removed (deprecated since 18.3.0). Use app.renderer — or me.game.renderer where only the global is in reach.
  • video : video.createCanvas() is removed (deprecated since 19.7.0). Use app.renderer.createCanvas(width, height, [returnOffscreenCanvas]) — the renderer instance reached through Application#renderer is the supported entry point.
// before
const canvas = me.video.createCanvas(64, 64);
// after
const canvas = app.renderer.createCanvas(64, 64);
  • video : video.getParent() is removed (deprecated since 18.3.0). Use app.getParentElement().
  • video : the WebGL renderer is now WebGL 2 only — the WebGL 1 fallback path has been removed (#1509). On the rare devices without WebGL 2 support, renderer: video.AUTO now falls back to the Canvas renderer, and an explicit renderer: video.WEBGL makes app.init() reject. No action needed for the overwhelming majority of devices (WebGL 2 has been universal for years, including Safari); if you must target WebGL-1-only hardware, stay on the 19.x line or use the Canvas renderer.
  • Application : the preferWebGL1 setting and the #webgl1 URL flag are removed (#webgl and #webgl2 are synonyms)
  • device : isWebGLSupported() now probes for a WebGL 2 context, so it always agrees with what renderer construction actually requests
  • Renderer : WebGLVersion is deprecated and always returns 2; renderer.type is always "WebGL2" for the WebGL renderer
  • Batcher : each batcher now owns an immutable Vertex Array Object, built once in init() — the vertex attribute layout is frozen from that point on, a batcher switch is a single bindVertexArray, and steady-state frames issue no attribute-specification calls at all. Custom batchers that subclass Batcher / QuadBatcher and chain to super.init() / super.bind() need no changes. Two things to be aware of if you wrote lower-level code: calling gl.vertexAttribPointer / enable/disableVertexAttribArray yourself now mutates the bound batcher's frozen vertex state rather than global GL state, and addAttribute() throws once the vertex state exists (declare your layout before/inside init()).
  • custom shaders : a shader hosted by a built-in batcher must declare that batcher's attributes first, in the batcher's layout order — attribute locations are bound in vertex-source declaration order and the vertex state is frozen against the default shader's mapping. Shaders generated by ShaderEffect already comply, so ordinary effects are unaffected; a raw GLShader that declares them out of order will read the wrong vertex data, and logs a console warning identifying the mismatch. GLShader.setVertexAttributes() is still public but is no longer called by the engine.

19.9.0 to 19.9.1 (Stable)

no breaking API changes — two behavior corrections worth knowing about:

  • Application : the game canvas now defaults to display: block (the browser's inline default created a baseline gap that could feed a canvas-growth loop under auto-scaling, #1231); set any inline display style on the canvas to keep your own value
  • Sprite : video sprites now genuinely pause on state.pause() — this was always the documented behavior, but the internal listener never fired

19.6.x to 19.7.x (Stable)

  • video : video.createCanvas(width, height, returnOffscreenCanvas) is now deprecated — use the new Renderer.createCanvas(width, height, returnOffscreenCanvas) static method instead. The old call still works (with a console deprecation warning) but forwards to the renderer-side API. Centralizing canvas allocation on Renderer makes it reachable without an active renderer instance (e.g. from a Mesh constructor) and decouples it from the deprecating video namespace.

19.2.x to 19.3.x (Stable)

  • Light2d : now centered on its pos (anchorPoint = (0.5, 0.5)) to match Sprite and Ellipse(x, y, w, h) conventions — constructor x/y and light.pos denote the light's center, not the bounding-box top-left. Existing call sites that passed top-left coordinates need to shift by the radii: new Light2d(x, y, r)new Light2d(x + r, y + r, r). Code using light.centerOn(x, y) is unaffected. Transforms (scale, rotate) now pivot around the visual center.

18.x.x to 19.0.0 (Stable)

  • Renderable : currentTransform is now a Matrix3d (was Matrix2d) — code accessing val[6]/val[7] for tx/ty must use val[12]/val[13]
  • Renderable : rotate(angle, axis) now accepts an optional axis parameter (defaults to Z axis)
  • Renderable : scale(x, y, z) now accepts an optional z parameter (defaults to 1)
  • Matrix3d : scale(x, y, z) default z changed from 0 to 1
  • Matrix3d : rotate(angle, axis) axis parameter now optional, defaults to Z axis
  • Matrix3d : multiply(m) now accepts both Matrix3d and Matrix2d
  • Matrix3d : rotate() returns this instead of null on zero-length axis
  • Matrix2d : fromMat3d() now extracts translation from indices [12],[13] (was [8],[9])
  • Text : draw() no longer accepts text, x, y parameters — standalone draw removed (deprecated since 10.6.0)
  • BitmapText : draw() no longer accepts text, x, y parameters — standalone draw removed (deprecated since 10.6.0)
  • Text : measureText() no longer takes a renderer parameter (was unused)
  • UITextButton : settings backgroundColor and hoverColor removed — use hoverOffColor and hoverOnColor
  • Tween : no longer adds itself to game.world — uses event-based lifecycle (TICK, GAME_AFTER_UPDATE, STATE_PAUSE, STATE_RESUME, GAME_RESET). Public API (to(), start(), stop(), chain(), etc.) is unchanged. isPersistent and updateWhenPaused still supported.
  • Application : depthTest setting removed — GPU depth sorting is incompatible with 2D alpha blending. Depth testing remains available internally for 3D mesh rendering only (drawMesh).

18.2.x to 18.3.x (Stable)

  • Application : new Application(width, height, options) is now the recommended entry point. video.init(), video.renderer, video.getParent(), and device.onReady() are deprecated — use Application directly and access the renderer via app.renderer
  • Stage : onResetEvent(app, ...args) and onDestroyEvent(app) now receive the Application instance as first parameter
  • Container : default dimensions are now Infinity (no intrinsic size) — the game.viewport dependency has been removed

18.1.x to 18.2.x (Stable)

no breaking API changes

18.0.0 to 18.1.x (Stable)

  • Renderer : Compositor, QuadCompositor, and PrimitiveCompositor are now deprecated in favor of Batcher, QuadBatcher, and PrimitiveBatcher

17.x.x to 18.0.0 (Stable)

  • chore : deprecated classes and methods from version 15 and lower have been removed (Texture, DraggableEntity, DroptargetEntity, getScreenCanvas, getScreenContext, GUI_Object, getWidth, getHeight)

16.x.x to 17.0.0 (Stable)

  • loader : the nocache, crossOrigin and withCredentials loader options, now have to be set using the setOptions() method, for example : me.loader.setOptions({ crossOrigin : "anonymous" });

15.x.x to 16.0.0 (Stable)

no breaking API changes

14.5.x to 15.0.0 (Stable)

  • UI: GUI_Object is now deprecated and replaced by two new classes, UISpriteElement and UITextButton
  • Text : drawStroke() is now deprecated in favour of the lineWidth property, which when set to a value greater than 0 will automatically stroke the text

13.0.x to 14.0.0 (Stable)

no breaking API changes

12.0.x to 13.0.x (Stable)

  • device: as part of device refactoring to a proper ES6 syntax, the previous device.isFullScreen property has been changed into a device.isFullScreen() function
  • device: deprecated function device.turnOnPointerLock and device.turnOffPointerLock since version 10.3 have been removed; please use input.requestPointerLock() or input.exitPointerLock()
  • Physic: when applying a force, melonJS will now automatically reset the remaining force to 0 at the end of the update loop.

11.0.x to 12.0.x (Stable)

  • Core: utils.string helper trim functions have been removed in favour to their native es10 equivalent (String.trimLeft and String.trimRight)

10.12.x to 11.0.x (Stable)

  • Renderable: the Light2d constructor now takes an additional parameter (x, y, radiusX, [radiusY], [color], [intensity]) allowing to create elliptical shaped lights

10.5.x to 10.12.x (Stable)

no breaking API changes

10.4.x to 10.5.x (Stable)

  • Renderable: DraggableEntity and DroptargetEntity have been renamed to Draggable and DropTarget

10.3.x to 10.4.x (Stable)

  • Renderer: the video.renderer.Texture class is now directly available as TextureAtlas

10.0.x to 10.3.x (Stable)

  • Input: device.turnOnPointerLock() and device.turnOffPointerLock() have been replaced respectively by input.requestPointerLock() and input.exitPointerLock(), and updated to the latest 2.0 specs

Clone this wiki locally