Communitygithub.com

melonis/melonjs-performance

Use esta habilidade quando um jogo melonJS estiver com baixo FPS, alocando muitos recursos ou precisando escalar para muitos objetos. Abrange: pool de objetos, batelada de chamadas de desenho, atlas, baking com CanvasRenderTarget, instanciamento, culling, alwaysUpdate, plugin de depuração e onde estão os custos reais.

O que é melonjs-performance?

Esta habilidade é projetada para desenvolvedores que usam o framework melonJS e enfrentam problemas de desempenho, como quedas de frames (FPS baixo), uso excessivo de memória ou necessidade de lidar com muitos objetos na cena. Ela oferece um conjunto de técnicas e boas práticas para otimização, incluindo: pool de objetos (para reutilizar objetos em vez de criar/remover constantemente), batelada de chamadas de desenho (reduzindo o número de draw calls por frame), uso de atlas de textura para minimizar trocas de estado da GPU, rendering em texturas com `CanvasRenderTarget`, instanciamento (`InstancedMesh`), e configuração de culling (remoção de objetos fora da tela) e `alwaysUpdate` para controle de atualização. A habilidade também explica como usar o plugin de depuração do melonJS para identificar gargalos de CPU e memória. Funciona em todas as plataformas suportadas pelo melonJS (Web, mobile, etc.) e é baseada em documentação oficial e melhores práticas da comunidade. O conteúdo é apresentado em formato SKILL.md, com exemplos de código e explicações passo a passo.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/melonjs/melonJS/tree/master/packages/melonjs/skills/melonjs-performance

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que melonjs-performance faz?

Use esta habilidade quando um jogo melonJS estiver com baixo FPS, alocando muitos recursos ou precisando escalar para muitos objetos. Abrange: pool de objetos, batelada de chamadas de desenho, atlas, baking com CanvasRenderTarget, instanciamento, culling, alwaysUpdate, plugin de depuração e onde estão os custos reais. As ações são acionadas por palavras-chave como: performance, slow, frame rate, fps, lag, pool, pool.register, pool.pull, batching, draw calls, InstancedMesh, culling, alwaysUpdate, inViewport, CanvasRenderTarget, optimise, profiling, debug plugin, memory.

Pool de Objetos (Object Pooling)

  • Objetivo: Reduzir alocações de memória e coleta de lixo (Garbage Collection) reutilizando objetos em vez de criá-los/destruí-los constantemente.
  • Como usar:
    1. Registre a classe do objeto com me.pool.register("meuObjeto", MinhaClasse). Exemplo:
      import { pool } from 'melonjs';
      pool.register('bullet', BulletEntity);
      
    2. Em vez de new MinhaClasse(), use pool.pull('meuObjeto') para obter uma instância do pool.
    3. Quando o objeto não for mais necessário, retorne-o ao pool chamando obj.release() (ou método similar, que deve ser implementado na classe).
  • Benefício: Menos alocações, menor pressão no GC, frames mais estáveis.

Batelada de Chamadas de Desenho (Draw-Call Batching)

  • Contexto: Cada chamada de desenho (draw call) é cara. Agrupar objetos que compartilham a mesma textura/shader reduz o número de chamadas.

  • Como otimizar:

    • Atlas de textura: Combine várias imagens pequenas em uma única textura grande (por exemplo, usando TexturePacker). Carregue o atlas com me.loader.preload.
    • Instanciamento: Use me.ObjectEntity com renderable.isPersistent = true e, se possível, utilize me.Renderer.drawInstanced ou InstancedMesh para renderizar muitas cópias do mesmo sprite com uma única chamada de desenho.
    • CanvasRenderTarget: Para elementos estáticos (como um fundo), renderize uma vez em um CanvasRenderTarget (textura de renderização) e depois desenhe essa textura como um único sprite.

    Exemplo com CanvasRenderTarget:

    import { CanvasRenderTarget, Vector2d } from 'melonjs';
    let target = new CanvasRenderTarget(800, 600);
    // renderize objetos no target
    // depois, no loop principal, desenhe apenas o target:
    target.render(me.video.getRenderer(), 0, 0);
    

