
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
TextureAtlasand prefer one large tileset over several small ones, so a screenful of sprites fits inside the pool with room to spare. - Changing
blendMode,setBlendModeflushes 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
ShaderEffecton the quad batcher also turns multi-texture batching off for the duration, dropping you back to one texture per draw.


