Phaser AE

Terrain Rider

Free packv3.0.0-33DLogic

Something that sits on the ground and moves over it, ridden smoothly: a snowboard, a kart, a rolling ball, a walking character or a hovering drone. Give it a height function and it hands back ride height, pitch, roll and whether it is in the air, without the jitter a single height sample gives.

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

Released October 14, 2026 · updated October 20, 2026

Terrain Rider: 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

Each frame your game moves the rider in x and z its own way, then calls step(dt, x, z, yaw) and reads back y, pitch, roll, grounded, landed and airTime to put on the mesh. The split is deliberate. Horizontal motion genuinely differs between a board that carves, a ball that rolls and a kart that grips, but sitting on the ground smoothly is the same fiddly problem for all of them, so the rider owns only the vertical.

The idea that removes the jitter is that contact is a shape, not a point. A point sample drops into every notch in the terrain. A plank samples a footprint along its length, and across its width if you give one, rests on its highest contact and tilts to the fitted slope, so a board bridges dips and pivots over crests. A sphere averages the ground over its contact disc and sits its radius above it, which smooths away the slope kinks between terrain quads, so a ball rolls across an incline without trembling and bridges notches narrower than its radius. The shape is picked from what you give: a radius makes a sphere, a length a plank, neither a point.

The rest of the feel is in the details. Suspension stiffens with speed so a fast descent does not float, but it is capped, because an almost rigid follow passes every change of support straight through. Orientation is smoothed twice, the slope first and then pitch and roll towards it, so it neither snaps nor lags. Off a lip the rider leaves carrying the descent speed it already had, so it arcs rather than dropping like a stone, and landed is true on exactly one frame with airTime frozen at the flight's length, ready to scale an impact.

Features

  • Three contact shapes — point, plank and sphere, picked from radius and length or set with contact.
  • Slope-following orientation — pitch and roll to the fitted slope and cross-slope, scaled by pitchGain and rollGain, with tilt: false for a box that stays level on its highest corner.
  • Speed-scaled, capped suspension — followK, followKGain and followKMax, 25, 0.5 and 55 by default.
  • An airborne state machine — detaching off a lip deeper than detach, gravity in the air, a one-frame landed and the flight's airTime.
  • Jumps — launch(vy) pops the rider into the air.
  • Glued riders — detach: Infinity never leaves the surface, for a ball held to a seabed.
  • Settling in — settle sinks the contact into the surface, as a board compacts the snow it rides.
  • Inputs for an energy model — groundY, lastGroundY and the smoothed slope, for trading height for speed.
  • Pure and headless — no objects, no clock and no drawing, so it runs in a test or a worker exactly as in a frame.

Good for

  • Snowboarding and skiing games, where a board carves down a slope and catches air off lips.
  • Kart and off-road games over rolling 3D terrain, with the kart banking to the cross-slope.
  • Rolling-ball games across inclines and bumpy ground, where a point sample would make the ball tremble.
  • Boats riding a swell, fed the water's height instead of the land's.
  • Characters and creatures walking over terrain, with a point or a short plank for feet.
  • Hovering drones holding a clearance above the ground.

Make it yours

groundAt is the one required input; everything else has a default. The contact is shaped by contact, radius, ringTaps, length, width and tilt; the ride by settle, gravity (30), detach (0.9) and maxFall (200); the suspension by followK, followKGain and followKMax; and the orientation by slopeK, orientK, pitchGain and rollGain.

Two different uses: a snowboard as a plank with a length and a width, banking to the cross-slope, settling into the snow, popping an ollie with launch and scoring the trick from airTime on the landing frame; and a ball as a sphere with a radius, glued to a seabed with detach: Infinity, its pitch and roll left to the game, which spins it as it rolls.

A quick look

A board over a terrain, stepped after the game has moved it:

const board = game.rider.add({ groundAt: (x, z) => terrain.heightAt(x, z), length: 1.6, width: 0.5 });
board.reset(start.x, start.z, yaw);                  // on the ground, at rest
// each frame, after the game has moved x and z its own way:
board.step(dt, x, z, yaw, speed);
mesh.y = board.y; mesh.pitch = board.pitch; mesh.roll = board.roll;
if (board.landed) scoreJump(board.airTime);

Works with

  • terrain-3d — pass its height query as the ground.
  • water-3d — ride a swell through the water's height query.
  • physics-3d — for walls, overhangs and sideways collisions, which the rider does not know about.

Good to know

  • It rides a height function, so it knows nothing of walls, overhangs or anything it should hit sideways; that is your game's job or a physics pack's.
  • There is no wheel model, friction or traction: the slope and the change in ground height are given to you to build an energy model on.
  • Keep groundAt smooth. A rider that carves the surface it rides should be fed the fresh field, or it rides its own trench.
  • Smooth riding also needs frame order: move the camera after the rider, or every acceleration reads as judder.

More Logic packs

Show all →