pixi-reels
All recipes

Hold & Win: collector + flight choreography

A board that opens holding three 5.00 coins, lands a 10.00, then lands a collector orb that pulls a value clone out of every coin along bezier arcs — summing up tick by tick. Next press resets with a column-wave sweep.

Loading recipe…

Press Run. the free cells respin twice (held coins never move), the purple collector orb lands, and a clone of each coin’s value arcs into it — 5.00, 5.00, 5.00, 10.00 ticking the orb’s total up to 25.00. Press again for the reset sweep.

This is the “special collector symbol” variant of the collect family: the collector is just another server-placed id, the coins keep their values, and everything that moves is game-layer choreography on top of three board openings (events, cellCenter(), symbolAt()).

The collector orb holds 25.00 after value clones arc in from each coin
The collected state — every coin's value summed into the orb

Wave choreography: coinWaves()

Every batched effect in the demo — collect order, the reset sweep — goes through one helper that turns a coin list into ordered waves:

coinWaves(board.lockedCoins, 'sequence')   // one by one, reading order
coinWaves(board.lockedCoins, 'by-col')     // column sweeps (the reset uses this)
coinWaves(board.lockedCoins, 'by-row')     // row pulses
coinWaves(board.lockedCoins, 'all')        // everything at once
coinWaves(board.lockedCoins, { chunk: 5 }) // index ranges: 0-4, 5-9, 10-14
coinWaves(board.lockedCoins, (c, i) => i % 2) // custom: any item -> wave index

Fire a wave, await it, move to the next. The same call drives landing effects, collects, win presentations — anything that should hit coins in a pattern.

Curved flights: bezierFly()

Flights are quadratic beziers with a configurable arc — no straight-line tweens:

bezierFly(clone, from, to, { lean: 'up', curvature: 0.4, arriveScale: 0.45 })
// lean: 'up' | 'down' arcs over/under the path
// lean: 'in' | 'out' bends toward/away from `around` (e.g. screen centre)
// control: { x, y } overrides everything - compute it per coin index to
//          aim flights at a specific feature meter

arriveScale shrinks the clone as it lands in the meter; the promise resolves on arrival so sums tick exactly on impact.

Pacing rule: land effects gate the next spin

Every coin:locked handler pushes its effect promise into a pendingFx batch, and the spin loop does await Promise.all(pendingFx.splice(0)) before the next respin(). Reveals and flourishes always finish before the reels move again.