npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dreams-engine/slot-state

v0.1.2

Published

XState-based state machine for managing slot machine game flow, including spinning, autoplay, free spins, and presentation coordination.

Readme

Slot State

XState-based state machine for managing slot machine game flow, including spinning, autoplay, free spins, and presentation coordination.

Features

  • State machine-driven game flow with XState 5
  • Spin cycle management (request, machine control, presentation)
  • Autoplay system with configurable limits and stops
  • Free spins state management with intro/playing/outro phases
  • Session management with automatic refresh and fallback
  • Configurable feature flags and delays
  • Win and big win presentation coordination
  • Game speed control (normal, quick, turbo)
  • Audio and UI state management

Installation

npm i @dreams-engine/slot-state

Core Architecture

Main State Machine

Central game controller managing all game states:

import { createSlotMachine } from '@dreams-engine/slot-state';

const slotOptions = {
  transport: mockTransport,
  auth: { token: 'demo-token' },
  boot: { createGame: gameFactory },
  features: { autoplay: true, winPresentation: true }
};

const machine = createSlotMachine(slotOptions);
const actor = createActor(machine).start();

State Flow

Main States:

  • boot - Initial game loading and session setup
  • idle - Ready for player interaction
  • spinning - Active spin cycle
  • freeSpins - Free spin bonus rounds
  • error - Error/maintenance state

Child Machines

SpinFlow Machine

Manages individual spin cycles:

// Spin sequence: request → machine start → machine stop → presentation
states: {
  requesting: {},      // HTTP spin request
  machineSpinning: {}, // Physical reel spinning
  presenting: {},      // Win presentations
  done: {}            // Spin complete
}

FreeSpins Machine

Handles free spin bonus rounds:

// Free spin phases: intro → playing → outro
states: {
  intro: {},    // Free spin introduction
  playing: {},  // Active free spins
  outro: {},    // Free spin conclusion
  done: {}      // Return to base game
}

Autoplay Machine

Controls automated spinning:

// Autoplay cycle: waiting → trigger → awaiting → repeat
states: {
  inactive: {},  // Autoplay disabled
  waiting: {},   // Delay between spins
  trigger: {},   // Request next spin
  awaiting: {}   // Wait for spin completion
}

Configuration

SlotStateOptions

Main configuration object:

type SlotStateOptions = {
  transport?: Transport;           // Backend communication
  auth?: AuthConfig;              // Authentication settings
  boot?: GameBootstrapConfig;     // Game initialization
  features?: FeatureFlags;        // Enabled features
  delays?: DelayConfig;           // Timing configuration
  presenters?: Presenters;        // Presentation handlers
  adapters?: Adapters;            // Request/response adapters
  machine?: IMachine;             // Pre-initialized slot machine
};

Feature Flags

Control which features are enabled:

type FeatureFlags = {
  autoplay?: boolean;           // Autoplay functionality
  winPresentation?: boolean;    // Win animations
  allowFsIntro?: boolean;       // Free spin introductions
  allowFsOutro?: boolean;       // Free spin conclusions
  bigWin?: boolean;            // Big win presentations
  gameSpeed?: boolean;         // Speed control
  soundFx?: boolean;           // Sound effects
  music?: boolean;             // Background music
  batterySave?: boolean;       // Battery optimization
};

Delay Configuration

Timing settings for game flow:

type DelayConfig = {
  winStartDelay?: number;        // Delay before win presentation
  longRequestDelay?: number;     // Timeout for HTTP requests
  delayAfterSpinEnd?: number;    // Pause after spin completion
  minimumSpinDuration?: number;  // Minimum spin time
  autoplayDelay?: number;        // Delay between autoplay spins
};

Events

UI Events

Player-initiated actions:

// Spinning
actor.send({ type: 'UI_SPIN', payload: { betAmount: 10 } });
actor.send({ type: 'UI_FORCE_STOP' });

// Autoplay
actor.send({ 
  type: 'UI_AUTOPLAY_TRIGGER', 
  count: 50, 
  stopOnFeature: true,
  winLimit: 1000 
});

// Settings
actor.send({ type: 'UI_SET_GAME_SPEED', speed: 'turbo' });
actor.send({ type: 'UI_TOGGLE_SOUND_FX' });

Machine Events

Internal state transitions:

// Spin cycle events
{ type: 'MACHINE_SPIN_STARTED' }
{ type: 'MACHINE_ALL_REELS_STOPPED' }
{ type: 'PRESENTATION_DONE' }

// Free spin events  
{ type: 'FS_INTRO_COMPLETE' }
{ type: 'FS_OUTRO_COMPLETE' }

// System events
{ type: 'SESSION_READY' }
{ type: 'GAME_READY' }
{ type: 'ERROR', message: string }

Data Types

SpinResult

Server response format:

type SpinResult = {
  prevBalance: number;
  balance: number;
  betAmount: number;
  reels?: string[][];              // Landing symbols
  wins?: WinData[];               // Win information
  bigWins?: BigWinData[];         // Big win information
  roundWinAmount?: number;        // This spin's wins
  totalWinAmount?: number;        // Total session wins
  transition?: TransitionData;    // Game mode transitions
  fs?: FreeSpinData;             // Free spin state
};

WinData

Individual win information:

interface WinData {
  symbolId: string;               // Winning symbol
  matrix: WinMatrix;             // Win positions
  amount: number;                // Win amount
  total: number;                 // Total amount
  multiplier?: number;           // Win multiplier
  lineNumber?: number;           // Payline number
  cascade?: CascadeMatrix;       // Cascade information
  wildWin?: boolean;             // Wild symbol win
  meta?: Record<string, unknown>; // Additional data
}

AutoplayState

Autoplay configuration and status:

type AutoplayState = {
  active: boolean;               // Currently running
  remaining: number;             // Spins left
  initial: number;               // Original count
  stopOnFeature: boolean;        // Stop on bonus features
  totalWin: number;             // Session win total
  winLimit?: number;            // Stop on win limit
  lossLimit?: number;           // Stop on loss limit
};

State Context

GameContext

Complete game state:

type GameContext = {
  app?: Application;             // PIXI application
  machine?: IMachine;            // Slot machine instance
  transport?: Transport;         // HTTP transport
  features: FeatureFlags;        // Enabled features
  delays: DelayConfig;           // Timing settings
  presenters: Presenters;        // Presentation handlers
  
  // Game state
  balance: number;               // Current balance
  prevBalance: number;           // Previous balance
  betAmount: number;             // Current bet
  isSpinning: boolean;          // Spin in progress
  autoplay: AutoplayState;       // Autoplay status
  gameSpeed: GameSpeed;          // Speed setting
  gameReady: boolean;           // Game initialized
  
  // Session
  sessionId?: string;           // Backend session
  token?: string;               // Auth token
  ping: number;                 // Last request latency
  
  // Features
  soundFxEnabled: boolean;      // Sound effects on/off
  musicEnabled: boolean;        // Music on/off
  batterySaveEnabled: boolean;  // Battery save mode
};

Actor System

Master Bridge Actor

Bridges slot game presentation events to the state machine:

import { fromCallback } from 'xstate';
import { attachSlotBridge } from '@dreams-engine/slot';

// Listens master application's events and forwards them to the state machine.
export const masterBridge = fromCallback(({ sendBack }) => {
  const detach = attachSlotBridge({
    onBigWinComplete: () => sendBack({ type: 'BIG_WIN_DONE' } as any),
    onGameReady: () => sendBack({ type: 'GAME_READY' } as any),
    onFreeSpinsIntroComplete: () => sendBack({ type: 'FS_INTRO_COMPLETE' } as any),
    onFreeSpinsOutroComplete: () => sendBack({ type: 'FS_OUTRO_COMPLETE' } as any),
  } as any);

  return () => {
    detach?.();
  };
});

Bridge Events:

  • game:readyGAME_READY - Game initialization complete
  • game:bigwincompleteBIG_WIN_DONE - Big win presentation finished
  • game:fsintrocompleteFS_INTRO_COMPLETE - Free spins intro complete
  • game:fsoutrocompleteFS_OUTRO_COMPLETE - Free spins outro complete

The bridge automatically attaches to the master application's event system and forwards presentation-level events to the state machine. It handles cleanup when the actor is stopped.

HTTP Transport

Transport Interface

Backend communication:

type Transport = {
  request<T>(params: { path: string; payload?: any }): Promise<T>;
};

Session Management

Automatic session handling:

// Session refresh on 401 errors
try {
  const data = await transport.request({ path: 'spin', payload: spinData });
} catch (error) {
  if (error.status === 401) {
    // Auto-refresh session and retry
    const newSession = await transport.request({ 
      path: 'session/refresh', 
      payload: { id: sessionId, token } 
    });
    // Retry original request with new session
  }
}

Presentation Integration

Win Presenter

Coordinate with @dreams-engine/slot-flow:

const presenters = {
  win: new WinPresenter(machine)
};

const slotOptions = {
  presenters,
  features: { winPresentation: true }
};

Game Events

Listen to game events:

import { emitSlotEvent } from '@dreams-engine/slot';

// Events emitted by state machine:
emitSlotEvent('game:balancechange', { current: 1000, old: 990 });
emitSlotEvent('game:autoplaychange', { autoplay: state });
emitSlotEvent('game:fsintro', { remaining: 10, total: 10 });
emitSlotEvent('game:speedchange', { speed: 'turbo' });
emitSlotEvent('game:forcestop');

Usage Examples

Basic Setup

import { createSlotMachine, createActor } from '@dreams-engine/slot-state';

const machine = createSlotMachine({
  transport: mockTransport,
  auth: { token: 'demo-token' },
  boot: { 
    createGame: async ({ signal }) => {
      const app = new Application();
      await app.init();
      return app;
    }
  }
});

const actor = createActor(machine);
actor.start();

// Trigger spin
actor.send({ type: 'UI_SPIN' });

Note: This is a basic example for demonstration. In production environments (such as in @dreams-engine/slot-launcher), actor initialization is handled within service layers with additional features like state subscription management, canvas attachment, cleanup handling, and error management. See the SlotStateService in the slot-launcher package for the complete production implementation.

Autoplay Configuration

// Start 100 autoplay spins, stop on bonus features
actor.send({ 
  type: 'UI_AUTOPLAY_TRIGGER',
  count: 100,
  stopOnFeature: true,
  winLimit: 5000,
  lossLimit: 1000
});

// Cancel autoplay
actor.send({ type: 'AUTOPLAY_CANCEL' });

State Observation

actor.subscribe((state) => {
  console.log('Current state:', state.value);
  console.log('Balance:', state.context.balance);
  console.log('Is spinning:', state.context.isSpinning);
  console.log('Autoplay active:', state.context.autoplay.active);
});

Dependencies

  • XState 5: State machine implementation
  • @dreams-engine/slot: Core slot machine interfaces
  • @dreams-engine/engine: Game engine integration
  • @dreams-engine/slot-flow: Presentation coordination
  • PIXI.js: Graphics framework integration

The package provides a complete state management solution for slot machine games with robust error handling, session management, and presentation coordination.