PR pixi-reels
All recipes

Nudge through a big symbol

A 1xH block on the target reel is nudged through as a unit. The engine survival-checks anchor + h fits on the strip post-rotation; cross-reel (w>1) blocks still throw.

Loading recipe…

A 1xH block on the target reel is nudged through as a single unit provided the rotation keeps the block intact. The engine pre-flights every block on the strip against an explicit survival formula:

DirectionSurvival condition
'down'anchorStripIdx + h - 1 + distance < total
'up'anchorStripIdx - distance >= 0

Where total = bufferAbove + visibleRows + bufferBelow and anchorStripIdx is the anchor’s index along the full strip (0 is the topmost bufferAbove cell, bufferAbove is visible row 0).

Partial visibility works in both directions. A block whose anchor lives in bufferAbove (tail visible at the top of the window) renders correctly: _finalizeFrame sizes anchors above visible too. Same for anchors in the last visible row whose stubs spill into bufferBelow. The mask clips the off-screen portion; the visible portion of the sprite shows through. Use this for the classic “nudge the tail into view” reveal:

// Block landed with anchor in bufferAbove + tail at row 0.
// Nudge down by 1 brings the full block into rows 0+1.
await reelSet.nudge(2, { distance: 1, direction: 'down', incoming: [...] });

Blocks that wouldn’t survive (anchor or any stub crosses the wrap boundary off the strip) throw with a precise message naming the violated condition. Cross-reel blocks (w > 1) always throw. splitting an anchor from its right-side cells on a different reel isn’t safe under any single-reel nudge.

Tail-visible → nudge to reveal

A tall wild lands with most of it hidden in bufferAbove. only the bottom cell (“the tail”) shows at the top of the visible window. The player nudges to drag the whole block into view.

Loading recipe…

// 1. Land 1x2 MEGA at column 2, rows 0+1 (anchor at row 0).
reelSet.setResult([..., [MEGA, MEGA, filler], ...]);

// 2. Nudge UP by 1 → anchor lives in bufferAbove now, only the bottom
//    cell of the block is in the visible window. Top half is clipped.
await reelSet.nudge(2, { distance: 1, direction: 'up', incoming: [filler] });

// 3. Nudge DOWN by 1 → the full block snaps back into view at rows 0+1.
await reelSet.nudge(2, { distance: 1, direction: 'down', incoming: [filler] });

_finalizeFrame scans bufferAbove for anchors whose blocks extend into visible, sizes the anchor sprite to the full block, and writes the visible-row occupancy with a negative anchorRow referencing the out-of-window anchor. The mask clips the off-screen portion; the visible portion of the sprite shows through naturally.

What the recipe does

// 1. Land a 1x2 wild on column 2 at rows 0+1.
const grid = [col3(), col3(), [MEGA.id, MEGA.id, filler()], col3(), col3()];
reelSet.setResult(grid);

// 2. Nudge column 2 down by 2. Anchor at strip[1] (visible row 0), h=2:
//    survival = 1 + 2 - 1 + 2 = 4, which is < 5 (total). Block fits.
//    After: anchor at strip[3] (visible row 2), stub at strip[4] (bufferBelow).
//    Visually: only the top half of the block is in the visible window.
await reelSet.nudge(2, {
  distance: 2,
  direction: 'down',
  incoming: [filler(), filler()],
});

// 3. Nudge column 2 up by 1. Anchor at strip[3], so up-survival = 3 >= 1 ✓.
//    Block returns to rows 1+2, fully visible.
await reelSet.nudge(2, {
  distance: 1,
  direction: 'up',
  incoming: [filler()],
});

What’s NOT supported

  • Cross-reel blocks (w > 1). Cells on neighbouring reels stay put; nudging only this reel would split the anchor from its other-reel stubs.
  • Big symbols in incoming. The incoming array is 1x1 cells. Placing a new big symbol via a nudge would require the cross-reel OCCUPIED coordinator and a different API surface. use setResult or placeSymbols for that.

Error messages

Each throw spells out the violation so you can debug from the stack alone:

nudge: block 'MEGA' (1x2) at strip[2] wouldn't survive a distance=3 down
nudge. the wrap boundary would split the anchor from its stubs. Block
survival: anchor + h + distance < total (2 + 2 + 3 = 7 vs 5).
nudge: reel 0 carries cross-reel big symbol 'BONUS' (2x2) at strip[1].
Cross-reel blocks can't be nudged from a single reel. the other-reel
cells would stay put and split the block.