Slot reels,
ready to spin.
An open-source slot reel engine for PixiJS v8. Fluent builder, typed events, and the weighty spin+stop feel modeled on real-money games.
The parts you'd have to build anyway.
Fluent builder
Zero to a running 5×3 reelset in 10 chainable lines. Validated on build().
Typed events
spin:start, spin:reelLanded, speed:changed, spotlight:end — fully typed payloads.
Headless testing
createTestReelSet + FakeTicker run the full spin lifecycle in Node. No renderer, no flaky timers.
Mechanic sandboxes
Every demo ships with a cheat panel. "Force 3 scatters" is one click.
Agent-friendly debug
enableDebug() attaches JSON + ASCII snapshots to window. Agents inspect state without reading the canvas.
Plug in anything
Symbols, phases, spinning modes, frame middleware — each extension is a named interface.
A builder so fluent
you'll never touch new ReelSet() again.
- One import — ReelSetBuilder wires every subsystem.
- Runtime validation — forget a required call? You'll know at build().
- Extension points everywhere — custom symbols, phases, spinning modes.
- No PixiJS coupling in your logic — tests run in Node.
import { ReelSetBuilder, SpriteSymbol } from 'pixi-reels';
const reelSet = new ReelSetBuilder()
.reels(5)
.visibleSymbols(3)
.symbolSize(140, 140)
.symbols((r) => {
r.register('cherry', SpriteSymbol, { textures: { cherry: cherryTex } });
r.register('seven', SpriteSymbol, { textures: { seven: sevenTex } });
r.register('bar', SpriteSymbol, { textures: { bar: barTex } });
})
.weights({ cherry: 40, seven: 10, bar: 20 })
.ticker(app.ticker)
.build();
const result = await reelSet.spin();
console.log(result.symbols); // [[ 'cherry','seven','bar' ], ...]
Every mechanic,
force any outcome.
Each demo is a live sandbox with the full source, a setup walkthrough, and a cheat panel that pins the result you want — no waiting on RNG.
Classic line pays
5×3 · left-to-right lines
The foundation every slot builds on. Forced wins, spotlight cycling.
- ◆Force winning line
- ◆Force full-grid jackpot
Scatter triggers Free Spins
5×3 · 3+ scatters → FS
Land three scatters anywhere, play a hit animation, enter bonus.
- ◆Force 3 scatters
- ◆Force 4 scatters
Hold & Win respin
5×3 · coins lock, respin until jackpot
Coins lock in place, respin until the grid fills — or 3 coins on middle row.
- ◆Guaranteed landing
- ◆Middle-row progression
Cascade + multiplier
6×5 · tumble × multiplier
Wins disappear, new symbols fall in. Each cascade multiplies payouts.
- ◆Scripted 4-cascade sequence
- ◆Single tumble
Sticky wilds
5×3 · wilds persist for N spins
A wild lands and stays for 3 spins. Stacks with more.
- ◆Force wild on reel 3
- ◆Force 3 stickies on row 2
Anticipation + slam-stop
5×3 · tension + skip()
Hold the last reel for tension, let the player slam-stop it.
- ◆Force anticipation on reels 4+5
- ◆Near-miss scatter
Classic lines with sprite symbols
5×3 · TexturePacker atlas · blur-on-spin
Real sprite art from a single atlas. Motion-blur textures swap in during SPIN, crisp on land.
- ◆Force royal line
- ◆Full-grid royal jackpot
Questions you probably have.
What is pixi-reels? +
An MIT-licensed TypeScript library that gives you a slot reel engine for PixiJS v8: fluent builder, typed events, default spin phases, win spotlight, pluggable symbols (Sprite, AnimatedSprite, Spine), and a headless testing mode.
Which PixiJS version is required? +
PixiJS v8 (^8.17.0) and GSAP v3 (^3.14.0). Spine is optional — only install @esotericsoftware/spine-pixi-v8 if you use SpineReelSymbol.
Can I test mechanics without a renderer? +
Yes. Import from pixi-reels/testing: createTestReelSet, FakeTicker, HeadlessSymbol, spinAndLand, expectGrid, captureEvents, countSymbol. You can run full spin lifecycles and assert on grid outcomes in Node — no canvas, no DOM.
How do I force a specific outcome? +
Call reelSet.setResult(grid) during a spin. For structured control (force a scatter count, force a near-miss, seed an RNG), examples/shared/cheats.ts exposes a CheatEngine with forceGrid, forceLine, forceScatters, forceNearMiss, forceCell, holdAndWinProgress, cascadeSequence, forceAnticipation. Deterministic via Mulberry32.
Which mechanics ship as demos? +
Line pays, scatter-triggered free spins, hold & win, cascade/tumble with multipliers, sticky wilds, anticipation, slam-stop. Each has its own /demos page with a cheat panel.
Does it handle server-driven cascades? +
Yes. runCascade(reelSet, stages, opts) accepts either a pre-known string[][][] array or an AsyncIterable<string[][]> streamed from the server. Each yielded grid becomes a cascade stage.
Is it tree-shakeable? +
ESM + CJS dual format. Spine lives on a separate subpath (pixi-reels/spine) so its runtime drops out of your bundle when unused. Testing utilities are in pixi-reels/testing for the same reason.
Install, and you're spinning.
One package, three peer deps, ten lines of code. Or skip ahead and poke a demo.