ReelSet
pixi-reels / index / ReelSet
Class: ReelSet
Defined in: core/ReelSet.ts:377
The whole slot board as one object.
A ReelSet is a PixiJS Container that owns every reel, the spin
controller, the speed manager, and the win spotlight. You addChild it
to your stage and then drive it from the four public verbs below:
spin(). start the reels moving, returns a promise that resolves when every reel has landed (or been slam-stopped)setResult(grid). tell the reels what to land on; the spin controller consumes this and each reel queues its target symbolssetAnticipation(reelIndices). slow the given reels before they stop, for “will the third scatter land?” tensionskipSpin()lands the in-flight spin immediately. The slam-stop button calls this.
Everything else is subsystems: speed, spotlight, events, viewport.
Construction goes through ReelSetBuilder, never new ReelSet()
directly. the builder enforces that every required piece is wired.
const reelSet = new ReelSetBuilder()
.reels(5).visibleRows(3).symbolSize(140, 140)
.symbols((r) => r.register('cherry', SpriteSymbol, { textures }))
.ticker(app.ticker)
.build();
app.stage.addChild(reelSet);
const spin = reelSet.spin();
reelSet.setResult(await server.spin());
await spin;
Teardown cascades: one reelSet.destroy() disposes every child.
Extends
Container
Implements
Constructors
Constructor
new ReelSet(params: ReelSetParams): ReelSet;
Defined in: core/ReelSet.ts:460
Parameters
| Parameter | Type |
|---|---|
params | ReelSetParams |
Returns
ReelSet
Overrides
Container.constructor
Accessors
events
Get Signature
get events(): EventEmitter<ReelSetEvents>;
Defined in: core/ReelSet.ts:545
The event emitter for reel-specific events.
Returns
frame
Get Signature
get frame(): FrameAPI;
Defined in: core/ReelSet.ts:1865
Runtime-mutable middleware pipeline for symbol-frame generation.
Example
// Feature entry. swap to a middleware that injects more wilds
reelSet.frame.use(moreWildsMiddleware);
// Feature exit
reelSet.frame.remove('more-wilds');
Returns
isDestroyed
Get Signature
get isDestroyed(): boolean;
Defined in: core/ReelSet.ts:1871
Returns
boolean
Implementation of
isMultiWaysSlot
Get Signature
get isMultiWaysSlot(): boolean;
Defined in: core/ReelSet.ts:1303
Whether this slot was built with .multiways(...).
Returns
boolean
isSpinning
Get Signature
get isSpinning(): boolean;
Defined in: core/ReelSet.ts:1298
Returns
boolean
pins
Get Signature
get pins(): ReadonlyMap<string, CellPin>;
Defined in: core/ReelSet.ts:1668
All active pins, keyed by "col:row".
Reads are safe at any time. during a spin the map reflects pins that
will apply to the NEXT setResult(), not the one already in flight.
Returns
ReadonlyMap<string, CellPin>
reels
Get Signature
get reels(): readonly Reel[];
Defined in: core/ReelSet.ts:1531
Get all reels.
Returns
readonly Reel[]
skipStage
Get Signature
get skipStage(): 0 | 1 | 2;
Defined in: core/ReelSet.ts:1057
Current skipSpin() position within the active round. 0 until the
player presses the slam button, 2 after. Read this to drive button
labels (e.g. “Skip” to “Skipped”). 1 is reserved for forward compat
and is not currently reachable.
requestSkip() that gets queued pre-setResult() does NOT advance
the stage until the queued slam actually fires (i.e. once
setResult() arrives). If you need a “queued” UI state, track that
yourself alongside skipStage.
Returns
0 | 1 | 2
speed
Get Signature
get speed(): SpeedManager;
Defined in: core/ReelSet.ts:1507
Speed profile manager.
Returns
spotlight
Get Signature
get spotlight(): SymbolSpotlight;
Defined in: core/ReelSet.ts:1524
Returns
viewport
Get Signature
get viewport(): ReelViewport;
Defined in: core/ReelSet.ts:1576
Get the viewport.
Returns
Methods
destroy()
destroy(): void;
Defined in: core/ReelSet.ts:1875
Removes all internal references and listeners as well as removes children from the display list.
Do not use a Container after calling destroy.
Returns
void
Example
container.destroy();
container.destroy(true);
container.destroy({ children: true });
container.destroy({ children: true, texture: true, textureSource: true });
Implementation of
Overrides
Container.destroy
destroySymbols()
destroySymbols(cells: readonly Cell[], opts?: DestroySymbolsOptions): Promise<void>;
Defined in: core/ReelSet.ts:718
Destroy a batch of cells in parallel, deferring to each symbol’s own
playDestroy() so subclasses (Spine, particles, custom sprites) can
provide art-appropriate disintegration without the spin handler caring.
This is the canonical “fade out the winners” step in a cascade chain:
call it between win-detection and refill(). Every cell’s view is
lifted with a high zIndex so the destroy animation isn’t clipped by
neighbours. The default playDestroy is a brief scale/fade implode;
override it per symbol class for art-appropriate destruction.
- Empty
cellsresolves immediately, no work. - Out-of-range cells throw. the contract is that you’ve already run win detection on the visible grid, so coords must be valid.
Parameters
| Parameter | Type |
|---|---|
cells | readonly Cell[] |
opts? | DestroySymbolsOptions |
Returns
Promise<void>
Examples
const winners = detectWinners(reelSet.getVisibleGrid());
await reelSet.destroySymbols(winners);
await reelSet.refill({ winners, grid: nextGrid });
// Per-cell stagger. disintegrate left-to-right with a 30 ms beat.
await reelSet.destroySymbols(winners, {
delay: (cell, i) => i * 0.03,
});
getBlockBounds()
getBlockBounds(col: number, row: number): CellBounds;
Defined in: core/ReelSet.ts:1474
Pixel rectangle covering a big symbol’s whole N×M block, in
ReelSet-local coordinates. Returns the anchor cell’s bounds for 1×1
symbols. Pass any cell of a block. anchor or non-anchor. and you
get the same rect.
Useful for win presenters drawing an outline around a whole bonus, or any overlay aligned to the visible footprint of a big symbol:
const rect = reelSet.getBlockBounds(2, 1);
gfx.rect(rect.x, rect.y, rect.width, rect.height)
.stroke({ color: 0xff6b35, width: 4 });
reelSet.addChild(gfx);
For 1×1 cells this is equivalent to getCellBounds(col, row). For
big-symbol cells it multiplies width/height by the block size and
starts from the anchor cell’s bounds.
Parameters
| Parameter | Type |
|---|---|
col | number |
row | number |
Returns
getCellBounds()
getCellBounds(col: number, row: number): CellBounds;
Defined in: core/ReelSet.ts:1559
Returns the bounding box of a visible grid cell in ReelSet-local coordinates (i.e. relative to this Container, before any parent transforms). Row 0 is the top visible row.
Use this to place payline graphics, hit areas, or debug overlays that must align with a specific symbol cell:
const b = reelSet.getCellBounds(2, 1);
gfx.rect(b.x, b.y, b.width, b.height).stroke({ color: 0xff6b35 });
reelSet.addChild(gfx);
To convert to stage / global coordinates use PixiJS:
const global = reelSet.toGlobal({ x: b.x, y: b.y });
Parameters
| Parameter | Type |
|---|---|
col | number |
row | number |
Returns
getPin()
getPin(col: number, row: number): CellPin | undefined;
Defined in: core/ReelSet.ts:1673
Convenience: get the pin at (col, row) or undefined.
Parameters
| Parameter | Type |
|---|---|
col | number |
row | number |
Returns
CellPin | undefined
getReel()
getReel(index: number): Reel;
Defined in: core/ReelSet.ts:1536
Get a reel by index.
Parameters
| Parameter | Type |
|---|---|
index | number |
Returns
getSymbolFootprint()
getSymbolFootprint(col: number, row: number): {
anchor: {
col: number;
row: number;
};
size: {
h: number;
w: number;
};
};
Defined in: core/ReelSet.ts:1410
Footprint of the symbol at (col, row).
- 1×1 symbols:
{ anchor: { col, row }, size: { w: 1, h: 1 } }. - Big symbols: returns the anchor cell and block size.
- OCCUPIED cells: resolves transparently to the anchor.
Useful for win presenters that need to highlight a whole NxM block.
Parameters
| Parameter | Type |
|---|---|
col | number |
row | number |
Returns
{
anchor: {
col: number;
row: number;
};
size: {
h: number;
w: number;
};
}
| Name | Type | Defined in |
|---|---|---|
anchor | { col: number; row: number; } | core/ReelSet.ts:1413 |
anchor.col | number | core/ReelSet.ts:1413 |
anchor.row | number | core/ReelSet.ts:1413 |
size | { h: number; w: number; } | core/ReelSet.ts:1413 |
size.h | number | core/ReelSet.ts:1413 |
size.w | number | core/ReelSet.ts:1413 |
getVisibleGrid()
getVisibleGrid(): string[][];
Defined in: core/ReelSet.ts:1397
Resolved grid, with all OCCUPIED cells (same-reel and cross-reel)
replaced by their anchor’s symbol id. A 2×2 bonus reads as four
'bonus' cells.
Equivalent to reelSet.reels.map(r => r.getVisibleSymbols()) because
each reel has a cross-reel resolver wired in by ReelSet’s constructor.
the per-reel surface and the grid surface are the same.
Returns
string[][]
movePin()
movePin(
from: CellCoord,
to: CellCoord,
opts?: MovePinOptions): Promise<void>;
Defined in: core/ReelSet.ts:1707
Move an existing pin from one cell to another. Animates a flight symbol between the two cells, updates pin state atomically, and resolves when the animation completes.
This is the engine-native replacement for ghost sprites in walking-wild
recipes. The flight symbol is a pooled ReelSymbol acquired from the
factory, parented briefly to the viewport’s unmaskedContainer so it
can travel across reel boundaries without being clipped.
Constraints:
- Only callable at rest (throws if
isSpinning === true). tomust be within the grid; no pin may already exist there.- Calling with
from === tois a no-op that still firespin:moved.
Parameters
| Parameter | Type |
|---|---|
from | CellCoord |
to | CellCoord |
opts? | MovePinOptions |
Returns
Promise<void>
Example
// Walking wild. move the pinned wild one column left each spin
reelSet.events.on('spin:complete', async () => {
for (const pin of [...reelSet.pins.values()]) {
if (pin.col > 0) {
await reelSet.movePin(
{ col: pin.col, row: pin.row },
{ col: pin.col - 1, row: pin.row },
);
} else {
reelSet.unpin(pin.col, pin.row);
}
}
});
nudge()
nudge(col: number, options: NudgeOptions): Promise<{
symbols: string[];
}>;
Defined in: core/ReelSet.ts:1145
Shift a single reel by distance positions after it has landed, revealing
caller-supplied symbols.
Per-reel by design. multi-reel sync is via Promise.all([...]) of
independent calls. Each call emits its own nudge:start / nudge:complete
pair on the ReelSet bus and phase:enter('nudge') / phase:exit('nudge')
on the per-reel bus.
Big-symbol blocks on the target reel are nudged through as a unit as long as they fit on the strip post-rotation. Use case: a 1xH block lands with stubs in bufferBelow; nudge up to reveal it fully.
nudge:start fires AFTER pre-placement so listeners observe the
about-to-tween state, mirroring nudge:complete which fires after
the strip has snapped. To capture the pre-nudge state, snapshot the
grid in your call site before awaiting.
Throws (synchronously) if:
- the reel set is currently spinning (avoid races with the spin pipeline),
colis out of range,- any visible cell on the target reel has an active pin,
Reel.nudgeitself rejects (bad distance / direction / incoming / incompatible big-symbol layout).
While nudge() is in flight, calling spin(), setResult(), pin(),
or setShape() throws. Await the returned promise before calling any
of those methods.
Rejects with an AbortError if options.signal aborts or the reel
is destroyed mid-tween. nudge:cancelled fires on the bus in that case.
Parameters
| Parameter | Type |
|---|---|
col | number |
options | NudgeOptions |
Returns
Promise<{
symbols: string[];
}>
Examples
await reelSet.spin(); // landed
await reelSet.nudge(2, { distance: 1, direction: 'down', incoming: ['wild'] });
Parallel nudges across two reels:
await Promise.all([
reelSet.nudge(2, { distance: 1, direction: 'down', incoming: ['wild'] }),
reelSet.nudge(3, { distance: 1, direction: 'down', incoming: ['wild'] }),
]);
Staggered parallel via `startDelay`:
await Promise.all(
[1, 2, 3].map((col, i) =>
reelSet.nudge(col, { ...opts, startDelay: i * 80 }),
),
);
Abortable nudge:
const controller = new AbortController();
skipButton.onclick = () => controller.abort();
await reelSet.nudge(2, { ...opts, signal: controller.signal })
.catch((e) => { if (e.name !== 'AbortError') throw e; });
pin()
pin(
col: number,
row: number,
symbolId: string,
options?: CellPinOptions): CellPin;
Defined in: core/ReelSet.ts:1607
Pin a symbol to a grid cell. Applied immediately if the reel is idle;
applied at the next setResult() otherwise. Fires pin:placed.
Passing the same (col, row) replaces the previous pin. The old one
is replaced silently (no pin:expired fires for replacement).
Negative rows are rejected. Place buffer-row anchors via setResult()
with bufferAbove / bufferBelow on the column’s ColumnTarget.
Parameters
| Parameter | Type |
|---|---|
col | number |
row | number |
symbolId | string |
options? | CellPinOptions |
Returns
Example
// Sticky wild for 3 spins
reelSet.pin(2, 1, 'wild', { turns: 3 })
// Hold & Win coin with a payout value
reelSet.pin(col, row, 'coin', { turns: 'permanent', payload: { value: 50 } })
// Expanding wild: fill column for the current spin's evaluation only
for (let r = 0; r < 3; r++) reelSet.pin(2, r, 'wild', { turns: 'eval' })
refill()
refill(opts: RefillOptions): Promise<RefillResult>;
Defined in: core/ReelSet.ts:658
Tumble cascade: cascade refill (Moment B). Call this AFTER you’ve faded out the winning symbols in your own code, with the list of winner cells and the next grid the server returned.
- Untouched survivors don’t animate.
- Survivors above a hole slide down to fill it.
- New symbols enter from above into the top
winners.lengthrows of each reel.
The new grid must follow the gravity convention: per reel, the top
winnerRows.length rows are the new symbols, the remaining rows are
survivors in their original top-to-bottom order. This matches what
server-side gravity simulations emit.
Resolves with a RefillResult (mirror of RunCascadeResult.
one stage’s worth). Requires the builder to have been configured with
.tumble(...).
For the common destroy → refill → check → repeat loop, prefer ReelSet.runCascade. it composes refill, destroySymbols, and win-detection with the same cancellation semantics.
Parameters
| Parameter | Type |
|---|---|
opts | RefillOptions |
Returns
Promise<RefillResult>
Examples
const winners = detectWins(currentGrid);
await reelSet.destroySymbols(winners);
const next = await server.cascade(winners);
const result = await reelSet.refill({ winners, grid: next });
console.log(result.finalGrid, result.wasSkipped);
// Abort mid-refill: slams the in-flight animation, resolves with wasSkipped.
const ac = new AbortController();
skipButton.onclick = () => ac.abort();
const result = await reelSet.refill({
winners, grid: next, signal: ac.signal,
});
refreshPinOverlaysForReel()
refreshPinOverlaysForReel(reelIndex: number): void;
Defined in: core/ReelSet.ts:2158
Reposition + resize every pin overlay on the given reel.
The engine calls this automatically after every MultiWays AdjustPhase
reshape (and from the skip path), so applications that just use
setShape() / setResult() never need to invoke it. Call it
yourself only if you mutate Reel.symbolWidth, Reel.symbolHeight,
or a pin’s row outside the normal MultiWays flow. e.g. a custom
mid-spin layout swap that bypasses AdjustPhase.
No-op for reels with no active pin overlays.
Parameters
| Parameter | Type |
|---|---|
reelIndex | number |
Returns
void
requestSkip()
requestSkip(): void;
Defined in: core/ReelSet.ts:1029
Slam-stop safe before setResult() arrives: queues until then.
Bypasses the two-stage skipSpin() machine. An explicit slam intent.
Note on skipStage: when this call queues a slam (pre-setResult)
rather than firing one, skipStage stays at 0 until setResult()
arrives and the queued slam actually runs. If your UI labels the
button off skipStage, expect a beat of “Skip” still shown while
the queued intent is in flight; the queued state is not exposed as
its own stage on purpose (kept the 0 | 1 | 2 shape stable).
Returns
void
runCascade()
runCascade(opts: RunCascadeOptions): Promise<RunCascadeResult>;
Defined in: core/ReelSet.ts:832
Run the canonical cascade chain on top of refill(). Loops:
detect winners → destroy → pause → refill → emit. until
detectWinners returns an empty list (or maxChain is hit, or the
player slammed via skipSpin() / abort). Resolves with the final grid
and a summary.
The orchestration is library-owned; the game rules (what counts
as a winner, how the next grid is computed) stay in your callbacks.
This is the cascade equivalent of spin() + setResult(). three
lines instead of fifteen, and the slam path is handled for you.
Typical usage:
await reelSet.spin();
reelSet.setResult(await server.spin());
const summary = await reelSet.runCascade({
detectWinners: (grid) => detectClusters(grid),
nextGrid: async (grid, winners) => server.cascade(winners),
onCascade: ({ chain, winners }) => bumpMultiplier(chain),
});
console.log(summary.chainLength, summary.totalWinners);
Composes with everything else in the library:
setDropOrder(...)is honoured on every refill in the chain. set it beforerunCascadeand the same order applies to every drop.cascade:fall:symbol,cascade:place:end,cascade:dropIn:symbolfire on each refill.reelSet.skipSpin()ends the chain immediately; the returned summary reportswasSkipped: true.
Event order per stage with winners: cascade:chain:start →
cascade:destroy:start → (destroy tweens) → cascade:destroy:end →
onCascade → pause → refill (cascade:place:end +
cascade:dropIn:* per reel) → cascade:chain:end. The chain itself
is delimited by the returned Promise. await the call to know
when it’s done.
Requires .tumble(...) on the builder (same as refill()).
Parameters
| Parameter | Type |
|---|---|
opts | RunCascadeOptions |
Returns
Promise<RunCascadeResult>
setAnticipation()
setAnticipation(reelIndices: number[]): void;
Defined in: core/ReelSet.ts:963
Set which reels should show anticipation before stopping.
Parameters
| Parameter | Type |
|---|---|
reelIndices | number[] |
Returns
void
setDropOrder()
setDropOrder(order: number[] | "all" | "ltr" | "rtl", stepMs?: number): void;
Defined in: core/ReelSet.ts:1277
Set the per-reel drop order for the next stop / refill sequence.
Convenience wrapper over setStopDelays() for common patterns. The
stagger step defaults to the active speed profile’s stopDelay (or
150 ms if stopDelay is 0).
Sticky. The override persists indefinitely. until another
setDropOrder() / setStopDelays() call overwrites it (a null /
absent override falls back to the default i * speed.stopDelay
stagger). It survives across spin() AND refill() boundaries by
design, because runCascade(...) calls refill() in a loop and the
order set once before the chain must apply to every iteration.
The canonical cascade pattern resets it per phase:
setDropOrder('ltr')beforespin(). left-to-right reveal on the initial drop.setDropOrder('all')beforerunCascade(). every refill in the chain drops all columns simultaneously (the commercial-cascade pattern).
If you leave the order set between rounds and don’t re-set before the
next spin(), the previous value carries over. Re-set explicitly per
round if your rounds use different patterns.
Call again with a different value to change it; the previous value is replaced, not stacked.
Parameters
| Parameter | Type |
|---|---|
order | number[] | "all" | "ltr" | "rtl" |
stepMs? | number |
Returns
void
Example
reelSet.setDropOrder('ltr'); // left-to-right
reelSet.setDropOrder('rtl'); // right-to-left
reelSet.setDropOrder('all'); // all columns simultaneously
reelSet.setDropOrder([0, 0, 200, 200, 400]); // custom per-reel delays
setResult()
setResult(symbols: ColumnTarget[]): void;
Defined in: core/ReelSet.ts:607
Set the target result symbols. Triggers the stop sequence.
One ColumnTarget per reel. visible is the visible-window target;
optional bufferAbove / bufferBelow target cells outside it.
If any pins are active (reelSet.pin(...)), their symbols are overlaid
onto the result before it reaches the stop sequencer, so pinned cells
always land on the pin’s symbolId regardless of what the server sent.
Parameters
| Parameter | Type |
|---|---|
symbols | ColumnTarget[] |
Returns
void
Example
reelSet.setResult([
{ visible: ['A','B','C'] },
{ visible: ['A','B','C'] },
{ visible: ['A','B','C'], bufferAbove: ['COIN'] },
{ visible: ['A','B','C'] },
{ visible: ['A','B','C'] },
]);
setShape()
setShape(rowsPerReel: number[]): void;
Defined in: core/ReelSet.ts:1322
MultiWays: record the row count each reel should land on this spin. The AdjustPhase between SPIN and STOP will reshape reels (resize symbols, reshape motion) before the stop sequence runs.
Must be called between spin() and setResult(). The shape stays in
effect for the current spin only. call again on every spin.
Throws if:
- this slot was not built with
.multiways(...) rowsPerReel.length !== reelCount- any entry falls outside
[multiways.minRows, multiways.maxRows]
Parameters
| Parameter | Type |
|---|---|
rowsPerReel | number[] |
Returns
void
setSpeed()
setSpeed(name: string): void;
Defined in: core/ReelSet.ts:1512
Change speed and emit event.
Parameters
| Parameter | Type |
|---|---|
name | string |
Returns
void
setStopDelays()
setStopDelays(delays: number[]): void;
Defined in: core/ReelSet.ts:981
Override the per-reel stop delay (in ms). Pass one value per reel.
Sticky. The override persists indefinitely. it survives across
spin() AND refill() boundaries until you call setStopDelays()
(or setDropOrder()) again. The persistence is deliberate: cascade
recipes that set setDropOrder('all') once before runCascade(...)
want every internal refill() to honor it. If your rounds use
different patterns, re-set explicitly per round.
Parameters
| Parameter | Type |
|---|---|
delays | number[] |
Returns
void
Example
// Stagger the last two reels more than the default for dramatic effect:
reelSet.setStopDelays([0, 140, 280, 600, 1100]);
setSymbolAt()
setSymbolAt(
col: number,
row: number,
symbolId: string): void;
Defined in: core/ReelSet.ts:1077
Swap the symbol at a single grid cell in-place, at rest.
Caller-facing wrapper over Reel.setSymbolAt that ALSO refuses
pinned cells (since Reel itself can’t see the pin map). Use this
for live presentation effects. sticky-after-win, mid-feature
rewrites. without going through setResult().
Throws (in addition to the per-reel guards documented on
Reel.setSymbolAt) if (col, row) currently has an active pin.
Use unpin(col, row) first if you intentionally want to overwrite it.
Parameters
| Parameter | Type |
|---|---|
col | number |
row | number |
symbolId | string |
Returns
void
Example
await reelSet.spin(); // landed
reelSet.setSymbolAt(2, 1, 'wild'); // swap centre cell to wild
skipNudge()
skipNudge(col?: number): void;
Defined in: core/ReelSet.ts:1229
Fast-forward an in-flight nudge() to its landed state. No-op if the
given reel is not currently nudging.
The tween’s onComplete fires synchronously, the strip snaps to the
final position, and the original nudge() promise resolves on the
next microtask. nudge:complete fires normally. From a listener’s
POV the nudge just landed fast.
Pairs with skipSpin() (round-aware spin land + boost) and
slamStop() (unconditional spin land-now). These three are distinct:
spin actions do not affect a nudge in flight, and skipNudge does
not touch spin state.
Parameters
| Parameter | Type | Description |
|---|---|---|
col? | number | Reel index, or undefined to skip all in-flight nudges. |
Returns
void
skipSpin()
skipSpin(): void;
Defined in: core/ReelSet.ts:1014
Round-aware spin skip. The button-press entry point. The first press in a round slams the current drop AND applies a round-scoped side effect:
- Standard mode: boost the active speed profile to the fastest
registered one (emits
skip:boosted). Restored on the nextspin()(unless the app manually changed speed in between). - Cascade/tumble mode: flag every subsequent
refill()to auto-slam with no animation. One press ends a multi-drop cascade.
Subsequent presses also slam each current drop.
Throws if called before setResult() arrives (nothing to land on:
slamming now would land on random spin-buffer content). The universal
“spin/skip” button pattern should call requestSkip() in that window
(or wrap skipSpin() in a try/catch that routes to requestSkip()
in the catch). Callers that want a slam without the round-scoped side
effects (tests, anti-cheat) should use slamStop().
Pairs with skipNudge() (skip an in-flight nudge()) and slamStop()
(unconditional land-now, no boost). Three distinct actions:
skipSpin()lands the in-flight spin and applies the round-scoped boost / auto-slam-refills side effect.skipNudge()fast-forwards an in-flightnudge()to its landed position. Spin state is unrelated.slamStop()lands every un-landed reel unconditionally. No boost.
Returns
void
slamStop()
slamStop(): void;
Defined in: core/ReelSet.ts:1042
Hard slam-stop. Always lands every un-landed reel immediately.
Bypasses the two-stage skipSpin() machine and any speed boost.
For tests, anti-cheat flows, or any caller with unambiguous
“end now” intent.
Pairs with skipSpin() (round-aware land + boost) and skipNudge()
(fast-forward an in-flight nudge()).
Returns
void
spin()
spin(options?: SpinOptions): Promise<SpinResult>;
Defined in: core/ReelSet.ts:583
Start spinning. Returns a promise that resolves when all (non-held) reels land.
Pass { holdReels: [i, ...] } to keep specific columns frozen for
this spin. they skip START / SPIN / STOP entirely and stay on
whatever symbols they’re currently showing. The use cases are
Hold & Win respins, sticky / expanding wilds, and “the trigger
column stays in place” bonus rounds.
Pass { mode: 'standard' | 'cascade' } to override the builder-time
default for a single spin (e.g. classic strip-spin on the first round,
drop-in on the cascade waves). 'cascade' requires .tumble(...)
on the builder.
Parameters
| Parameter | Type |
|---|---|
options? | SpinOptions |
Returns
Promise<SpinResult>
Examples
// Plain spin. every reel animates.
await reelSet.spin();
// Hold reels 0 and 4; only the middle three reroll.
const spin = reelSet.spin({ holdReels: [0, 4] });
reelSet.setResult(serverGrid); // entries at 0/4 are ignored
await spin;
// Per-spin cascade override.
await reelSet.spin({ mode: 'cascade' });
See {@link SpinOptions} for the full contract (event behaviour,
setResult interaction, setAnticipation filtering).
unpin()
unpin(col: number, row: number): void;
Defined in: core/ReelSet.ts:1653
Remove a pin at (col, row). If no pin exists at that cell, this is a
no-op. Fires pin:expired with reason 'explicit'.
Parameters
| Parameter | Type |
|---|---|
col | number |
row | number |
Returns
void