Repository navigation
A* pathfinding plugin, modernized from melonjs-astar #1720
Description
Summary
melonJS used to have an A* pathfinding plugin, melonjs/plugins/pathfinding/melonjs-astar, last updated in 2013. The algorithm itself is solid and small (A* over a grid, binary heap open list, Manhattan / chessboard heuristics, optional diagonal moves), but the plugin targets the 0.9.x API and does not run on melonJS 20.
This issue proposes taking it as the base, modernizing it, and shipping it as an official plugin in this monorepo: packages/pathfinding-plugin, published as @melonjs/pathfinding-plugin, alongside debug-plugin and spine-plugin.
Why it no longer works
- uses
me.plugin.Base.extend,me.game.collisionMap,me.Rectandme.event.subscribe(me.event.LEVEL_LOADED), none of which exist in that form any more - builds its grid from a dedicated collision tile layer; collision in current melonJS comes from shapes in Tiled object layers and from physics bodies
- installed as a global script (
me.astar), not an ES module
Port
- TypeScript ES module, registered through the current
pluginAPI - keep the A* core and binary heap, with the original credits and MIT license (Sean Muron; javascript-astar by Brian Grinstead; binary heap by Marijn Haverbeke)
- coordinates in world units in and out, with tile coordinates available too
- returns plain points (or
Vector2d), not internal grid nodes
Grid sources
- from the level's collision shapes (Tiled object layers / static bodies), rasterized to the map's tile grid on load
- from any tile layer, where a non-empty tile, or a tile property, means blocked
- from a callback
isWalkable(x, y)/getCost(x, y)for custom grids - rebuilt automatically on level load, and
refresh()/setWalkable(x, y, bool)when the map changes at runtime (doors, destructible walls)
Features from the original TODO list, and other missing ones
- per-tile cost (mud, water, roads)
- path smoothing: drop intermediate points when there is a clear straight line, so units don't zigzag tile to tile
- diagonal moves without cutting corners past walls
- optional dynamic blockers: given objects mark their cells as blocked or costly
- a search limit (max nodes) so an unreachable target can't stall a frame; return the closest reachable point instead
- isometric and hexagonal maps, or at least a clear note that only orthogonal is supported at first
Debug
- overlay through
@melonjs/debug-plugin: blocked cells, cost, the last path and visited nodes
Pathfinding example
A new demo in the examples site, packages/examples/src/examples/pathfinding/, registered in the demo list in packages/examples/src/main.tsx (label "Pathfinding", path pathfinding, sourceDir: "pathfinding"):
- a small Tiled map with walls and a couple of slow-terrain areas (cost)
- a few units that chase the pointer, or a player-controlled target, re-planning as it moves
- click to toggle a wall at runtime, showing the grid refresh
- toggles for diagonal moves and path smoothing, with the path drawn so the difference is visible
- the debug overlay available through the debug panel
- works with the built-in physics adapter; short note on Matter / Planck if anything differs
Done when
- the plugin is published as its own package, with README, CHANGELOG and tests (core search, grid building from shapes, smoothing, runtime updates)
- the Pathfinding example is in the demo list
- a skill documents it (
melonjs-pluginsor a new pathfinding section), with a symptom table entry for "path goes through walls" and "no path found" - the old repository's README points to the new package
Activity