Phaser AE

Crowd cannon and multiplier gates

Pro packv3.0.0-12DArcade

A crowd battle with a cannon: fire a stream of units through gates that multiply them, against an enemy base sending its own waves back. The field, the gates and the balance are options, and the pack hands you every unit to draw.

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

Released October 19, 2026 · updated October 20, 2026

Crowd cannon and multiplier gates: 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

crowdCannon

function crowdCannon(): Pack<{ crowdCannon: CrowdCannonApi }>

The crowd-cannon pack: game.crowdCannon, Mob Control's rules. No options.

Helpers

createCannonAutopilot

function createCannonAutopilot(game: CrowdCannonGame, options: { speed?: number } = {}): CannonAutopilot

The round's autopilot.

createCrowdCannon

function createCrowdCannon(options: CrowdCannonOptions = {}): CrowdCannonGame

Start a round. Throws, with every fault, on options validateCrowdCannon refuses.

planCannonGates

function planCannonGates(field: { width: number; length: number }, count: number, rng: Rng): CannonGate[]

Gates by seed for a field: one a band up the field, mostly x2, some x3 and a few +2 or +3, half of them swinging.

validateCrowdCannon

function validateCrowdCannon(options: CrowdCannonOptions = {}): string[]

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

Types

CannonAutopilot

interface CannonAutopilot

A player that aims and fires.

  • next(): number — Where to aim the cannon now; it also fires and launches giants through game.

CannonEvent

type CannonEvent = | { kind: 'shot' } | { kind: 'giant' } | { kind: 'multiply'; gate: number; made: number } | { kind: 'clash'; x: number; y: number } | { kind: 'base'; damage: number; hp: number } | { kind: 'breach'; damage: number; hp: number } | { kind: 'won' } | { kind: 'lost' }

Something that happened.

CannonGate

interface CannonGate

A gate: units passing through it become n times as many ('x') or gain n more ('+').

  • x: number — Its middle across the field (0 the middle), how far up the field, and its width.
  • y: number — How far up the field the gate's line stands, in field units from the cannon's line; between 0 and the field's length, exclusive.
  • w: number — The gate's width in field units; above 0 and no wider than the field.
  • op: 'x' | '+' — What it does to a unit that crosses: 'x' multiplies it, '+' adds units.
  • n: number — The multiplier for 'x' or the number of units added for '+'; a whole number, 1 or more.
  • sweep?: { range: number; rate: number } — It swings side to side: this far each way, this many times a second.

CannonUnit

interface CannonUnit

A unit on the field.

  • id: number — Unique number, rising in the order units appeared.
  • side: 'blue' | 'red' — Whose it is: 'blue' is yours, 'red' the enemy base's.
  • x: number — Across the field in field units, 0 the middle.
  • y: number — Up the field in field units, from 0 at the cannon's line to the field's length at the base.
  • hp: number — Hit points left; the unit is removed at 0. Ordinary units have 1, giants more.
  • giant: boolean — Whether it is a giant: slow, many hit points, and no gate multiplies it.
  • gates: number[] — Indices into the game's gates of the gates it has passed; a unit crosses each gate once.

CannonView

interface CannonView

What is where.

  • state: CrowdCannonState — A copy of the round's state.
  • gates: (CannonGate & { now: number })[] — The gates, each with now, its middle across the field at the round's current time.
  • field: { width: number; length: number } — The field's width and length in field units.

CrowdCannonApi

interface CrowdCannonApi

What the crowd-cannon pack adds to a game: game.crowdCannon.

  • create: typeof createCrowdCannon — Start a round.
  • validate: typeof validateCrowdCannon — Check a round's options.
  • gates: typeof planCannonGates — Generate gates for a field by seed.
  • autopilot: typeof createCannonAutopilot — A player for an attract mode or a test.

CrowdCannonGame

interface CrowdCannonGame