Culling e alwaysUpdate

  • Culling: Desabilite o desenho e a atualização de objetos que estão fora do viewport (tela). Use a propriedade inViewport ou implemente lógica própria com me.viewport.isVisible().
    • Exemplo:
      if (!me.viewport.isVisible(this.pos.x, this.pos.y, this.width, this.height)) {
          this.setVisible(false);
          return; // pula a atualização
      }
      
  • alwaysUpdate: Por padrão, objetos que não estão no viewport não são atualizados (se alwaysUpdate = false, que é o padrão). Se um objeto precisa ser atualizado mesmo fora da tela (ex: IA de inimigo distante), defina this.alwaysUpdate = true.
    • Atenção: Use com moderação – muitos objetos com alwaysUpdate = true podem consumir CPU desnecessariamente.

Plugin de Depuração (Debug Plugin)

  • Ativação: Ative o plugin de depuração durante o desenvolvimento para visualizar métricas:
    import { debug } from 'melonjs';
    me.debug.renderHitBox = true;
    me.debug.renderVelocity = true;
    // ou ative o painel de debug via starter template
    
  • Como usar: Inicie o jogo com a flag --debug ou pressione F12 para abrir o painel do plugin. Lá você verá:
    • FPS atual e histórico
    • Número de objetos ativos (active objects)
    • Memória (total, alocada, GC runs)
    • Draw calls por frame
  • Interpretação: FPS abaixo de 60 com alto número de draw calls (>100) sugere que batching é necessário. Picos de memória indicam alocações excessivas – considere pool de objetos.

Onde estão os verdadeiros gargalos?

  1. CPU: Profiling com me.debug ou ferramentas do navegador (Chrome DevTools). Procure funções que consomem muito tempo, como atualização de física, IA ou renderização individual de muitos objetos.
  2. GPU: Baixo FPS com draw calls baixas pode indicar shaders complexos ou texturas grandes. Use o painel de debug para ver o número de draw calls e pixels preenchidos.
  3. Memória: Alocações frequentes (GC) causam pausas. Use o profiler de memória do navegador e verifique se objetos estão sendo criados/destruídos em loop – solução: pool de objetos.

Exemplo Integrado

Combinação de pool, batching e culling para uma cena de muitos projéteis:

import { pool, CanvasRenderTarget, viewport } from 'melonjs';

class Bullet extends me.Sprite {
    constructor(x, y) {
        super(x, y, { image: 'bullet' });
        this.alive = false;
    }
    // ... métodos onActivate, onDeactivate
}

// Registrar
pool.register('bullet', Bullet);

// No loop de atualização:
function spawnBullet(x, y) {
    let bullet = pool.pull('bullet', x, y);
    me.game.world.addChild(bullet);
}

// Culling: verificar se está visível
bullet.update = function(dt) {
    if (!viewport.isVisible(this)) {
        this.release(); // retorna ao pool
        return false;
    }
    // lógica de movimento
    return true;
};

Notas Finais

  • Sempre perfilar antes de otimizar. Adivinhações podem piorar o desempenho.
  • Use o plugin de debug como primeira ferramenta.
  • Comece com pool de objetos e batching – essas são as otimizações de maior impacto na maioria dos jogos melonJS.

Individual skills in this repo

This repo contains 10 individual skills — each has its own dedicated page.

melonjs/melonjs-3d

Use this skill for anything 3D or 2.5D in melonJS — Camera3d, Mesh, InstancedMesh, Sprite3d billboards, Light3d, ground shadows, glTF/GLB scenes, and depth sorting. Covers the Y-down/+Z-forward convention that is the inverse of OpenGL, the cameraClass opt-in, clip planes, and what does not work on the Canvas fallback. Triggers on: Camera3d, Mesh, InstancedMesh, Sprite3d, Light3d, billboard, glTF, glb, 3D, 2.5D, depth, cameraClass, fov, setClipPlanes, setFog, fog, distance fog, height fog, heightFalloff, transparent, transparency, alpha, blendMode, fade, castGroundShadow, lit.

melonjs/melonjs-3d-assets

Use this skill when loading 3D models into melonJS — glTF and GLB scenes, OBJ/MTL models, materials, imported lights, node animation, ground shadows and GPU instancing. Covers level.load options including the async flag, the rightHanded conversion, and exactly what the loader does and does not support. Triggers on: glTF, gltf, glb, OBJ, MTL, 3D model, getGLTF, getOBJ, getMTL, GLTFModel, GLTFScene, level.load glb, rightHanded, lightIntensityScale, castGroundShadow, shadowGroundY, EXT_mesh_gpu_instancing, KHR_lights_punctual, skinning, Blender export, 3D asset.

melonjs/melonjs-camera-and-drawing

