Phaser AE

Waves, difficulty and goals

Pro packv3.0.0-0Arcade

What a level throws at the player and what counts as beating it. A wave plan schedules the arrivals, a difficulty curve holds every number that rises with the level, and goals are the win and lose rules, each with a label and a progress bar's worth of state.

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

Released October 19, 2026

Waves, difficulty and goals: 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.

What it does

A wave plan is a list of waves, each a list of spawn entries: a type, how many, how far into the wave the first one comes and how often the rest follow, with any data you want passed back, such as a lane or a formation. You step the plan with your frame time, and it calls your onSpawn for each arrival as it falls due. A wave can stay open until your clear() check says the field is empty, the plan can loop with a counter or stop at the end, and the loop count is the number a per-loop speed-up reads. The plan never makes anything itself, so it is the same in 2D and 3D.

A difficulty curve declares each number once as a range, such as speed from 80 to 260 over twelve levels, linear, eased in or stepped to whole levels, and holds at the end. You set the curve's level as the game advances and read every value at once. It also records the level each kind of enemy first appears, so a wave can draw from the pool that is unlocked so far.

Goals are objectives with a label, a progress from 0 to 1, and done and failed flags: clear the field, reach a count, survive a time, protect what is left, collect, reach a place, escape before the time runs out, land hits or run laps. They combine with goals.all and goals.any, so "clear the waves while keeping a city standing" is one goal. A catalogue is the collect-one-of-each objective, telling you whether each capture was new and what is still missing.

Features

  • Wave plans — createWaves with spawn entries by type, count, start time and interval, and a callback for every spawn.
  • Waves that wait — a clear() check holds a wave open until the field is empty; without one it ends with its last spawn.
  • Loops — plans loop with a counter for per-loop speed-ups, or end and report finished; start, next and reset move between waves.
  • Difficulty curves — createCurve with named ranges over a number of levels, eased linear, ease or step.
  • Unlocks — the level each kind first appears, with unlocked and available for the pool a wave draws from.
  • Goals — clear, count, collect, hits, laps, survive, protect, reach and escape, each with a label and progress for the HUD.
  • Combined goals — goals.all and goals.any step their members and are done or failed as a group.
  • Catalogues — createCatalogue for one of each, usable as a goal of its own.

Good for

  • Shooters with attack waves, where each wave sends scouts, then escorts round a mothership, and the loop counter speeds the next pass up.
  • Tower defence rounds, with spawns along lanes passed through each entry's data and a protect goal for the base.
  • Survival modes, with a survive goal and a curve that raises speed and shortens gaps level by level.
  • Escapes against the clock, where the goal fails if the player is not out in time.
  • Collect-one-of-each levels, where a catalogue counts the kinds captured and says which are missing.
  • Level files, since waves, ranges and goals are plain data a level can carry.

Make it yours

Everything is the data you pass. A plan is your waves and spawn entries, whether it loops, and the callbacks for each spawn, each new wave and each loop. A curve is your named ranges, how many levels they span, the easing and the unlock table. A goal is a builder and the callbacks that read your counters, with a label of your own, and combined goals nest.

Two different games: a looping shooter whose waves end when the field is clear, whose loop counter sets the curve's level so enemies fly faster on every pass, and whose goal is simply to clear; and a timed escape level with no waves at all, where a curve sets the hazard speed, a catalogue asks for one of each relic, and the win is all of collecting them and escaping before the clock runs out.

A quick look

A plan that waits for the field to clear, and a goal that is lost with the last city:

const plan = createWaves({
    waves: [{ name: 'scouts', spawn: [{ type: 'scout', count: 6, every: 0.4 }], clear: () => enemies.count === 0 }],
    onSpawn: (e, i) => spawnEnemy(e.type, i, e.data),
    onLoop: n => { curve.level = n; },
});
const curve = createCurve({ speed: [80, 260], gap: [1.2, 0.35] }, { over: 12, ease: 'ease', unlock: { tank: 3 } });
const win = goals.all([goals.clear(() => enemies.count, 'WAVES'), goals.protect(() => cities.count, 1, 'CITIES')]);
plan.update(dt); win.update(dt);
if (win.failed) flow.go('over');

Works with

  • scoreboard — score, lives, extra lives and the high-score table.
  • fsm — the game's own flow of attract, play, between waves and game over.
  • flight-formation — for enemy formations that fly in and dive.
  • encounter-director — for encounter pacing with warnings and safe lanes.

Good to know

  • It schedules and counts: it never spawns, moves or draws anything, and what a spawn means is up to onSpawn.
  • Nothing advances on its own; call update(dt) on plans and goals once a frame. A long frame fires every spawn that fell due, in order.
  • A curve runs between two numbers per name; another shape is several ranges or your own function of the level.
  • Goals read your counters through callbacks, so a wrong count in the game is a wrong count in the goal.

More Arcade packs

Show all →