# Melonjs Renderables

Use this skill when subclassing Renderable, writing a custom draw() method, handling...

- Repository: https://github.com/melonjs/melonJS (6430 stars)
- Category: Writing
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add melonjs/melonJS --skill melonjs-renderables -g -a claude-code -y`
Codex: `npx skills add melonjs/melonJS --skill melonjs-renderables -g -a codex -y`
Cursor: `npx skills add melonjs/melonJS --skill melonjs-renderables -g -a cursor -y`
Gemini CLI: `npx skills add melonjs/melonJS --skill melonjs-renderables -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add melonjs/melonJS`

## Description

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: Tween, easing, animate, Renderable, extends Renderable, draw(, update(, isKinematic, pointerEvent, registerPointerEvent, onClick, addPostEffect, removePostEffect, ShaderEffect, addChild, z-order, anchorPoint, floating.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Renderables, input and effects

> Subclassing `Renderable`, custom drawing, receiving pointer events, and
> applying post effects, with the traps that produce silently wrong output
> rather than an error.

Everything here is a **silent failure**: the code runs, nothing throws, and the
result is wrong. Those are the cases worth memorising, because nothing in the
type signatures warns you.

## 1. A custom `draw()` must position itself from `this.pos`

The renderer is **not** pre-translated to the renderable's position when `draw()`
is called. `Container.draw` translates by the *container's* own `pos` and then
calls `child.preDraw` / `draw` / `postDraw`; `preDraw` never translates by the
child's `pos`. Read `this.pos` and draw relative to it.

```js
class Marker extends Renderable {
    draw(renderer) {
        // ✗ draws at the parent container's origin, not at the marker
        renderer.fillRect(0, 0, this.width, this.height);

        // ✓
        renderer.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    }
}
```

The symptom is an object that renders correctly at position (0, 0) and appears
stuck at the top-left as soon as you move it.

**Zero the anchor in custom-draw renderables.** `preDraw` does not translate to
`pos`, but it *does* apply the anchor offset `(-width * anchorPoint.x,
-height * anchorPoint.y)`. With the default centred anchor, drawing at
`this.pos` therefore lands half a size off:

```js
constructor(x, y, w, h) {
    super(x, y, w, h);
    this.anchorPoint.set(0, 0);   // ← or every custom draw is offset by -w/2, -h/2
}
```

## 2. `isKinematic` must be `false` to receive input or collisions

`Renderable.isKinematic` **defaults to `true`**, which means *"physics collision
and input events will not impact this renderable"*. A kinematic renderable is
skipped by the pointer-event dispatcher entirely.

The rest: https://github.com/melonjs/melonJS/blob/HEAD/packages/melonjs/skills/melonjs-renderables/SKILL.md
