pixi-reels

RunCascadeOptions

pixi-reels


pixi-reels / index / RunCascadeOptions

Interface: RunCascadeOptions

Defined in: core/ReelSet.ts:280

Options for ReelSet.runCascade. The two required callbacks (detectWinners, nextGrid) encode game rules; everything else is timing / cancellation / forwarded-to-destroy plumbing with sensible defaults.

Properties#

PropertyTypeDescriptionDefined in
destroyOptions?DestroySymbolsOptionsForwarded to destroySymbols(cells, opts) on every cascade. Useful for per-cell stagger, viewport dim, an abort signal, etc.core/ReelSet.ts:364
detectWinners(grid: string[][], chainLevel: number) => | readonly Cell[] | Promise<readonly Cell[]>Win-detection callback. Receives the current grid (a fresh copy from getVisibleGrid()) and the chain level (0 on the first iteration). Returns the cells whose symbols are “winners” that should be cleared before the next refill. Return [] to end the chain. Sync or async.core/ReelSet.ts:287
gravityHold?(info: { chain: number; winners: readonly Cell[]; }) => Promise<void>Per-cascade promise-builder. Invoked once per chain stage at the gravity-end boundary (i.e. AFTER every reel’s gravity stage has settled, just before the global hold begins). The returned promise is awaited in parallel with gravityHoldMs via Promise.all. whichever finishes LAST gates the drop-in. Only fires when refillMode === 'gravity-then-drop'. Use this when each cascade starts its own anticipation animation (multiplier roll, mascot reaction, anticipation SFX) and you want the builder’s side effects (e.g. multiplier.bumpTo(chain + 1)) to fire AT gravity-end. not back when the refill args were assembled. The library calls your function at the right beat and awaits the promise you return. - chain. same 1-indexed chain stage as cascade:chain:start. - winners. cells cleared this cascade. A rejection from the returned promise is surfaced via the cascade:gravity:error event AND logged via console.error; the engine slams the refill so the awaited promise still settles.core/ReelSet.ts:416
gravityHoldMs?numberFixed wall-clock pause between gravity end and drop-in start, in ms. Only used when refillMode === 'gravity-then-drop'. Default 250. Combines via Promise.all with gravityHold if both are provided. The natural place for asymmetric anticipation visuals: register a listener on cascade:gravity:end (one per reel) and trigger your mascot / multiplier roll / SFX from there. Use gravityHold if you already have an in-flight animation promise, or onGravityComplete if you need a post-hold callback.core/ReelSet.ts:393
maxChain?numberSafety cap on cascade-chain length. Defaults to 32. a sane upper bound that protects against pathological server bugs while being well above any commercial slot’s natural cap. Pass Infinity to disable.core/ReelSet.ts:359
nextGrid(grid: string[][], winners: readonly Cell[], chainLevel: number) => | ColumnTarget[] | Promise<ColumnTarget[]>Next-grid callback. Given the post-destroy grid and the winners that were cleared, return the grid the survivors + new symbols should land on. This is your server-side gravity simulation (or the fallback cascadeNextGrid from your client). Sync or async. Must follow the gravity convention: per reel, winners.length new symbols at the gravity-entry end, survivors packed against the gravity-exit end in their original order. tumble({ gravity }) picks which end is which; the engine animates your grid, it does not reorder it. Same contract as refill({ grid }). Returns ColumnTarget[] — one entry per reel, { visible } plus any bufferStart / bufferEnd anchors. A plain string[][] is not accepted anywhere in the API; wrap it with grid.map((visible) => ({ visible })).core/ReelSet.ts:308
onCascade?(info: { chain: number; currentGrid: string[][]; winners: readonly Cell[]; }) => void | Promise<void>Per-cascade hook fired AFTER destroySymbols and BEFORE the refill starts. Use it to bump multipliers, play SFX, run “winners gone” UI animations. Return a promise to delay the refill (e.g. for a number-roll animation). - chain. same 1-indexed chain stage as cascade:chain:start. - winners. cells that were just destroyed. - currentGrid. the grid as it stood at cascade:chain:start (same reference). The symbols at winners are visually gone but the grid array still names them. nextGrid will replace them.core/ReelSet.ts:342
onGravityComplete?(info: { chain: number; winners: readonly Cell[]; }) => void | Promise<void>Per-cascade callback fired AFTER gravityHoldMs + gravityHold both resolve, BEFORE the drop-in stage. Only fires when refillMode === 'gravity-then-drop'. Use for last-mile side effects that need to read post-hold state (e.g. snapshot the multiplier value that just finished its count-up). - chain. same 1-indexed chain stage as cascade:chain:start. - winners. cells cleared this cascade.core/ReelSet.ts:430
pauseAfterDestroyMs?numberMilliseconds to wait between win-destroy completing and the next refill starting. Commercial slots dial this between 150 ms (snappy) and 500 ms (dramatic). Default 250.core/ReelSet.ts:352
presentWinners?(info: { chain: number; currentGrid: string[][]; winners: readonly Cell[]; }) => void | Promise<void>Win-presentation hook fired AFTER detection (cascade:chain:start) and BEFORE destroySymbols. the beat where the winners are still on the board. This is where a WinPresenter pass belongs: play the authored win clip, dim the losers, await, and only then does the library destroy the cells. A round’s presentation order is win → destroy → refill; onCascade remains the post-destroy hook. - chain. same 1-indexed chain stage as cascade:chain:start. - winners. cells about to be destroyed. still visible. - currentGrid. the grid as it stood at cascade:chain:start.core/ReelSet.ts:325
refillMode?"combined" | "gravity-then-drop"How each refill in the chain animates. - 'combined' (default). survivors and new symbols animate together in one drop-in beat. The Sweet Bonanza / Sugar Rush feel. - 'gravity-then-drop'. survivors slide down to fill holes FIRST, then a global pause (gravityHoldMs), then new symbols enter from above with the per-reel stop delay applied. The Mummyland Treasures / Reactoonz feel. gives space for an anticipation beat between gravity and new-symbol entry. Per-column stagger inside the new-symbol drop is controlled by setDropOrder('ltr', stepMs) exactly as in combined mode. when the step is shorter than dropIn.duration you get overlapping waves; when it’s at least as long you get strictly sequential columns.core/ReelSet.ts:381
signal?AbortSignalAbort signal for caller-driven cancellation. The loop exits at the next await boundary, the in-flight refill (if any) is slammed via slamStop(), and the resolved summary reports wasSkipped: true. Use this for “player tapped SLAM mid-cascade”. reelSet.skipSpin() is a no-op when called between refills (the engine is idle), so it cannot end the chain from a button handler. AbortController can. const controller = new AbortController(); skipButton.addEventListener('click', () => controller.abort()); await reelSet.runCascade({ ..., signal: controller.signal });core/ReelSet.ts:449