What it does
Each call to step is one 60 Hz frame, with the player's presses and whether raise is held. The stack rises on its
own at the level's speed, or quickly while raise is held, and a new row slides in at the bottom. The cursor covers two
panels side by side and swaps them. When three or more of a colour line up, the panels flash, show their faces and pop
one at a time in reading order, then leave a gap.
The timing is what makes this genre feel right, and it is all here. Panels above a cleared group hover for a moment, then fall carrying a chain flag. If a flagged panel lands in a new match, the chain grows and scores its bonus; if it lands without matching, the flag is cleared; and when no flag is left and nothing is clearing, the chain ends. So a chain means exactly what it means in the original games, rather than anything that happens to match in quick succession.
Combos and chains score from tables, buy stop time that pauses the rise, and send garbage: a chain of n sends n − 1 full rows. Incoming garbage blocks drop, land, and break a row at a time into ordinary panels when a match touches them. Each frame returns its events: rises, swaps, matches with their combo and chain, pops, landings, chain ends, attacks, garbage drops and breaks, danger at the top and top-out.
Features
- A rising stack — a steady rise, a held fast raise, and a preview of the row coming in.
- A two-wide swap cursor — moved by presses, or
swap(x, y)directly for a pointer. - Flash and pop timing — matched panels flash, show their faces and pop one at a time.
- Hover and fall — panels pause over a gap before they fall, and a panel is never slid under one coming down.
- True chains — tracked by a flag on each falling panel, not guessed from timing.
- Scoring and stop time — per-panel points, combo and chain bonuses, and stop time that pauses the rise.
- Garbage blocks — sent by combos and chains, queued, dropped and broken a row at a time into panels.
- Danger and grace — a set number of frames pressed against the top before topping out.
- Hints and simple AI —
findSwapslists the swaps that would match at once. - Versus adapter —
riseVersusBoardseats a stack in aversus-garbagematch. - Snapshot and restore — the whole state as plain data, replaying exactly.
Good for
- Rising-stack panel puzzles, in the style of Panel de Pon, Tetris Attack or Puzzle League.
- Endless modes where the rise speed climbs with the level, changed while the game runs.
- Head-to-head versus, two stacks trading garbage through
versus-garbage. - Puzzle modes that start from an authored layout with no rise and a set of swaps to find.
- Score-attack and time-attack modes, built from the score, stop time and the game's own clock.
Make it yours
The board's columns, rows and colours are options, as are the seed and the number of rows dealt at the start with no matches, or a layout written as rows of text for a puzzle. The rise speed and raise speed can change while it runs. The grace period at the top, every timing (swap, flash, face, pop per panel, hover and fall per row) and every table (panel points, combo and chain bonuses, combo garbage and stop times) are settings; the defaults follow the classic game's tables as fans have documented them.
Two quite different games: an endless six-by-twelve stack in five colours that speeds up each level; and a puzzle board laid out from text with a rise speed of zero, where the player must clear every panel with a few well-placed swaps. A wider board with more colours, played head to head through the versus adapter, is a third.
A quick look
A six-by-twelve stack driven from the keyboard, with chains reported:
const stack = game.riseStack.createRiseStack({ cols: 6, rows: 12, colors: 5, riseSpeed: 0.3, seed: 8 });
game.step('stack', () => {
const events = stack.step({
left: keys.pressed('ArrowLeft'), right: keys.pressed('ArrowRight'), up: keys.pressed('ArrowUp'),
down: keys.pressed('ArrowDown'), swap: keys.pressed('Space'), raise: keys.held('ShiftLeft'),
});
for (const e of events) if (e.type === 'match' && e.chain > 1) showChain(e.chain);
});
Works with
versus-garbage— runs a match between two stacks throughriseVersusBoard.match3— for swap boards where a move resolves at once with no clock.faller— for falling-piece games.typography— for the score, the chain counter and the stop-time display.
Good to know
- One player's stack per object; two stacks are two objects, and
versus-garbageruns the match between them. - The stop times and rise rates are estimates; every one is a setting.
- Garbage waits in its queue until the rows it needs at the top are clear, rather than stacking above the field.
- There is no cursor auto-repeat: your game decides how a held key repeats.