A round.

  • readonly state: CrowdCannonState — The live round state; read it freely, but change it only through the methods.
  • readonly gates: readonly CannonGate[] — The gates in play: the gates option, or the generated set.
  • readonly field: { width: number; length: number } — The field's width and length in field units.
  • move(x: number): void — Slide the cannon: -1 left to 1 right.
  • aim(x: number | null): void — Slide the cannon towards a place across the field (as dragging does), or null to stop.
  • fire(on: boolean): void — Fire while true.
  • launch(): boolean — Launch a giant, if the meter is full.
  • gateX(g: CannonGate, time: number): number — A gate's middle across the field at a time.
  • step(dt: number): void — Advances the round by dt seconds in fixed 1/60 s ticks, counting at most 0.25 s per call. Throws if dt is negative or not a number.
  • view(): CannonView — A deep copy of the state, the gates with where each is now, and the field.
  • drain(): CannonEvent[] — Returns and clears the events since the last drain; only the latest 512 are kept.
  • snapshot(): CrowdCannonSave — Saves the round as plain JSON (a deep copy), including the random generator's state.
  • restore(save: CrowdCannonSave): void — Loads a save made by snapshot, replacing the round and discarding undrained events.

CrowdCannonOptions

interface CrowdCannonOptions

A round's options.

  • seed?: number — Default 1.
  • field?: { width?: number; length?: number } — The field: its width and length. Default 12 by 40.
  • gates?: CannonGate[] — The gates. Default a generated set (see gateCount).
  • gateCount?: number — Gates generated when none are given. Default 3.
  • baseHp?: number — The enemy base's hit points, and yours. Default 800 and 20.
  • hp?: number — Your hit points; enemies reaching the cannon's line take them. Default 20.
  • rate?: number — Units a second the cannon fires. Default 7.
  • speed?: number — Units' speed up and down the field. Default 6 and 3.5 for enemies.
  • enemySpeed?: number — Enemy units' speed down the field in field units a second. Default 3.5.
  • waves?: { start?: number; end?: number; ramp?: number } — Enemies a second from the base, at the start and after ramp seconds. Default 3 to 12 over 50 s.
  • giant?: { every?: number; hp?: number; damage?: number } — Shots that charge a giant, its hit points (units it outlasts) and damage to the base. Default 40, 12 and 12. The base's own giants have six tenths of the hit points.
  • max?: number — The most units on the field at once. Default 400.
  • slide?: number — The cannon's speed across the field. Default 10.

CrowdCannonSave

interface CrowdCannonSave

A round saved as plain JSON.

  • state: CrowdCannonState — The round's state.
  • serial: number — The last unit id handed out, so a restored round keeps numbering from there.
  • spawn: number — Seconds until the base sends its next enemy.
  • reload: number — Seconds until the cannon may fire again; zero or less means ready.
  • carry: number — Seconds of step time not yet spent, under one 1/60 s tick.
  • aim: number | null — The place across the field the cannon is sliding towards, or null when not aiming.
  • input: number — The slide direction set by move, -1 left to 1 right.
  • rng: RngState — The random generator's state.

CrowdCannonState

interface CrowdCannonState

Where the round stands.

  • time: number — Seconds of play elapsed; it stops when the round ends.
  • phase: 'play' | 'won' | 'lost' — 'play' while the round runs, 'won' once the base is down, 'lost' once your hit points are gone.
  • cannon: number — The cannon across the field.
  • firing: boolean — Whether the cannon is firing, as last set by fire.
  • baseHp: number — The enemy base's hit points left; the round is won at 0.
  • hp: number — Your hit points left; the round is lost at 0. An enemy reaching the cannon's line takes 1, an enemy giant 5.
  • meter: number — The giant's meter, 0 to 1 (full: one is ready), from the shots since the last giant.
  • charge: number — Shots counted towards the next giant, up to giant.every; meter is this divided by that.
  • shots: number — Shots fired so far this round.
  • units: CannonUnit[] — Every unit on the field, both sides, at most the max option.