Phaser AE

3D paths

Free packv3.0.0-03DLogic

Smooth curves through points in 3D, for rides, rails and cameras. A rider moves at an even speed, and a frame at every point keeps a coaster car upright through a loop without rolling over at the top.

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

Released October 19, 2026

3D paths: 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.

The pack

path3d

function path3d(): Pack<{ path3d: Path3dApi }>

The path-3d pack: rides, rails and camera paths through 3D points, at even speed and without twisting.

Classes

DynamicPath3d

class DynamicPath3d

A path as a rolling window: add waypoints ahead, trim behind, and ride by absolute distance forever.

  • constructor(opts: { samplesPerSegment?: number } = {})
  • get start(): number — Distance at the START of the ridable window (advances with trim()).
  • get head(): number — Distance at the END of the ridable window (grows with add()). Keep adding while head - riderDist shrinks — the rider must never catch the head. 0 until three waypoints exist.
  • get ready(): boolean — Ridable yet? (needs 3 waypoints for the first baked segment).
  • add(x: number | { x: number; y: number; z: number }, y = 0, z = 0): void — Append a waypoint AHEAD. Bakes every segment that just became stable and drops control points the baker no longer needs.
  • trim(d: number): void — Drop everything WHOLLY behind distance d (keeps the bracketing sample so frameAt(d) still interpolates). Distances stay absolute.
  • at(d: number): { x: number; y: number; z: number } — Position at ABSOLUTE distance d (clamped to [start, head]).
  • frameAt(d: number): PathFrame — Full frame at ABSOLUTE distance d — same contract as Path3d.frame.
  • pointsBetween(d0: number, d1: number, n: number): Array<[number, number, number]> — n points between two absolute distances — draw the plotted route.

Path3d

class Path3d

A baked Catmull-Rom curve through 3D points, sampled by arc-length fraction with a no-twist frame.

  • readonly length: number — Total arc length (world units).
  • readonly closed: boolean — True when the path joins the last point back to the first.
  • constructor(points: Array<[number, number, number]> | P3[], opts: Path3dOptions = {})
  • at(t: number): P3 — Position at arc-length fraction t (0..1; closed paths wrap).
  • atDist(d: number): P3 — Position at a distance in world units along the path.
  • frame(t: number): PathFrame — Full frame at t: position + tangent + parallel-transported normal + binormal (all unit) — orient a cart, bank a camera, place a rail tie.
  • points(count: number): Array<[number, number, number]> — n points evenly spaced by ARC LENGTH — feed world.tube({ path }) or a vector polyline directly. Closed paths omit the duplicate end point.

Types

Path3dApi

interface Path3dApi

game.path3d: 3D splines with frames.

  • Path3d: typeof Path3d — A baked Catmull-Rom curve through 3D points, by arc length, with a no-twist frame.
  • DynamicPath3d: typeof DynamicPath3d — A rolling 3D path: waypoints added ahead, trimmed behind, ridden by distance.

Path3dOptions

interface Path3dOptions

Options for the Path3d constructor.

  • closed?: boolean — Join the last point back to the first (loops: coasters, patrols).
  • samplesPerSegment?: number — Samples baked per segment (default 24; more = smoother frames).

PathFrame

interface PathFrame

One sampled point on a path: position plus a unit tangent/normal/binormal frame. Returned by Path3d.frame.

  • x: number — The position on the path, in world units.
  • y: number — The y position on the path, in world units.
  • z: number — The z position on the path, in world units.
  • tx: number — Unit tangent — the travel direction.
  • ty: number — The y part of the unit tangent.
  • tz: number — The z part of the unit tangent.
  • nx: number — Parallel-transported unit normal (no roll flips around loops).
  • ny: number — The y part of the unit normal.
  • nz: number — The z part of the unit normal.
  • bx: number — Binormal = tangent × normal.
  • by: number — The y part of the binormal.
  • bz: number — The z part of the binormal.