Skip to content

A* pathfinding plugin, modernized from melonjs-astar #1720

Open

Description

@obiot

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.Rect and me.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 plugin API
  • 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-plugins or 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions