PR pixi-reels
Docs · Architecture
Start here

Overview

The ten-thousand-foot view of every moving piece in pixi-reels.

pixi-reels splits into three concentric rings: the builder wires things, the reel set owns the scene graph and the spin controller, and the test harness + cheats let you drive it headlessly. Every line of the diagram below maps to a file you can click through to in the API reference.

flowchart TB
  Builder["ReelSetBuilder<br/><i>fluent config · .build()</i>"]

  subgraph Tests["Tests & Tooling"]
    direction TB
    subgraph ReelSet["ReelSet (PIXI Container)"]
      direction TB
      SpinController["SpinController<br/><i>orchestrates phases</i>"]
      SpeedManager["SpeedManager<br/><i>normal · turbo · super</i>"]
      SymbolSpotlight["SymbolSpotlight<br/><i>win animations</i>"]
      ReelViewport["ReelViewport<br/><i>masked container</i>"]

      subgraph Reels["Reels[]"]
        direction LR
        Reel0["Reel 0"]
        Reel1["Reel 1"]
        Reel2["Reel 2"]
        Reel3["Reel 3"]
        Reel4["Reel 4"]
      end

      subgraph PerReel["Per reel"]
        direction LR
        Symbols["ReelSymbol[]<br/><i>sprite · spine · headless</i>"]
        Motion["ReelMotion<br/><i>wrap + displace</i>"]
        Sequencer["StopSequencer<br/><i>target frame queue</i>"]
        FrameBuilder["FrameBuilder<br/><i>middleware pipeline</i>"]
      end
    end

    subgraph TestingModule["Testing module"]
      direction LR
      FakeTicker["FakeTicker"]
      HeadlessSymbol["HeadlessSymbol"]
      CreateTest["createTestReelSet"]
      SpinAndLand["spinAndLand"]
      ExpectGrid["expectGrid"]
    end
  end

  Builder --> SpinController
  Reel0 -.-> Symbols
  
Entry points · ReelSetBuilder, the API you actually call
Subsystems · SpinController, SpeedManager, Spotlight
Internals · Motion, StopSequencer, FrameBuilder
Test-time only · FakeTicker, harness

How the pieces talk to each other

ReelSetBuilder is the only class a consumer ever instantiates directly. Its .build() method constructs the ReelSet and every subsystem it needs. you never new a SpinController or a Reel yourself.

Inside the reel set:

  • SpinController orchestrates the spin lifecycle across all reels. It listens to the PixiJS ticker (via a TickerRef) and drives each reel's phase machine.
  • SpeedManager holds named speed profiles (normal, turbo, super-turbo) and emits speed:changed when the active one swaps.
  • SymbolSpotlight handles post-spin win animations: dim losers, promote winners, cycle through multiple pay lines.
  • ReelViewport is the PixiJS Container that masks each reel column to the visible rows.

Each Reel is a scene node that owns its ReelSymbol[] (pooled, swappable), a ReelMotion handler, and a StopSequencer for landing on specific frames. Spin phases (START, SPIN, ANTICIPATION, STOP) are per-reel, which is how anticipation can slow a single reel while the others land normally.

The dotted outer ring

Everything under src/testing/ is tree-shakeable: it exports FakeTicker, HeadlessSymbol, and the createTestReelSet harness. You can build a working 5×3 reel set in Node with no renderer, run a full spin synchronously, and assert the landed grid. see Testing model for how it hangs together.

What lives where

packages/pixi-reels/src/
  • core/. ReelSet, Builder, Reel, Viewport, Motion, StopSequencer
  • spin/. SpinController, phases, spinning modes
  • symbols/. ReelSymbol + Sprite/AnimatedSprite/Spine/Headless
  • speed/. SpeedManager + profiles
  • frame/. FrameBuilder, middleware, RNG
  • spotlight/. win animations
  • events/. typed EventEmitter, event types
  • testing/. FakeTicker, HeadlessSymbol, harness
  • debug/. debugSnapshot, debugGrid, enableDebug
examples/shared/
  • cheats.ts. CheatEngine + built-in cheats
  • BlurSpriteSymbol.ts. sprite symbol with motion-blur swap
  • prototypeSpriteLoader.ts. prototype-symbols atlas loader
  • mockServer.ts. fake spin responses
  • seededRng.ts. Mulberry32 PRNG

Read the next page for the class composition tree in detail, or skip ahead to Events for the full event choreography.