Phaser AE

Hangman letter guessing

Pro packv3.0.0-0WordNew

The letter-guessing game everyone knows, as rules you can drop into any game: a hidden word or phrase, a letter at a time, and a life lost for every miss. You draw the gallows; the pack keeps everything else straight.

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

Released October 21, 2026

Hangman letter guessing: 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

hangman

function hangman(): Pack<{ hangman: HangmanApi }>

The hangman pack: letter-guessing rules over the english-words lists. Pure logic, so it runs headless.

Helpers

createHangman

function createHangman(options: HangmanOptions): Hangman

Start a game. Throws a RangeError for options out of range: a seed that is not an unsigned 32-bit integer, a lives count that is not a whole number of 1 or more (or Infinity), a negative or fractional penalty or hint cost, a set answer with no letters, or a word source with nothing between min and max letters.

hangmanCandidates

function hangmanCandidates(pool: Iterable<string>, pattern: ReadonlyArray<string | null>, misses: Iterable<string> = [], opts: { hits?: Iterable<string>; hidden?: Iterable<string>; exclude?: Iterable<string> } = {}): string[]

The answers in pool still possible for pattern, in pool order, once each. pattern has one entry a character: a letter that shows, null for a hidden letter, or a character that is not a letter (a space), which must match. A candidate holds no letter of misses anywhere, shows the right letter at every shown place, and at a hidden place holds none of hits (letters guessed and in the answer: they would show), none of misses and none of hidden (letters that cannot hide, such as given vowels). hits defaults to every letter the pattern shows; exclude leaves out answers already guessed whole. Entries are compared in lower case with accents taken off.

Types

Hangman

interface Hangman

A game of hangman. Make one with createHangman.

  • observation(): HangmanView — The game as it stands.
  • check(move: HangmanMove): { readonly ok: true } | Refusal — Would move be accepted now? { ok: true }, or the refusal with a reason a player could be shown. Changes nothing.
  • letter(letter: string): { readonly ok: true; readonly result: HangmanResult } | Refusal — Guess a letter.
  • word(word: string): { readonly ok: true; readonly result: HangmanResult } | Refusal — Guess the whole answer; spaces and punctuation do not matter.
  • hint(): { readonly ok: true; readonly result: HangmanResult } | Refusal — Show one hidden letter, for hintCost lives: the one that uncovers the most positions (alphabetical on a tie).
  • undo(): boolean — Take back the last move. False when there is none.
  • candidates(): string[] — Every answer in the word source still possible: the same shape, agreeing with every letter shown and missed.
  • suggest(): string | null — The best next letter: the one most of candidates() hold in a hidden place (alphabetical on a tie); null when over.
  • autoStep(): { readonly ok: true; readonly result: HangmanResult } | Refusal — Play the advice: the whole answer when one candidate is left (and whole guesses are on), else suggest()'s letter.
  • answer(): string — The answer, for a game's own reveal or a test.
  • snapshot(): HistorySave<HangmanMove> — The game as a save: the seed and the moves. Restore it into a game made with the same options.
  • restore(save: HistorySave<HangmanMove> | string): void — Replace this game with a save. Throws, changing nothing, when the save does not replay under these options.

HangmanApi

type HangmanApi = typeof rules

game.hangman: every function and type this pack carries, as one namespace.

HangmanMove

type HangmanMove = | { readonly kind: 'letter'; readonly letter: string } | { readonly kind: 'word'; readonly word: string } | { readonly kind: 'hint' }

A move: a letter, a whole answer, or a hint.

HangmanOptions

interface HangmanOptions

How a game is set up. Only seed is required; the defaults are a 5 to 9 letter English word and six lives.

  • seed: number — Picks the answer when answer does not give it, as an unsigned 32-bit integer.
  • words?: WordList | ReadonlyArray<string> — Where answers come from: a word list, or an array whose entries may be phrases ("polar bear", "jack-in-the-box"): spaces, hyphens and other characters that are not letters are shown from the start and never guessed. Accents are taken off. Default the English lexicon.
  • min?: number — Fewest letters in a picked answer. Default 5 for a word list, 1 for an array.
  • max?: number — Most letters in a picked answer. Default 9 for a word list, no limit for an array.
  • answer?: string — The answer, a word or phrase, instead of a seeded pick.
  • lives?: number — Lives before the game is lost: a whole number of 1 or more, or Infinity. Default 6.
  • reveal?: HangmanReveal — Letters shown from the start. Default 'none'.
  • wordGuess?: boolean — May the player guess the whole answer? Default true.
  • wordPenalty?: number — Lives a wrong whole-answer guess costs, a whole number. Default 1.
  • hintCost?: number — Lives a hint costs, a whole number; 0 for free hints. Default 1.

HangmanResult

interface HangmanResult

What a move did.

  • readonly kind: 'hit' | 'miss' | 'solved' | 'wrong' | 'hint' — 'hit', 'miss', 'solved' (a right whole answer), 'wrong' (a wrong one) or 'hint'.
  • readonly guess: string — The letter guessed or hinted, or the whole answer guessed.
  • readonly uncovered: ReadonlyArray<number> — The positions in slots it uncovered, in order.
  • readonly cost: number — Lives it cost.
  • readonly phase: HangmanView['phase'] — The phase after it.

HangmanReveal

type HangmanReveal = 'none' | 'first' | 'first-last' | 'vowels'

Which letters show from the start: none, the first, the first and last, or every vowel.

HangmanSlot

interface HangmanSlot

One character of the answer as a player sees it.

  • readonly char: string | null — The character: a revealed letter (lower case), a character that is not a letter (shown from the start), or null for a hidden letter.
  • readonly letter: boolean — Is it a letter, to be guessed? A space or a hyphen is not.
  • readonly revealed: boolean — Showing? Always true for a character that is not a letter.

HangmanView

interface HangmanView

Everything a game draws, at one moment. Never holds the answer before the game is over.

  • readonly phase: 'playing' | 'won' | 'lost' — 'playing', 'won' or 'lost'.
  • readonly slots: ReadonlyArray<HangmanSlot> — Every character of the answer, in order.
  • readonly letters: number — How many of the slots are letters.
  • readonly hits: ReadonlyArray<string> — Letters guessed that are in the answer, in the order guessed.
  • readonly misses: ReadonlyArray<string> — Letters guessed that are not, in the order guessed.
  • readonly wrongWords: ReadonlyArray<string> — Whole-answer guesses that were wrong, in order.
  • readonly hinted: ReadonlyArray<string> — Letters shown by hints, in order.
  • readonly lives: number — Lives at the start; Infinity for no limit.
  • readonly lost: number — Lives lost so far: one a miss, wordPenalty a wrong whole-answer guess, hintCost a hint.
  • readonly livesLeft: number — Lives left; Infinity for no limit.
  • readonly answer: string | null — The answer, once the game is over; null before.
  • readonly keyboard: Readonly<Record<string, 'hit' | 'miss' | 'unused'>> — Each letter a to z: 'hit' (in the answer, guessed or hinted), 'miss', or 'unused'.
  • readonly wordGuess: boolean — May the whole answer be guessed?
  • readonly hintCost: number — Lives a hint costs.
  • readonly given: ReadonlyArray<string> — Letters the reveal shows and that cannot be guessed: the vowels with reveal: 'vowels', else none.