Phaser AE

Versus garbage

Pro packv3.0.0-32DGrid

The competitive layer between puzzle boards: who attacks whom, how much, when it lands and who wins the round. It seats any boards that expose its versus hooks, adds offsetting, margin time, rounds, handicaps and CPU opponents, and never takes over a board's own rules.

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

Versus garbage: 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 match holds two to eight seats, each with a board from a board pack, and one step is one 60 Hz tick. Every board steps, and the match reads what happened. An attack, a chain step or a line clear, is scaled by margin time and the seat's handicap, cancels the attacker's own incoming garbage first if offsetting is on, and the rest is routed to its targets and held in transit. When the attacker's move ends, everything in transit is committed to the targets, and each board lands it by its own rules: nuisance after the receiver's next move, garbage rows rising from below, counter gems in the attacker's drop pattern. A seat that tops out is out; the last seat standing wins the round, and the first to a set number of rounds takes the match.

Because attacks are plain numbers, the match is indifferent to what kind of board sends them. A falling-pair board can play a line-clear board. The boards are dealt the same pieces from one seed, so a match is decided by play rather than luck, and the whole match snapshots and restores. incoming says what is on its way to each seat, which is the number behind a nuisance tray, and helpers turn it into tray symbols or a caution, warning or danger level.

CPU seats make their own inputs. They search the board's own placement previews a fixed number at a time, so a frame stays cheap and play is deterministic, then steer the piece there with ordinary moves at their level's speed, under the same gravity and lock rules as a person. In the falling-pair game, easy fires single pops and makes mistakes, normal builds chains of three or four, and hard builds chains of five to seven and looks a piece ahead.

Features

  • Attack routing — to the opponent, to everyone, split between them, to the leader, at random, or by a function of your own.
  • Offsetting — your attack cancels garbage waiting for you, committed or still in transit, before any is sent.
  • Held garbage — attacks wait in transit until the attacker's move ends, or commit at once with hold: false.
  • Margin time — attack power rises over a round, by a target-points sequence or a multiplier table, or a rule of your own.
  • Rounds and matches — first-to-N, simultaneous losses replayed or shared, a pause between rounds and new boards on a new seed each round.
  • Handicaps — per-seat send and receive multipliers and garbage committed at the start of each round.
  • CPU opponents — easy, normal and hard for falling-pair, line-clear, gem-crash and column-grab boards, with profiles you can tune.
  • Shared pieces — every board in a round gets the same seed, so the same pieces.
  • Tray and warning helpers — trayIcons turns incoming garbage into nuisance symbols; warningLevel gives a caution, warning or danger band.
  • Four presets — puyoTsuVersus, puzzleFighterVersus, magicalDropVersus and tetrisVersus, each a plain options object to override.
  • Deterministic — renderer-free, with snapshot and restore for the whole match.

Good for

  • Falling-pair versus puzzles in the style of Puyo Puyo, with nuisance, offsetting and margin time.
  • Gem-crash battles in the style of Super Puzzle Fighter II Turbo, with counter gems and drop patterns.
  • Column-grab versus puzzles in the style of Magical Drop, with garbage lines in the attacker's colours.
  • Two-player line-clear battles, with garbage rows rising after a piece that clears nothing.
  • Free-for-all puzzle royales of up to eight boards, with attacks aimed at the leader.
  • Single-player modes against the computer, with three CPU levels and handicaps to balance them.
  • Mixed matches, such as a falling-pair board against a line-clear board.

Make it yours

A match is a VersusOptions: the number of seats, a function that builds each seat's board for a round, the seed and whether it is shared, the rounds to win, the routing, offsetting, holding, the margin rule, handicaps per seat, a CPU per seat, what a draw does, and the pause between rounds. Each preset returns those options for you to override field by field, and takes its own: colours, pop size and well size for the falling-pair game; drop patterns, speeds and board size for the gem-crash game; attack patterns for the column-grab game; shared pieces for the line-clear game. The CPU profiles expose thinking time, move speed, search depth and beam, mistakes, when to fire and the preview budget. Any board pack can join by implementing the VersusBoard contract.

Two materially different matches: a classic two-player falling-pair match on 6 by 12 wells, first to two, against a normal CPU; and a three-player royale on 8-wide wells that pop at three, attacks going to the leader, one hard CPU and one easy, where each lost seat drops out and the last well standing wins.

A quick look

A falling-pair match against a CPU, stepped once a frame:

const vg = game.versusGarbage;
const match = vg.createVersusMatch(vg.puyoTsuVersus({ cpu: [null, 'normal'], firstTo: 2, seed: 7 }));
// once per 60 Hz frame:
match.step([playerInput]);                       // seat 1 is a CPU: it makes its own input
for (const e of match.board(0).events()) { /* the board's own events: chains, pops, all clears */ }
for (const e of match.drain()) { /* attack, commit, landed, margin, roundOver, matchOver */ }
const icons = vg.trayIcons(match.incoming(0), vg.TSU_TRAY);   // the nuisance tray above well 0

Works with

  • faller — the falling-pair, line-clear and gem-crash boards, seated through fallerBoard and crashGemBoard.
  • grab-throw-columns — the column-grab board, seated through dropBoard.
  • typography — for scores, banners and chain counts.

Good to know

  • Board rules stay with the board packs; this pack only reads their attacks and calls their receive and offset hooks.
  • Falling-piece rulesets without a garbage hook, such as gem-column and capsule games, cannot be seated, and nor can bubbleshooter or catch-stack yet.
  • Continuous offsetting, where garbage is held for as long as you keep chaining, is not a mode yet.
  • Two identical CPUs dealt identical pieces mirror each other and every attack cancels out, so CPU-against-CPU demos should use different levels.
  • Hard CPUs spend up to their preview budget each tick, around 5 ms on a laptop for the falling-pair game; a slower machine plays the same moves at a higher frame cost.

More Grid packs

Show all →