Phaser AE

Reveal puzzles

Free packv3.0.0-32DGrid

The hidden-mine deduction puzzle: a field of covered cells, numbers that count the mines around them, and a flood when an empty cell opens. The first click is always safe, and the hint never guesses.

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

Released October 14, 2026 · updated October 19, 2026

Reveal puzzles: 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

reveal

function reveal(): Pack<{ reveal: RevealApi }>

The reveal pack. Pure logic, so it needs no backend and runs headless.

Helpers

createMinefield

function createMinefield(cfg: MinefieldConfig): Minefield

Creates a Minesweeper board from the config.

Classes

Minefield

class Minefield

A Minesweeper board with hidden state. Create one with createMinefield().

  • readonly cols: number — The number of columns on the board.
  • readonly rows: number — The number of rows on the board.
  • readonly mines: number — The number of mines on the board.
  • state: 'playing' | 'won' | 'lost' — The game state. 'playing' until a win or a loss.
  • constructor(cfg: MinefieldConfig)
  • cell(x: number, y: number): CellView — The player-visible view of a cell.
  • get minesLeft(): number — Mines minus flags placed (may go negative).
  • reveal(x: number, y: number): RevealResult — Reveal a cell. First reveal places mines (excluding the safe zone).
  • flag(x: number, y: number): void — Flag → question → hidden cycle. Flags block reveal.
  • chord(x: number, y: number): RevealResult — Chord: on a revealed number whose adjacent flags equal it, reveal the rest. A wrong flag here detonates.
  • hint(): { safe: XY[]; mines: XY[] } — The covered cells the open numbers prove safe, and those they prove are mines, as { safe, mines }, in board order; both empty before the first reveal. Every cell not yet revealed is covered, flagged and question-marked ones too: a flag is the player's guess, so the hint ignores it and proves from the numbers alone, and a flag the numbers prove wrong comes back in safe. Two rules, applied until neither proves more: a number whose proved mines equal it has its other covered neighbours safe; a number whose proved mines and unproved covered neighbours together equal it has those all mines.
  • step(): boolean — Apply one hint() pass: flag every proved mine and open every proved-safe cell, leaving the player's flags and question marks as they are (a mark blocks a reveal, as it blocks a click). Before the first reveal it opens the centre cell. Returns false when it could not act or the game is over.
  • debugGrid(): string — Returns the board as text: '.' hidden, 'F' flag, '*' mine, or the number. For tests.

Types

CellState

type CellState = 'hidden' | 'flagged' | 'question' | 'revealed'

The player-visible state of one cell.

CellView

interface CellView

What the player can see of one cell. Returned by cell().

  • state: CellState — The player-visible state of the cell.
  • number: number — Adjacent mine count (0–8). Meaningful once revealed.
  • mine?: boolean — True only after game end (loss reveals all).

MinefieldConfig

interface MinefieldConfig

Configuration for createMinefield().

  • cols: number — The number of columns on the board.
  • rows: number — The number of rows on the board.
  • mines: number — The number of mines. Must be less than cols × rows.
  • seed?: number — The seed for mine placement. The same seed gives the same board. Default 1.
  • firstClickSafe?: 'cell' | 'area' — cell = first click is never a mine; area = its 3×3 is mine-free (modern default).

RevealApi

type RevealApi = typeof kit

game.reveal — every function and type this pack carries, as one namespace.

RevealResult

interface RevealResult

A distance-ordered flood: waves[0]! is the clicked cell, waves[n]! are cells n steps away — the presenter animates them as an expanding ripple.

  • waves: { cells: { at: XY; number: number }[] }[] — The revealed cells, grouped by distance from the click.
  • detonated: XY | null — The mine cell the click set off, or null.
  • state: 'playing' | 'won' | 'lost' — The game state after the move.
  • reveal?: { mines: XY[]; wrongFlags: XY[] } — All mines + wrong flags, populated on loss for the reveal-everything render.

XY

interface XY

A grid cell position. x is the column and y is the row, from the top left.

  • x: number — The column, from the left.
  • y: number — The row, from the top.