pixi-reels
Step-by-step

Your first reelset

We build a 5x3 fruit slot. From nothing.

0. Before you start#

You have a Pixi app already. Install: npm i pixi-reels.

1. Make a builder#

import { ReelSetBuilder } from 'pixi-reels';
const builder = new ReelSetBuilder();

Builder first. Configure it. Build it last.

2. Set the grid#

builder
  .reels(5)
  .visibleCells(3)
  .symbolSize(140, 140)
  .symbolGap(4, 4)           // optional
  .bufferSymbols(1);         // optional, default 1

Nothing on screen yet. Nothing broken either. The builder does nothing until .build().

3. Register symbols#

Every symbol needs an id and a class.

  • SpriteSymbol — one static texture
  • AnimatedSpriteSymbol — sprite-sheet animation
  • SpineSymbol — Spine skeletons

Want something else? Extend ReelSymbol and draw whatever you like.

import { SpriteSymbol } from 'pixi-reels';

builder.symbols((r) => {
  r.register('cherry', SpriteSymbol, { textures: { cherry: cherryTex } });
  r.register('seven',  SpriteSymbol, { textures: { seven: sevenTex } });
  r.register('wild',   SpriteSymbol, { textures: { wild: wildTex } });
});

Register nothing and .build() throws: symbols() must register at least one symbol.

4. Weights, ticker, build#

app is your Pixi app.

builder
  .weights({ cherry: 40, seven: 8, wild: 5 })
  .ticker(app.ticker);

const reelSet = builder.build();
app.stage.addChild(reelSet);

Now you see a 5x3 grid of random symbols. Still. Not spinning.

Real slots do not open on random symbols. They open on a chosen frame, or on whatever the player left behind last round. Use initialFrame for that:

builder.initialFrame([
  { visible: ['cherry', 'seven', 'cherry'] },
  { visible: ['wild', 'cherry', 'seven'] },
  { visible: ['seven', 'seven', 'cherry'] },
  { visible: ['cherry', 'wild', 'cherry'] },
  { visible: ['seven', 'cherry', 'cherry'] },
])

It takes buffer symbols too, if you want something peeking in from off-window.

5. Spin#

const promise = reelSet.spin();

It spins. It keeps spinning.

Do not call this straight from a button click. Call it from the state that opens a round and sends the server request. The button starts a round; the round starts the reels.

6. Stop#

The spin promise does not resolve on its own. It waits for you to say what to land on:

const promise = reelSet.spin();

reelSet.setResult([
  { visible: ['wild','seven','wild'] },
  { visible: ['seven','wild','seven'] },
  { visible: ['wild','seven','wild'] },
  { visible: ['seven','wild','seven'] },
  { visible: ['wild','seven','wild'] },
]);

await promise;

Reels stop. Reels show your grid.

The classic mistake: await reelSet.spin() on its own. It never resolves, because nothing ever told it where to stop. Hold the promise, set the result, then await.

What next#