Phaser AE

Chained path notation

Free packv3.0.0-02DLogic

A route authored as data: a start point and a chain of segments, each picking up where the last left off. Enemy attack runs, patrol routes and racing lines live in a level file or a wave table instead of in code, and move at an even speed once baked.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 19, 2026

Chained path notation: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

What it does

A path is written as { start, segments }. Each segment is one shape continuing from the current point: a line to a point, a quad or cubic bezier, an arc round a centre to an angle (going past 360 degrees keeps orbiting, and a second radius makes it an ellipse), a spiral whose radius glides to a new size over a number of turns, or a wave that rides a straight chord while swinging to either side as a sine or a zigzag. Each segment can carry its own ease, and the whole run can have one too, so an enemy can dawdle in and then whip round a loop.

new Path(data) bakes the route once into arc-length tables. After that, getPoint(t) gives the place a fraction of the way along by length and getAngle(t) the direction of travel, cheap enough for hundreds of followers to call every frame, and getPoint can reuse an object you pass so nothing is allocated. Path.fromJSON takes a JSON string or the data.

The bake can transform the authored coordinates. flipX mirrors every x about a vertical line, flipY every y about a horizontal one, and offset moves the whole route, so one attack run written for the left of the screen serves the right as well, and offset copies let a formation fly one route side by side.

Features

  • Six segment kinds — lines, quadratic and cubic beziers, elliptical arcs, spirals and sine or zigzag waves.
  • Chained — each segment starts where the last ended, so routes read like directions.
  • Eases per segment and per run — any named easing from the maths pack, or your own function.
  • Plain JSON — for level files, config tables and wave plans.
  • Mirror and move — flipX, flipY and offset, applied once at the bake.
  • Even speed — arc-length tables, with the sample count per segment yours to raise.
  • Fast queries — getPoint and getAngle for many followers every frame.

Good for

  • Shoot-'em-ups, with enemy attack runs that loop and swoop, in the style of 1942 or Gradius, mirrored for each side of the screen.
  • Wave tables and level files that need routes as data alongside spawn times and enemy types.
  • Patrol routes for guards and creatures, written once and reused.
  • Racing lines for computer opponents on a circuit.
  • Cut-scene moves where a character or camera follows a set route.

Make it yours

The route is the data, so changing a level means editing JSON. Each Path also takes flipX, flipY, offset and samplesPerSegment (48 by default; more for long or tight segments). Two different uses: a shooter whose wave table holds one attack run, baked twice, once as written and once with flipX at the centre of the screen, so enemies peel in from both sides; and a racing game whose computer cars follow a closed circuit of arcs and lines read from the track's level file.

A quick look

An attack run of a line, an eased arc and a wave, baked as written and mirrored:

import { Path } from '@phaser-ae/path-notation';
const run = { start: [-40, 80], segments: [
    { line: [200, 80] },
    { arc: { center: [200, 160], to: 450 }, ease: 'easeInOutSine' },
    { wave: { to: [520, 300], amplitude: 30, cycles: 3 } },
] };
const fromLeft = new Path(run), fromRight = new Path(run, { flipX: W / 2 });
const p = fromLeft.getPoint(t);

Works with

  • track — networks of routes with junctions, built from this notation.
  • scrolling-shooter — shooter rules whose enemy routes are written in it.
  • track-racer — racing rules whose circuits are built from it.
  • path — moves an object along a single geometry shape, without authoring a chain.
  • path-3d — for curves in 3D with frames.

Good to know

  • It is 2D only.
  • A segment is sampled into short straight pieces, so between samples a point lies on the chord; raise samplesPerSegment for long, tight curves.
  • Eases change where t lands, so an eased route is no longer even in speed.
  • It computes places and angles; moving objects along the route is your game's, or a pack built on it.

More Logic packs

Show all →