Phaser AE

Falling-boulder caves

Pro packv3.0.0-12DArcade

The rules of the falling-rock cave game: dig through dirt, collect enough diamonds to open the exit, and keep out from under the boulders. The cave simulates itself a cell at a time round the player, and caves are data you can write or generate.

This is a Pro pack. Upgrade to Phaser Pro to use it in your games.See Phaser Pro →

Released October 19, 2026

Falling-boulder caves: 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

boulderDash

function boulderDash(): Pack<{ boulderDash: BoulderDashApi }>

The boulder-dash pack: game.boulderDash, Boulder Dash's rules. No options.

Helpers

caves

const caves: CaveDef[]

The built-in caves.

checkBoulderDashSave

function checkBoulderDashSave(save: unknown, caves: readonly CaveDef[] = builtIn): string | null

Why a save cannot be restored into a game of these caves, or null when it can: the cave must be one of them, every per-cell list must be that cave's size and hold cells, directions and burn counts, the timers must be finite numbers, and the random stream a real one. restore throws with this reason.

createBoulderAutopilot

function createBoulderAutopilot(game: BoulderDashGame): BoulderAutopilot

The game's autopilot. It only reads game.

createBoulderDash

function createBoulderDash(options: BoulderDashOptions = {}): BoulderDashGame

Start a game. Throws, with every fault, on options validateBoulderDash refuses.

layCave

function layCave(cave: CaveDef): CaveLayout | string

Lay a cave out: its map, or its fill and drawing.

validateBoulderDash

function validateBoulderDash(options: BoulderDashOptions = {}): string[]

Check a game's options. Empty when it can be played.

Types

BoulderAutopilot

interface BoulderAutopilot

A player that picks the way to go.

  • next(): Dir | null — The way to go now, or null to wait.

BoulderDashApi

interface BoulderDashApi

What the boulder-dash pack adds to a game: game.boulderDash.

  • create: typeof createBoulderDash — Start a game.
  • validate: typeof validateBoulderDash — Check a game's options.
  • checkSave: typeof checkBoulderDashSave — Why a save does not fit a game of these caves, or null.
  • caves: typeof caves — The built-in caves.
  • lay: typeof layCave — Lay a cave out.
  • autopilot: typeof createBoulderAutopilot — A player for an attract mode or a test.

BoulderDashEvent

type BoulderDashEvent = | { kind: 'cave'; cave: number; name: string } | { kind: 'born' } | { kind: 'dig' } | { kind: 'collect'; diamonds: number } | { kind: 'push' } | { kind: 'thud'; tile: 'boulder' | 'diamond' } | { kind: 'explode'; cell: number; diamonds: boolean } | { kind: 'open' } | { kind: 'exit'; bonus: number } | { kind: 'die'; cause: 'crushed' | 'creature' | 'explosion' | 'time' } | { kind: 'magic' } | { kind: 'amoeba'; into: 'diamond' | 'boulder' } | { kind: 'over' } | { kind: 'won' }

Something that happened.

BoulderDashGame

interface BoulderDashGame

A game.

  • readonly state: BoulderDashState — The live state; read it, do not change it.
  • readonly width: number — Cells across the current cave, the steel border included.
  • readonly height: number — Cells down the current cave, the steel border included.
  • readonly caves: readonly CaveDef[] — The caves in play, in order.
  • move(dir: Dir | null): void — Hold a way to go, or null to stand.
  • snap(on: boolean): void — Hold snap: dig or collect beside him without moving.
  • at(x: number, y: number): Cell — The cell at a column and row.
  • step(dt: number): void — Advances the game by dt seconds, running one cave frame for every frame seconds; a dt over 0.25 counts as 0.25. Throws if dt is negative or not a number.
  • view(): BoulderDashView — Every cell and a copy of the state, for drawing.
  • drain(): BoulderDashEvent[] — Takes the events since the last call, oldest first, and clears them. Only the latest 512 are kept.
  • snapshot(): BoulderDashSave — The whole game as plain JSON, to save.
  • restore(save: BoulderDashSave): void — Replaces the game with a saved one from snapshot() and discards pending events. Throws boulder-dash.restore: …, changing nothing, on a save that does not fit this game's caves (checkBoulderDashSave).

BoulderDashOptions

interface BoulderDashOptions

A game's options.

  • seed?: number — Default 1.
  • caves?: CaveDef[] — The caves, in order. Default caves.
  • cave?: number — The cave to start in, from 0. Default 0.
  • lives?: number — Lives. Default 3.
  • frame?: number — Seconds a cave frame takes: the game's speed. Default 0.125.
  • push?: number — The chance a push moves a boulder, each frame. Default 0.25.
  • growth?: [number, number] — An amoeba cell's chance to grow each frame, slow and then fast. Default 0.03 and 0.25.

BoulderDashSave

interface BoulderDashSave

