Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "melonjs",
"description": "Skills for building games with melonJS, the open source 2D, 2.5D and 3D HTML5 game engine.",
"owner": { "name": "melonJS", "url": "https://melonjs.org" },
"plugins": [
{
"name": "melonjs",
"source": "./",
"description": "Build games with melonJS — 23 guides to the 2D, 2.5D and 3D HTML5 game engine, its conventions and idioms, so generated code runs the first time."
}
]
}
38 changes: 38 additions & 0 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "melonjs",
"version": "20.3.0",
"description": "Build games with melonJS — 23 guides to the 2D, 2.5D and 3D HTML5 game engine, its conventions and idioms, so generated code runs the first time.",
"author": {
"name": "melonJS",
"url": "https://melonjs.org"
},
"homepage": "https://melonjs.org",
"repository": "https://github.com/melonjs/melonJS",
"license": "MIT",
"keywords": ["melonjs", "game-engine", "html5", "webgpu", "webgl", "gamedev"],
"skills": [
"./packages/melonjs/skills/melonjs",
"./packages/melonjs/skills/melonjs-getting-started",
"./packages/melonjs/skills/melonjs-20-migration",
"./packages/melonjs/skills/melonjs-renderables",
"./packages/melonjs/skills/melonjs-3d",
"./packages/melonjs/skills/melonjs-3d-assets",
"./packages/melonjs/skills/melonjs-physics",
"./packages/melonjs/skills/melonjs-sprites-and-animation",
"./packages/melonjs/skills/melonjs-input",
"./packages/melonjs/skills/melonjs-effects-and-shaders",
"./packages/melonjs/skills/melonjs-tilemaps",
"./packages/melonjs/skills/melonjs-audio",
"./packages/melonjs/skills/melonjs-scenes-and-state",
"./packages/melonjs/skills/melonjs-ui-and-text",
"./packages/melonjs/skills/melonjs-particles-and-trails",
"./packages/melonjs/skills/melonjs-camera-and-drawing",
"./packages/melonjs/skills/melonjs-lighting",
"./packages/melonjs/skills/melonjs-deployment",
"./packages/melonjs/skills/melonjs-loading-assets",
"./packages/melonjs/skills/melonjs-renderer-backends",
"./packages/melonjs/skills/melonjs-performance",
"./packages/melonjs/skills/melonjs-events",
"./packages/melonjs/skills/melonjs-plugins"
]
}
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,46 @@ Transpiling costs some size and speed: private class members become `WeakMap`
lookups, which are on hot paths in the renderer. Only reach for it if you have
users on browsers that need it.

Building with AI agents
-------------------------------------------------------------------------------

melonJS ships **skills** — guidance files that teach AI coding assistants the
engine's conventions and, more usefully, the mistakes that fail silently rather
than raising an error.

They are installed with the package, at `node_modules/melonjs/skills/`, and are
versioned with the engine — so the guidance always matches the release you have.

**Claude Code** — install as a plugin :

```
/plugin marketplace add melonjs/melonJS
```

or copy the skills into a project :

```bash
mkdir -p .claude/skills && cp -r node_modules/melonjs/skills/melonjs* .claude/skills/
```

**Other agents** (Codex, Cursor, Gemini CLI, …) read an `AGENTS.md` from your own
project root. One ships ready to use — copy it across :

```bash
cp node_modules/melonjs/skills/AGENTS.md ./AGENTS.md
```

It points at the shipped skills, names the three rules that produce code which
runs and is wrong, and links the API index below. If you already have an
`AGENTS.md`, paste its sections into yours.

The skills are plain markdown and can be read by any agent, or by a human.

