pixi-reels

RunCascadeOptions

pixi-reels


pixi-reels / index / RunCascadeOptions

Interface: RunCascadeOptions

Defined in: core/ReelSet.ts:195

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:279
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:202
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:331
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:308
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:274
nextGrid(grid: string[][], winners: readonly Cell[], chainLevel: number) => | string[][] | ColumnTarget[] | Promise<string[][]> | 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: top winners.length rows per reel are new symbols; the rest are survivors in original top-to- bottom order. Same contract as refill({ grid }). May return string[][] (visible cells only) or ColumnTarget[] (when the next grid places anchors in bufferAbove / bufferBelow).core/ReelSet.ts:219
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:257
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:345
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:267
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:240
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:296
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:364