Skip to content

v19.6.0

Choose a tag to compare

@obiot obiot released this 22 May 23:31
· 34 commits to master since this release
39631a3

What's New in melonJS 19.6.0

WebGL context-loss hardening release. Fixes a Windows + Chrome crash where a GPU switch lost the WebGL context and a partial GLShader.destroy() left the next frame's setUniform("uTime", …) reading from null uniforms. Beyond the crash, the renderer now transparently recovers the rest of the pipeline (vertex buffer, default GL state, batchers, texture cache) across a webglcontextlostwebglcontextrestored cycle, and shaders replay their cached uniforms on restore — so the game keeps drawing across a GPU switch without any intervention from user code.

New Features

  • Transparent WebGL context recovery, pipeline-wide — the renderer re-creates its vertex buffer, re-applies default GL state, re-initialises every batcher, drops stale texture-unit assignments, and emits ONCONTEXT_RESTORED so GLShader / ShaderEffect instances recompile + replay their cached uniforms. NVIDIA Optimus GPU switches, browser tab eviction recovery, and WEBGL_lose_context teardowns no longer require user code to re-apply uniforms, re-upload textures, or recreate shaders.
  • GLShader.destroyed / GLShader.suspended / ShaderEffect.destroyed — public read-only diagnostic flags. destroyed is the stable "explicitly released" signal (distinct from ShaderEffect.enabled, which auto-toggles across the cycle); suspended is true only between lost and restored.

Changed

  • Platformer example coins migrated to per-instance ShineEffect, matching the pattern of every other 19.5+ shader-using example. GAME_UPDATE subscription tied to onActivateEvent / onDeactivateEvent so pool-recycled coins re-bind on respawn instead of leaking a dead handler per pickup.

Bug Fixes

  • Stale shader references no longer crashGLShader.destroy() is atomic + idempotent and wraps gl.deleteProgram in a try / catch, so a throw on a dead ANGLE / D3D11 context (the 19.5.0 Windows + Chrome TypeError: Cannot read properties of null (reading 'uTime') crash) can't leave a half-destroyed shader. Public setUniform / bind / getAttribLocation paths also no-op on destroyed shaders instead of throwing.
  • ShaderEffect.destroy() sets enabled = false BEFORE the inner destroy — even if the inner destroy throws outward, the effect's public methods are already in the safe no-op state via the enabled gate.
  • GLShader._uniformCache snapshots arrays / typed arrays via captureValue on write, so caller mutation after setUniform can't silently rewrite what replays on context restore.
  • ShaderEffect.enabled auto-toggle preserves user-set state across a context cycle — an effect the user explicitly disabled stays disabled after restore.

Performance

  • GLShader.setUniform zero-allocation hot path — the replay cache reuses the existing slot's array (via captureValue) when the value's length matches. Steady-state writes for the same uniform name (light positions, animation uniforms, per-frame uTime) no longer allocate a fresh array on every call.

Install

npm install melonjs@19.6.0