Phaser AE

Screwed plates

Free packv3.0.0-12DPhysics

Plates screwed to a board in layers: the mechanic every screw puzzle shares. It answers what is covered, what is held, what swings and what falls, on real rigid-body physics, and leaves the rules of a particular game to the pack or game on top.

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

Released October 19, 2026

Screwed plates: 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

plateStack

function plateStack(): Pack<{ plateStack: PlateStackApi }>

The plate-stack pack: game.plateStack, plates and screws on a physics-2d world of their own.

Functions

createPlateStack

function createPlateStack(spec: PlateStackSpec): PlateStack

Make a stack. Throws, listing every problem, on a spec validatePlateStack refuses.

insidePolygon

function insidePolygon(x: number, y: number, points: ReadonlyArray<readonly [number, number]>): boolean

Whether a point is inside a polygon (even-odd).

validatePlateStack

function validatePlateStack(spec: PlateStackSpec): string[]

Check a stack and say what is wrong with it, as plain sentences; empty when it can be used.

Types

BoardHole

interface BoardHole

A hole in the board, where a screw can sit.

  • id: string — Its id.
  • x: number — Where it is, across.
  • y: number — Where it is, down.

PlateSpec

interface PlateSpec

A plate: a polygon on a layer, with holes screws can pass through. Coordinates are where it starts, y down.

  • id: string — Its id.
  • layer: number — Its layer: higher lies over lower. Plates on one layer should not overlap.
  • points: ReadonlyArray<readonly [number, number]> — Its outline, any polygon (concave is fine), in board units.
  • holes: ReadonlyArray<readonly [number, number]> — Its holes, in board units.
  • colour?: string — Its colour, for drawing.

PlateStack

interface PlateStack

The plates and screws, live.

  • readonly world: World — The physics world, for a presenter or a test.
  • step(dt: number): void — Advance by dt seconds: plates pivot and fall.
  • covered(screw: string): boolean — Whether a screw is covered: a plate on a higher layer than every plate it fastens lies over its head.
  • remove(screw: string): boolean — Take a screw out. False when it is covered or out already.
  • place(screw: string, hole: string): boolean — Put a screw that is out into a free hole, fastening the plates with a hole over it. False when it cannot go.
  • move(screw: string, hole: string): boolean — Move a screw from its hole to a free one: take it out (it must not be covered) and put it in.
  • free(hole: string): boolean — Whether a hole can take a screw: none is in it, and no plate's solid part lies over it.
  • freeHoles(): string[] — The holes that can take a screw.
  • plates(): PlateView[] — The plates as they are now.
  • screws(): ScrewView[] — The screws as they are now.
  • holes(): readonly BoardHole[] — The board holes.
  • drain(): PlateStackEvent[] — What happened since the last drain, oldest first.

PlateStackApi

interface PlateStackApi

What the plate-stack pack adds to a game: game.plateStack.

  • create: typeof createPlateStack — Make a stack of plates and screws.
  • validate: typeof validatePlateStack — Check a stack; empty when it can be used.
  • inside: typeof insidePolygon — Whether a point is inside a polygon.

PlateStackEvent

type PlateStackEvent = | { kind: 'out'; screw: string } | { kind: 'in'; screw: string; hole: string; plates: string[] } | { kind: 'pivot'; plate: string; screw: string } | { kind: 'fall'; plate: string } | { kind: 'gone'; plate: string }

What happened, for the rules and the presenter.

PlateStackSpec

interface PlateStackSpec

A stack: the board, its holes, the plates and the screws.

  • width: number — The board's width.
  • height: number — The board's height. A plate that falls below it is gone.
  • gravity?: number — Gravity, units per second squared, down. Default 900.
  • holes: BoardHole[] — The board's holes.
  • plates: PlateSpec[] — The plates.
  • screws: ScrewSpec[] — The screws.
  • tolerance?: number — How near a plate's hole must be to a board hole to be fastened there. Default 12.

PlateView

interface PlateView

A plate as it is now.

  • id: string — Its id.
  • layer: number — Its layer.
  • colour?: string — Its colour.
  • points: [number, number][] — Its outline now, in board units.
  • holes: [number, number][] — Its holes now, in board units.
  • screws: string[] — The screws that fasten it.
  • state: 'held' | 'pivot' | 'falling' | 'gone' — 'held' (two screws or more), 'pivot' (one), 'falling' (none), 'gone' (fallen off the board).
  • x: number — Its centre and turn now.
  • y: number — Its centre and turn now.
  • angle: number — Its turn now, radians.

ScrewSpec

interface ScrewSpec

A screw, in a board hole.

  • id: string — Its id.
  • hole: string — The board hole it is in.
  • colour?: string — Its colour, for rules that sort by colour.

ScrewView

interface ScrewView

A screw as it is now.

  • id: string — Its id.
  • colour?: string — Its colour.
  • hole: string | null — The hole it is in, or null once taken out.
  • x: number — Where it is (its hole's place, or where it was).
  • y: number — Where it is, down.
  • plates: string[] — The plates it fastens.
  • covered: boolean — Whether a plate on a higher layer lies over its head.