For anything the skills do not cover, the complete API is indexed for agents at
[llms.txt](https://melonjs.github.io/melonJS/llms.txt) — every exported class,
function and type with a one-line summary and a link to its reference page,
regenerated on every docs build.

Community
-------------------------------------------------------------------------------
Join us and get help or share your projects :
Expand Down
18 changes: 12 additions & 6 deletions packages/melonjs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
# Changelog

## [20.3.0] (melonJS 2) - _unreleased_
## [20.3.0] (melonJS 2) - _2026-08-31_

### Added
- Skills for AI coding assistants, shipped in the package at `skills/` and versioned with the engine. Twenty-three topic guides — bootstrap, scenes, renderables, sprites, input, physics, tilemaps, audio, UI and text, shaders, particles, lighting, the 3D tier and its asset formats, loading, backends, events, performance, plugins and the 20.x migration — each ending with a symptom-to-cause table for the failures that are silent rather than fatal: a custom `draw()` that ignores `this.pos`, `isKinematic` blocking pointer events, `.z` set after `addChild`, `removePostEffect()` destroying the effect. Installable in Claude Code via `/plugin marketplace add melonjs/melonJS`; for agents following the `AGENTS.md` convention (Codex, Cursor, Gemini CLI) a ready-made `skills/AGENTS.md` ships alongside them, to copy into a game's project root
- Documentation: an `llms.txt` index is now published with the API reference at <https://melonjs.github.io/melonJS/llms.txt>, listing every exported class, function, interface, type and namespace with a one-line summary, a link to its page and a marker on the deprecated ones. Regenerated from the TSDoc comments on every docs build, so an agent that cannot find something in a skill has one URL to fetch rather than an API name to guess
- Audio: sprite support — a clip can declare named regions of one file (`sprite: { jump: [0, 450] }`) and `audio.play("sfx", { sprite: "jump" })` plays one, so a single download can carry many effects. `play()`'s second argument now takes either the original `loop` boolean or an options object (`sprite`, `loop`, `onend`, `volume`); every existing call form is unchanged
- Audio: `duration()`, `playing()` and `state()` report a clip's length, whether it is playing, and its load state
- Audio: `pool`, `rate`, `mute`, `preload` and `format` can be set when loading a clip, along with an `on` map of lifecycle callbacks (`play`, `pause`, `stop`, `end`, `fade`, `seek`, `rate`, `volume`, `mute`, `unlock`). Each is forwarded only when set, so existing declarations are unaffected
- Device: `platform.appleVendor` reports whether the browser is Apple's WebKit, which `platform.iOS` does not answer — a Mac running Safari is one but not the other
- Input: added `input.setPreventDefault(value)`. `input.preventDefault` is documented as a global option but is a read-only module binding, so assigning to it silently had no effect; the setter is the working form, and `bindKey`'s fourth argument still overrides it per binding

### Changed
- Engine: melonJS has no runtime dependencies. `core-js` provided three language polyfills — `globalThis`, `String.trimStart` and `String.trimEnd` — all of which are ES2019/ES2020 features that predate the ES2022 bundle target by years, so they were no-ops in every environment the engine supports. `globalThis` in particular was added for Node ([#1092](https://github.com/melonjs/melonJS/issues/1092)), which has had it natively since Node 12. Removing it drops 15.6 kB from the bundle and 1.3 MB from every install. Games needing older browsers must transpile *and* polyfill, which is the consumer's build to configure — a library patching `String.prototype` for the whole application was never the right call
- Loader: the shared fetch helper moved from `loader/parsers/` to `utils/`. It is engine transport rather than loader policy, and every asset type — including audio, which needs it for the `file:` fallback — is a peer consumer of it. Internal module, no public API change
- Loader: audio is registered like every other asset type, through a parser in `loader/parsers/`. The loader previously imported the whole audio module to register its load function directly, so it was the one type whose parser was not a parser. It now has no direct dependency on the audio module, which keeps a future backend change from rippling into the loader
- Audio: the engine no longer depends on a third-party audio library. The backend is now maintained in-tree, which removes melonJS's last runtime dependency besides core-js and fixes a long-standing packaging wart: the emitted type declarations referenced the library, so consumers type-checking with `skipLibCheck: false` had to install it themselves
- Audio: the engine no longer depends on Howler, the third-party audio library — the backend is now maintained in-tree. This also fixes a long-standing packaging wart: the emitted type declarations referenced the library, so consumers type-checking with `skipLibCheck: false` had to install it themselves
- Loader: the `onload`, `onProgress` and `onError` properties are removed. Deprecated since 18.2.0, they were `let` bindings on an ES module namespace — `loader.onProgress = fn` threw a `TypeError`, so the documented callback API could never be used by anyone. Use the `LOADER_COMPLETE` / `LOADER_PROGRESS` / `LOADER_ERROR` events, or `preload(assets, onloadcb)`

### Fixed
- Audio: sound files failed to load when the game is served from `file://` — a Cordova or Capacitor APK on Android, most commonly. `fetch()` cannot read that scheme in those WebViews, and audio was the only asset type still calling it directly instead of going through the engine's loader, which falls back to XHR
- Tiled: an object with no explicit geometry got a **triangular** collision shape. The default shape was built from three vertices — `(0,0)`, `(w,0)`, `(w,h)` — so the lower-left half of every plain rectangle in a map was not solid
- Timer: `setInterval`'s `pauseable` argument was ignored — the expression storing it was unconditionally true, so a repeating timer could never be made to keep running while the engine is paused. `setTimeout` was unaffected. A pause-menu animation or a countdown that should not freeze now works as documented ([#1619](https://github.com/melonjs/melonJS/issues/1619))
- Loader: a failed asset reported `Cannot read properties of undefined (reading 'onError')` instead of `Failed loading resource <src>` when `preload` was called detached from the `loader` namespace, masking the real failure — the error path read `this.onError` from a module function, which has no `this`
- Lighting: the one-time console warning for normal-map lighting named the WebGL renderer and told you to switch to `video.WEBGL`, which sent WebGPU users chasing a fallback they were not on — WebGPU implements the lit pipeline too. It now names a GPU backend, and says that `Light2d` glow and stage lighting still draw on Canvas
- Docs: a sweep of the API reference against the source it documents. `Renderable#draw` told you to draw at `(0, 0)` when `preDraw` never translates to `this.pos`; the `body` example called `viewport.follow(this.pos, …)`, which throws; `Camera3d` documented a `roll` axis that does not exist; `Mesh` omitted eight constructor settings including `lit`, the switch for the whole lit-mesh path; the `Asset` typedef advertised `"tmj"` / `"tsj"` asset types that throw (those are file extensions under `"tmx"` / `"tsx"`); `Body#addShape`'s documentation had drifted onto a private helper, leaving the public method undocumented; and 18 effect classes carried an unresolvable `@param` import path plus examples teaching `renderable.shader =`, deprecated since 19.2.0. `setBlendMode` also claimed on all three backends that "every renderer supports the full set", when `"none"` needs a GPU backend — on Canvas it resolves to `"normal"`, which `setBlendMode` reports back
- Docs: the README gained a short guide on transpiling for older browsers, including the trap that catches people — build setups skip `node_modules` by default, so melonJS is left untouched however low the target is set
- Docs: the README described the engine as ES6 and gave no target for the published bundle, which reads as a compatibility claim it does not meet — the bundle uses private class members and ~700 ES2020 constructs, so an ES6-era browser cannot parse it at all. It now states the ES2022 target once, where someone deciding whether to adopt will look. The CDN example also still referenced v19
- Audio: sound files failed to load when the game is served from `file://` — a Cordova or Capacitor APK on Android, most commonly. `fetch()` cannot read that scheme in those WebViews, and audio was the only asset type still calling it directly instead of going through the engine's loader, which falls back to XHR
- Device: `platform.Kindle` missed every current Fire tablet. It required `Silk` followed by `Mobile Safari`, but Chromium-based Silk ends its user agent with `Safari/537.36`; it now matches the `Silk/` token directly

## [20.2.0] (melonJS 2) - _2026-08-29_
Expand Down
9 changes: 5 additions & 4 deletions packages/melonjs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "melonjs",
"version": "20.2.0",
"version": "20.3.0",
"description": "melonJS Game Engine",
"homepage": "http://www.melonjs.org/",
"type": "module",
Expand Down Expand Up @@ -50,9 +50,10 @@
},
"files": [
"build",
"package.json",
"skills",
"README.md",
"CHANGELOG"
"CHANGELOG",
"package.json"
],
"devDependencies": {
"@types/node": "^25.6.0",
Expand All @@ -76,7 +77,7 @@
"build": "pnpm lint && tsx scripts/build.js && pnpm types",
"dist": "pnpm clean && pnpm lint && pnpm vitest run && pnpm build && pnpm doc && cp ../../README.md .",
"dist:publish": "pnpm clean && pnpm lint && pnpm build && pnpm doc && cp ../../README.md .",
"doc": "tsx scripts/check-doc-readme.ts && typedoc src/index.ts --tsconfig tsconfig.build.json --readme ../../DOC_README.md --hideGenerator --name 'melonJS' --navigation.includeCategories true --categorizeByGroup false",
"doc": "tsx scripts/check-doc-readme.ts && typedoc src/index.ts --tsconfig tsconfig.build.json --readme ../../DOC_README.md --hideGenerator --name 'melonJS' --navigation.includeCategories true --categorizeByGroup false && tsx scripts/generate-llms-txt.ts",
"doc:watch": "typedoc src/index.ts --tsconfig tsconfig.build.json --readme ../../DOC_README.md --hideGenerator --name 'melonJS' --navigation.includeCategories true --categorizeByGroup false --watch --skipErrorChecking --preserveWatchOutput --logLevel Error",
"serve": "serve docs",
"prepublishOnly": "pnpm dist:publish",
Expand Down
Loading
Loading