A game saved as plain JSON.

  • state: BoulderDashState — The game's state.
  • cells: Cell[] — Every cell of the cave, row by row.
  • falling: number[] — Indices into cells of the boulders and diamonds that are falling.
  • dirs: number[] — Per cell, the way a creature there is heading: 0 up, 1 right, 2 down, 3 left.
  • burn: number[] — Per cell, the cave frames an explosion there has left to burn.
  • product: Cell[] — Per cell, what an explosion there leaves behind: a diamond or space.
  • wait: number — Seconds left of the pause at a cave's start, a death or an exit.
  • carry: number — Seconds of unspent time towards the next cave frame.
  • magicTime: number — Seconds the magic wall stays active, once woken.
  • amoebaTime: number — Seconds since the cave began; the amoeba grows fast once this passes its slow period.
  • rng: RngState — The random stream's state.

BoulderDashState

interface BoulderDashState

Where the game stands.

  • phase: 'start' | 'play' | 'dead' | 'exit' | 'over' | 'won' — start while Rockford arrives, play, dead after a death, exit after leaving a cave, over with no lives left, won after the last cave.
  • cave: number — Index of the current cave in the game's caves, from 0.
  • lives: number — Lives left, including the one in play.
  • score: number — Points scored so far.
  • diamonds: number — Diamonds collected in this cave.
  • needed: number — Diamonds this cave requires before its exit opens.
  • time: number — Seconds left in the cave.
  • open: boolean — The exit is open.
  • rockford: number — Rockford's cell (row * width + column), the way he faces, and whether he lives.
  • facing: Dir — The way Rockford last moved or faced.
  • alive: boolean — Whether Rockford is alive.
  • magic: 'dormant' | 'active' | 'expired' — The magic wall: dormant until a boulder or diamond wakes it, active for the cave's magic seconds, then expired.
  • frame: number — Cave frames run since the game began, one per frame seconds of play.

BoulderDashView

interface BoulderDashView

What is where.

  • state: BoulderDashState — The game's state when the view was taken; a copy.
  • width: number — Cells across the cave, the steel border included.
  • height: number — Cells down the cave, the steel border included.
  • cells: Cell[] — The cell at each position, row by row: width * height long. Rockford's cell reads rockford while he is in play.
  • falling: number[] — Cells whose boulder or diamond is falling.

CaveDef

interface CaveDef

A cave.

  • name: string — The cave's name, shown by the game and used in error messages.
  • diamonds: number — Diamonds to collect before the exit opens; points for each, and for each after that.
  • value: number — Points for each of the first diamonds diamonds collected.
  • extra: number — Points for each diamond collected after the first diamonds.
  • time: number — Seconds to finish it in.
  • map?: string[] — A map in text (rows of the same length): W steel, w brick, . dirt, space, r boulder, d diamond, q firefly, B butterfly, a amoeba, M magic wall, X the exit, P Rockford. Or the fill and drawing below.
  • size?: [number, number] — Width and height, the steel border included. Default 40 by 22.
  • seed?: number — The fill's seed and its chances of each tile (the rest is dirt).
  • fill?: Partial<Record<'boulder' | 'diamond' | 'space' | 'firefly' | 'butterfly', number>> — Chance, 0 to 1, that each cell of the fill is a boulder, diamond, space, firefly or butterfly; the rest is dirt. The chances should total no more than 1.
  • draw?: CaveDraw[] — Lines, boxes and single tiles drawn over the fill, in order. They stay inside the steel border.
  • start?: [number, number] — Column and row of the cell Rockford starts in, counted from the top left. Default [3, 2]. Loose objects in the cells around it are turned to dirt.
  • exit?: [number, number] — Column and row of the exit's cell. Default [width - 3, height - 2]. Loose objects in the cells around it are turned to dirt.
  • amoeba?: { slow?: number; max?: number } — Seconds the amoeba grows slowly before it grows fast; cells at which it turns to boulders. Default 20 and 200.
  • magic?: number — Seconds a magic wall stays active once a boulder wakes it. Default 15.

CaveDraw

type CaveDraw = | { kind: 'line'; tile: Tile; from: [number, number]; to: [number, number] } | { kind: 'box'; tile: Tile; from: [number, number]; to: [number, number]; fill?: boolean } | { kind: 'point'; tile: Tile; at: [number, number] }

Something drawn over the fill: a line or box of a tile, or one tile at a cell.

CaveLayout

interface CaveLayout

A cave laid out: width, height and the tiles, row by row; where Rockford starts and where the exit is.

  • width: number — Cells across, the steel border included.
  • height: number — Cells down, the steel border included.
  • tiles: Tile[] — The tile in each cell, row by row: width * height long. Rockford's cell is space.
  • start: number — Index into tiles of the cell Rockford starts in.
  • exit: number — Index into tiles of the exit's cell.

Cell

type Cell = Tile | 'explosion'

A cell: a tile, or an explosion burning out.

Dir

type Dir = 'up' | 'right' | 'down' | 'left'

A way to go.

Tile

type Tile = 'space' | 'dirt' | 'brick' | 'steel' | 'boulder' | 'diamond' | 'firefly' | 'butterfly' | 'amoeba' | 'magic' | 'exit' | 'rockford'

What can be in a cell.