Phaser AE

Block-game first-person controls

Free packv3.0.0-43DRigs

The first-person controls for a block-building game: look, walk, sprint, jump, fly, break, place and pick from a hotbar, in the scheme players know from Minecraft. It turns keyboard, mouse or touch into intent, and you decide what that intent moves.

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

Released October 14, 2026 · updated October 20, 2026

Block-game first-person controls: 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

rigMinecraft

function rigMinecraft(opts: RigMinecraftOptions = {}): Pack<{ mc: RigMinecraftApi }>

The rig-minecraft pack: the block-game control scheme, as intent plus the two helpers that apply it.

Helpers

lookVector

function lookVector(yaw: number, pitch: number): { x: number; y: number; z: number }

The unit forward vector for a yaw and a pitch, in the engine's convention: forward.xz is (−sin yaw, cos yaw), and POSITIVE PITCH LOOKS DOWN. Pure, so the convention can be pinned by a test rather than by a screenshot.

moveVector

function moveVector(yaw: number, fwd: number, strafe: number, speed: number): { x: number; z: number }

The horizontal move for a forward/strafe intent at a yaw, normalised so a diagonal is not faster than a straight line — which it is if you simply add the two axes, and which players feel immediately.

Functions

coarsePointer

function coarsePointer(): boolean

Is this a touch-first device? A coarse pointer, or a touch API present at all.

It matters because the on-screen controls have to be there BEFORE the first touch: a player who cannot see a joystick has no reason to put a thumb down, and waiting for a touch to reveal the thing you touch is a chicken and egg the player loses.

touchLayout

function touchLayout(w: number, h: number, slots = 9): TouchLayout

The Bedrock layout, from a screen size. It is a pure function so a game can draw the controls without asking the rig anything, and so the zones can be tested without a screen.

Classes

DoubleTap

class DoubleTap

The double-tap detector, pure: feed it presses and it says when two landed inside the window.

  • constructor(private window = 0.28)
  • press(t: number): boolean — A press at time t seconds. Returns true when it completes a double tap.

Types

McWalkSpeeds

interface McWalkSpeeds

Walk speeds in blocks a second: sneaking, walking, sprinting.

  • sneak?: number — Sneak. Default 1.8.
  • walk?: number — Walk. Default 4.6.
  • sprint?: number — Sprint. Default 7.

RigMinecraftApi

interface RigMinecraftApi

game.mc.

  • sensitivity: number — Mouse sensitivity in radians per pixel. Live — it is a comfort setting, so it belongs in a menu.
  • yaw: number — Look angle about the vertical, radians. Live.
  • pitch: number — Look tilt, radians. Live.
  • readonly forwardAxis: number — Forward intent, −1..1, refreshed every frame.
  • readonly strafeAxis: number — Strafe intent, −1..1.
  • readonly upAxis: number — Vertical intent while flying, −1..1.
  • readonly jumpHeld: boolean — Jump held, while walking.
  • readonly sneak: boolean — Sneak held.
  • readonly sprint: boolean — Sprinting — Ctrl, or the double-tap-W latch.
  • readonly mining: boolean — Break button held.
  • readonly placing: boolean — Place button held.
  • fly: boolean — Flying rather than walking. Live.
  • slot: number — The selected hotbar slot, 0-based. Live.
  • readonly locked: boolean — Is the pointer locked?
  • forward(): { x: number; y: number; z: number } — The unit vector the player is looking along.
  • flyStep(eye: { x: number; y: number; z: number }, dt: number, speed?: number): void — Fly a free eye by the current intent.
  • walkStep(body: Steppable, dt: number, speeds?: McWalkSpeeds): void — Walk a body by the current intent, choosing the speed from sneak and sprint.
  • firstPerson(eye: { x: number; y: number; z: number }, eyeHeight?: number): void — Point the camera out of a body's eyes: eye is the body's feet (a VoxelBody's x, y, z), and the camera sits eyeHeight above it, default 1.62 blocks.
  • readonly touch: boolean — True once a finger has touched — the game draws the on-screen controls from then on. It starts true on a coarse-pointer device so the controls are there before the first touch rather than after it.
  • readonly layout: TouchLayout — Where the on-screen controls are, for drawing them.
  • readonly stick: { baseX: number; baseY: number; knobX: number; knobY: number; radius: number } | null — Where the joystick is being held, or null — its base, its knob and its reach.

RigMinecraftOptions

interface RigMinecraftOptions

Manifest options.

  • yaw?: number — Starting look angle about the vertical, radians. Default 0.
  • pitch?: number — Starting look tilt, radians. Default 0.1.
  • vertical?: 'jump' | 'fly' — What Space and Shift mean: jump is walking, fly is creative. Live, and double-tapping Space flips between them when canFly allows. Default fly.
  • canFly?: boolean — Let a double-tap of Space toggle flying. Default false.
  • canBreak?: boolean — Enable the break button. Default true.
  • canPlace?: boolean — Enable the place button. Default false.
  • slots?: number — How many hotbar slots the number keys and the wheel walk. Default 9.
  • sensitivity?: number — Mouse sensitivity, radians per pixel. Default 0.0025.

Steppable

interface Steppable

Anything the rig can walk — a voxel body satisfies it.

  • step(dt: number, wishX: number, wishZ: number, jump: boolean): void — Advance one tick with a wished horizontal velocity and a jump flag.
  • x: number — Footprint centre x, in blocks.
  • y: number — Feet y, in blocks.
  • z: number — Footprint centre z, in blocks.

TouchLayout

interface TouchLayout

Where the on-screen controls sit, in logical screen pixels. Pure, so a game can draw them however it likes.

  • joyRadius: number — The joystick's reach from wherever the thumb lands.
  • jump: { x: number; y: number; r: number } — The jump-or-rise button.
  • sneak: { x: number; y: number; r: number } — The sneak-or-sink button.
  • slots: Array<{ x: number; y: number; w: number; h: number }> — One hotbar slot's box, left to right.
  • joySplit: number — Everything left of this is the joystick half; right of it looks and acts.