Phaser AE

Destructible cover

Pro packv3.0.0-32DArcade

Cover that wears away the way arcade bunkers do: masks of square cells, each with its own material and health, that shots trace through and explosions chip away. Shapes, materials and blast patterns are all yours to author.

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

Released October 14, 2026 · updated October 20, 2026

Destructible cover: 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

destructibleCover

function destructibleCover(): Pack<{ destructibleCover: typeof rules; }>

Install the renderer-independent destructible cover API.

Helpers

bunkerPreset

function bunkerPreset( options: { count?: number; worldWidth?: number; /** Top edge of the bunkers. */ y?: number; cellSize?: number; hp?: number; mask?: readonly string[]; /** Left x of the first bunker and gap between bunker left edges; default spreads them evenly. */ left?: number; pitch?: number; } = {}, ): CoverDefinition[]

Evenly spaced bunkers of any authored mask (default: the Space Invaders shield at one unit per pixel).

createDestructibleCover

function createDestructibleCover(definitions: CoverDefinition[] = [])

Create independent damageable masks, or empty cover for a game without shields.

INVADERS_ALIEN_SPLAT

const INVADERS_ALIEN_SPLAT: readonly string[]

The alien-shot explosion stencil (ROM AShotExplo, $1CDC, upright): a ragged 6-wide, 8-tall splat.

INVADERS_PLAYER_SPLAT

const INVADERS_PLAYER_SPLAT: readonly string[]

The player-shot explosion stencil (ROM ShotExploding, $1C91, upright): a ragged 8 x 8 splat.

INVADERS_SHIELD_MASK

const INVADERS_SHIELD_MASK: readonly string[]

The Space Invaders shield, 22 x 16 pixels, upright (from the ROM's ShieldImage at $1D20, which is stored rotated): a flat top with chamfered corners and a notch cut into the base.

Classes

DestructibleCover

class DestructibleCover

Owns mask health and swept contacts through surviving cells; destroyed cells become transparent.

  • readonly definitions: CoverDefinition[] — The validated definitions (a private copy).
  • constructor(definitions: CoverDefinition[])
  • get revision() — Increments whenever any cell's health changes; renderers can redraw only when it moves.
  • cells(id?: string): CoverCell[] — Surviving cells of one definition or all of them.
  • runs(id?: string): CoverRun[] — Surviving cells merged into horizontal runs of equal material and health.
  • cellHealth(id: string, col: number, row: number) — Health of one cell (0 when destroyed, empty or outside the mask).
  • trace(from: Cell, to: Cell, radius = 0): CoverContact | null — Earliest swept contact for a point/circle approximated as a square of half-size radius.
  • traceBox( from: Cell, to: Cell, halfWidth: number, halfHeight: number, ): CoverContact | null — Earliest swept contact for an axis-aligned box of half extents halfWidth/halfHeight moving from from to to, through actual surviving cells only, so holes stay transparent. t is 0..1.
  • damage(contact: CoverContact, amount = 1, blastRadius = 0) — Damage the contacted cell by amount and every surviving neighbour whose centre is within blastRadius.
  • splat(at: Cell, splat: CoverSplat, amount = Infinity) — Stamp an explosion stencil at a world point on every cover it overlaps. A cover cell is damaged when its centre falls inside a set stencil cell. amount defaults to Infinity (erase), divided by each material's blastResistance; indestructible cells survive.
  • eraseRect( rect: { x: number; y: number; w: number; h: number }, amount = Infinity, ) — Damage every cell overlapping a world rectangle, e.g. an invader marching through a bunker.
  • drain() — Take damage events not returned yet.
  • snapshot() — Health of every cell.
  • restore(s: Record<string, number[]>) — Restore health from a snapshot of the same definitions.
  • reset() — Restore every cell to full health.

Types

CoverCell

interface CoverCell extends Cell

One surviving mask cell with its world position (top-left), authored material and current health.

  • id: string — Owning definition id.
  • col: number — Mask column.
  • row: number — Mask row.
  • size: number — Cell size.
  • material: string — Mask character.
  • hp: number — Remaining health.

CoverContact

interface CoverContact

The earliest swept hit, including mask indices and interpolated contact position.

  • cover: string — Definition id hit.
  • col: number — Mask column hit.
  • row: number — Mask row hit.
  • t: number — Fraction of the sweep at contact, 0..1.
  • at: Cell — Swept centre at contact.

CoverDamageEvent

interface CoverDamageEvent

One cell's health change.

  • cover: string — Definition id.
  • col: number — Mask column.
  • row: number — Mask row.
  • remaining: number — Health left.

CoverDefinition

interface CoverDefinition

An arbitrary rectangular material mask positioned in renderer-independent model units.

  • id: string — Unique id.
  • x: number — Left edge of mask column 0.
  • y: number — Top edge of mask row 0 (y grows downward).
  • cellSize: number — World size of one mask cell.
  • mask: string[] — Equal-width rows; . and space are empty, every other character names a material.
  • materials: Record<string, CoverMaterial> — Material per mask character.

CoverMaterial

interface CoverMaterial

Durability, blast resistance and optional permanent blocking for one mask character.

  • hp: number — Health of one cell of this material.
  • blastResistance?: number — Divides splash damage from blasts and splats (direct hits are undivided). Default 1.
  • indestructible?: boolean — Blocks traces but never loses health.

CoverRun

interface CoverRun extends Cell

A horizontal run of adjacent surviving cells with one material and one health value, for cheap drawing.

  • id: string — Owning definition id.
  • row: number — Mask row.
  • col: number — First mask column.
  • length: number — Cells in the run.
  • size: number — Cell size.
  • material: string — Mask character.
  • hp: number — Health shared by the run.

CoverSplat

interface CoverSplat

An explosion stencil. Every non-empty mask cell (any character except . and space) is a pixel of damage; the stencil is centred on the blast point unless anchor (in stencil cells) says otherwise. Space Invaders' shot explosions are splats like this: a ragged 8x8 or 6x8 pattern, not a circle and not a single cell.

  • mask: string[] — Stencil rows; any character but . and space damages.
  • cellSize?: number — World size of one stencil cell. Default: the damaged cover's own cellSize.
  • anchor?: Cell — Stencil cell placed on the blast point. Default: the stencil centre.