@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-stateCore 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 setupidle- Ready for player interactionspinning- Active spin cyclefreeSpins- Free spin bonus roundserror- 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:ready→GAME_READY- Game initialization completegame:bigwincomplete→BIG_WIN_DONE- Big win presentation finishedgame:fsintrocomplete→FS_INTRO_COMPLETE- Free spins intro completegame:fsoutrocomplete→FS_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 theSlotStateServicein 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.
