What it does
You create a walker with a start tile, a heading, a speed in tiles per second and a walls(x, y) test, and call
tick(dt) every frame. The walker moves along its lane and returns its new position in tiles; your game maps that to
the world however it likes. Positions have tile centres on whole numbers, and headings are the words 'up', 'left',
'down' and 'right'.
The player's input is buffered. want('up') holds the turn until the walker reaches a junction where up is open, so a
player can press early and never feel a missed corner, while a full reversal happens at once. Two turn windows,
turnBefore and turnAfter, let a turn be taken a little before or after a centre, sliding diagonally onto the new
lane, and arcadeAsymmetry swaps them when heading up or left, as the 1980 arcade maze chase's cornering does.
A tick is cut into pieces of at most 1/64 of a tile and stops exactly at tile centres, so a large frame never skips a junction. Callbacks fire as the walker reaches a centre (where an enemy chooses its next heading) and as it enters a new tile (where it can look ahead), and every piece of travel is reported with its timing so a collision sweep can follow it. Portals turn any tile into a tunnel, either jumping centre to centre or walking off one edge and back on at the other.
Features
- Buffered turns — a turn waits for an opening; a reversal is immediate.
- Arcade cornering — early and late turn windows up to just under half a tile, with the optional up-and-left asymmetry.
- Wrap portals — jump centre to centre, or slide off one edge and reappear at the matching edge with the remaining distance carried over.
- Decisions at centres —
onCentreasks for the next heading andonEnterreports each new tile, for enemy AI. - Travel pieces — every move and portal jump reported with its share of the tick, so collision never treats a teleport as travel.
- Variable speed — pass a different speed to any
tick, for tunnel slow-downs or frightened enemies. - Snapshots —
snapshotandrestorefor undo, rewinds and deterministic tests.
Good for
- Maze chases in the style of Pac-Man, with tunnels and forgiving corners.
- Bomb-laying grid games in the style of Bomberman, where actors walk the lanes between blocks.
- Block-pushing and digging games in the style of Pengo or Dig Dug.
- A new rules pack that keeps a whole game's state in tiles, with no renderer.
- Replays and tests, where movement must be exact and repeatable.
Make it yours
The board is any size and shape: walls and portal are the whole map, and walls is asked about tiles off the
board too, so the edges are yours to define. Speed, start tile and heading, both turn windows, the asymmetry and how
portals behave are all part of the config, and speed can change on every tick.
Two different uses: a maze chase with forgiving 0.4-tile corners, the asymmetry on and an edge-sliding tunnel on one row; and a strict grid game with both windows at 0, so actors turn only exactly on a centre, and no portals at all.
A quick look
A player walker with arcade corners, and an enemy that decides at each tile centre:
import { createGridWalker } from '@phaser-ae/grid-walker';
const pac = createGridWalker({
at: { x: 13.5, y: 23 }, direction: 'left', speed: 8, // 8 tiles/s
walls: (x, y) => MAZE[y]?.[x] === '#',
turnBefore: 0.4, turnAfter: 0.4, arcadeAsymmetry: true,
});
pac.want('up'); // buffered until the turn is open
const s = pac.tick(dt);
sprite.x = OX + s.x * TILE; sprite.y = OY + s.y * TILE; // tiles to world: the game's own mapping
ghost.tick(dt, ghostSpeed, (cell, heading) => brain.choose(cell, heading));
Works with
maze-chase,grid-bombs,grid-kickandexcavation— rules packs that move their actors with it.grid-move— the choice for a sprite steered by the keys in world pixels.controls-2d— for free movement rather than lanes.tween— for tile-to-tile hops with no motion between.
Good to know
- Four directions only: no diagonals and no speed ramps.
- It knows nothing of the world: your game maps tiles to world units itself.
tickrefuses a frame over 10 seconds, a speed over 10,000 tiles a second, or a tick needing more than a million pieces.