Use this skill for camera control and immediate-mode drawing in melonJS — following a target, viewport bounds, shake and fade, secondary cameras, and drawing shapes, lines and gradients inside a custom draw(). Covers world versus screen coordinate conversion, clipping and masking, and baking with CanvasRenderTarget. Triggers on: Camera2d, viewport, follow, setBounds, shake, fadeIn, fadeOut, worldToLocal, localToWorld, colorMatrix, renderer.fill, renderer.stroke, Rect, Ellipse, Polygon, Line, Gradient, clipRect, mask, CanvasRenderTarget, NoiseTexture2d.

melonjs/melonjs-effects-and-shaders

Use this skill for post-processing effects, custom shaders, blend modes and colour grading in melonJS. Covers the built-in ShaderEffect presets, addPostEffect on renderables and cameras, writing a custom dual-language GLSL/WGSL effect, the screen_texture builtins, and why effects silently do nothing on the Canvas fallback. Triggers on: ShaderEffect, addPostEffect, removePostEffect, getPostEffect, VignetteEffect, GlowEffect, BlurEffect, PixelateEffect, ScanlineEffect, shader, GLSL, WGSL, uniform, setUniform, setTexture, setTime, blendMode, colorMatrix, screen_texture, toFrameTexture, post effect, filter.

melonjs/melonjs-loading-assets

Use this skill for loading and managing game assets in melonJS — the resource descriptor format, the full asset type list, preload versus load, retrieving loaded assets, base URLs and cross-origin settings, and the loading screen. Triggers on: loader, loader.preload, loader.load, resources, getImage, getJSON, getTMX, getGLTF, getVideo, getFont, setBaseURL, setOptions, crossOrigin, withCredentials, credentials, cookies, authenticated assets, CORS, asset, preload, LOADER_COMPLETE, loading screen, unload.

melonjs/melonjs-physics

Use this skill for collision, physics bodies, movement, and spatial queries in melonJS — the built-in SAT world and the planck/matter adapters. Covers bodyDef vs Body, collision types and masks, the collision callback family and their firing rules, raycast/queryAABB/querySphere, and the behaviour differences between adapters. Triggers on: Body, bodyDef, collision, collisionType, collisionMask, onCollision, onCollisionStart, onCollisionActive, raycast, queryAABB, querySphere, PlanckAdapter, MatterAdapter, gravity, velocity, applyForce, isGrounded, SAT.

melonjs/melonjs-renderables

Use this skill when subclassing Renderable, writing a custom draw() method, handling pointer or click events on game objects, applying post effects and shaders, or controlling draw order. Covers the pos-relative draw contract, isKinematic and input, addPostEffect vs the deprecated shader property, and z-ordering. Triggers on: Renderable, extends Renderable, draw(, update(, isKinematic, pointerEvent, registerPointerEvent, onClick, addPostEffect, removePostEffect, ShaderEffect, addChild, z-order, anchorPoint, floating.

melonjs/melonjs-renderer-backends

Use this skill when a feature works on one machine and not another, when choosing or pinning a renderer, or when writing code that must degrade gracefully. Covers the WebGPU to WebGL 2 to Canvas fallback ladder, what each backend supports, capability detection, and the subsystems that warn once and then stop working on Canvas. Triggers on: video.AUTO, video.WEBGPU, video.WEBGL, video.CANVAS, renderer.type, supportsDepthBuffer, shaderLanguage, WebGPU, WebGL2, Canvas fallback, context loss, backen

melonjs/melonjs-scenes-and-state

Use this skill for scene structure and game flow in melonJS — Stage subclasses, the state manager, transitions, pausing, the update loop, timers and tweens. Covers onResetEvent versus the constructor, state.set before state.change, the camera and world lifecycle per stage, and pause-aware timing. Triggers on: Stage, state, state.set, state.change, state.transition, state.pause, onResetEvent, onDestroyEvent, onActivateEvent, onDeactivateEvent, PLAY, MENU, LOADING, update loop, GAME_UPDATE, timer, setTimeout, setInterval, Tween, freeze.

melonjs/melonjs-ui-and-text

Use this skill for HUDs, buttons, menus, dialogue panels and on-screen text in melonJS. Covers UIBaseElement/UISpriteElement/UITextButton, Draggable and DropTarget, the floating screen-space container pattern, Text and BitmapText, web font loading, and NineSliceSprite panels. Triggers on: UI, HUD, button, UIBaseElement, UISpriteElement, UITextButton, Draggable, DropTarget, menu, dialogue, Text, BitmapText, font, fontface, wordWrapWidth, NineSliceSprite, score display, floating.

Habilidades Relacionadas