Skills

Melonjs Performance

Use this skill when a melonJS game drops frames, allocates heavily, or needs to scale...

Install

npx skills add melonjs/melonJS --skill melonjs-performance -g -a claude-code -y
Repository
melonjs/melonJS6.4k
Category
Testing
Updated
3d ago
License
MIT
Context cost
Mediumabout 3,000 tokens
Runs scripts
No, instructions only

What it does

Use this skill when a melonJS game drops frames, allocates heavily, or needs to scale to many objects. Covers object pooling, draw-call batching, atlases, baking with CanvasRenderTarget, instancing, culling and alwaysUpdate, the debug plugin, and where the real costs are. Triggers on: performance, slow, frame rate, fps, lag, pool, pool.register, pool.pull, batching, draw calls, InstancedMesh, culling, alwaysUpdate, inViewport, CanvasRenderTarget, optimise, profiling, debug plugin, memory, render targets, hdr.

Performance

Measure first

Register the debug plugin and read the numbers before changing anything:

import { plugin } from "melonjs";
import { DebugPanelPlugin } from "@melonjs/debug-plugin";

await app.init();
plugin.register(DebugPanelPlugin, "debugPanel");

It reports frame time, draw calls, object counts, and can overlay collision shapes and bounds. Draw calls is usually the number that matters.

Batching: the biggest lever

Both GPU backends batch across textures, not just within one: the quad batcher assigns each source image a texture unit and embeds the unit in the vertex data, so several different images still flush as a single draw. The pool is finite, the WebGL batcher gets renderer.maxTextures units (the maxTextures application setting, "auto" = the device limit capped at 32), the WebGPU batcher eight per segment. Overflow the pool and the batch flushes.

So the goal is not "one image" but "few state changes". What actually ends a batch:

  • Overflowing the texture-unit pool, pack sprites into a TextureAtlas and prefer one large tileset over several small ones, so a screenful of sprites fits inside the pool with room to spare.
  • Changing blendMode, setBlendMode flushes before it touches GL state. Group by blend mode where you can.
  • Switching batcher, interleaving primitives (strokeRect, fillRect, debug shapes) or meshes between sprites flushes the quad batcher and rebinds. Draw all the sprites, then all the primitives.
  • Binding a custom shader, a ShaderEffect on the quad batcher also turns multi-texture batching off for the duration, dropping you back to one texture per draw.
Read the whole SKILL.md on GitHub

More in Testing