Phaser 3 Arcade Physics: sprite following a precomputed waypoint path stalls / doesn't move correctly
11:39 23 Aug 2026

I'm building an automated "level solver" for a top-down Phaser 3 game: a bot walks a precomputed path (array of {x, y} pixel waypoints) to test whether a level is completable with the game's actual physics/speed/hitbox parameters, before a human player tries it.

The path itself is verified correct (I draw it with Graphics and it matches the maze exactly, avoiding walls and enemy patrol zones). The problem is purely getting the sprite to actually follow it during gameplay — it stalls / jitters in place instead of moving smoothly along the waypoints.

What I've tried

1. Digital controls (left/right/up/down booleans), translated elsewhere into setVelocityX/setVelocityY:

typescript

const dx = target.x - state.player.x;
const dy = target.y - state.player.y;
const dist = Math.hypot(dx, dy);

if (dist < ARRIVE_THRESHOLD) {
  pathIndex++;
  return stop();
}

return {
  left: dx < 0,
  right: dx > 0,
  up: dy < 0,
  down: dy > 0,
};

Result: sprite oscillates near a waypoint instead of settling (flips left/right every frame) — presumably overshooting ARRIVE_THRESHOLD each frame.

2. Direct velocity vector (body.setVelocity(vx, vy)), normalized direction * known speed:

typescript

const vx = (dx / dist) * SPEED;
const vy = (dy / dist) * SPEED;
return { vx, vy };

Also didn't behave as expected — not obviously better, and I couldn't isolate whether the problem was in this code or in how something else in the scene also touches the body's velocity in the same frame.

3. Directly setting position (setPosition(x, y)), computed from delta time and known speed, bypassing physics velocity entirely:

typescript

const maxStep = SPEED * (deltaMs / 1000);
if (maxStep >= dist) return { x: target.x, y: target.y };
return {
  x: state.player.x + (dx / dist) * maxStep,
  y: state.player.y + (dy / dist) * maxStep,
};

This one passes in an isolated Node.js simulation of the frame loop (no Phaser, just plugging numbers through the same math) — the position converges correctly to the final waypoint. I haven't yet tested this specific version inside the actual Phaser scene.

Setup

  • Phaser 3, Arcade Physics

  • Player: Phaser.Physics.Arcade.Sprite, circular body via body.setCircle(6, offsetX, offsetY)

  • Movement is normally driven by keyboard input for a human player; for the bot, I want to drive the same sprite from a precomputed path instead, one waypoint at a time

  • Fixed known "logical" speed: 200 px/s

  • path is a flat array like:

json

  [
    { "x": 112, "y": 240 },
    { "x": 132, "y": 240 },
    { "x": 132, "y": 230 },
    { "x": 146.14, "y": 244.14 }
  ]

Question

What's the correct/idiomatic way in Phaser 3 Arcade Physics to move a sprite precisely along a list of predetermined waypoints (not just "toward a target forever", but actually arriving at and advancing through each point in order), in a way that:

  1. Doesn't fight with Arcade Physics' own velocity/position integration

  2. Doesn't overshoot/oscillate near each waypoint

  3. Works predictably regardless of frame rate (variable delta)

Should I be using setPosition (and if so, do I need body.reset(x, y) instead, to avoid the physics engine "pulling it back"?), setVelocity with a specific approach to avoid overshoot, or something else entirely (e.g. Phaser.Curves.Path

  • follow, or tweens)? Is there a standard pattern for this kind of "replay a recorded path exactly" bot in Arcade Physics that I'm missing?

javascript phaser