Skip to main content

State Machine

Spinorium includes a built-in state machine that can operate in two modes: with a predefined list of states and strict transitions or dynamically changing states based on game behavior.

Creating a State

To define a new state, extend the State class and override the following methods:

  • enter(manager) – Called when the state manager enters this state.
  • complete() – Marks the current state as complete and requests a transition (typically called within the state itself).
  • leave() – Called when the state manager exits this state.

Additionally, you can override these optional static methods:

  • canEnterState(sourceType?) – Determines whether the state can be entered, optionally considering the sourceType (the previous state). Defaults to true.
  • canCacheState() – Controls whether the state instance should be cached. If enabled, the state manager will create the state instance once and reuse it. Defaults to true.

State Example

export class CustomState extends State {
public override enter(manager:IStateManager):void {
super.enter(manager);

// Do some work, then complete the state

this.complete();
}

public static override canEnterState(sourceType?:IStateType):boolean {
return true;
}

public static override canCacheState():boolean {
return true;
}
}

Predefined States

Spinorium provides several predefined state classes that simplify common use cases. You can extend these states to customize their behavior. These predefined states help streamline the creation of event-driven and timeline-based states, reducing the need for redundant logic.

  • WaitEventState – A state that waits for a specific event before completing.
export class CustomEventState extends WaitEventState {
protected override readonly _eventType = TemplateEvent.SHOW_MAIN_SCREEN;
}
  • StaticTimelineState – A state that creates a timeline once and awaits its completion.
export class StaticAnimationState extends StaticTimelineState {
protected override createTimeline():IAction {
return Actions.waitStaticAnimation(System.scenes.current, {
type: AnimationType.SPINE,
labelName: 'sparks',
path: 'fire'
});
}
}
  • DynamicTimelineState – A state that creates a new timeline instance each time it is entered and awaits its completion.
export class AnimationState extends DynamicTimelineState {
protected override createTimeline():IAction {
return Actions.waitStaticAnimation(System.scenes.current, {
type: AnimationType.SPINE,
labelName: 'sparks_' + RandomUtil.randomBetween(1, 5),
path: 'fire'
});
}
}

State Manager

Spinorium provides two implementations of state manager:

  • StateMachine – A standard state machine where you can define state transitions, manually switch states, and access the current state.
  • StateContainer – A state that functions as a state manager. It allows queuing multiple states, entering them sequentially in predefined steps.

Template Config Customization

To enhance your game or game template with a custom transition list, you can override the stateMachine.initialTransitionsList property in the system config. You'll need to provide an array of pairs (or more if a state can transition to multiple states). Optionally set stateMachine.defaultStateType to define a default state when no transition is possible.

Template Transition List

export const TRANSITIONS_LIST:IStateType[][] = [
[ LoadingState, SplashScreenState ],

[ SplashScreenState, MainScreenState ],
[ MainScreenState, RoundRestoreState ],
[ RoundRestoreState, PlaceBetState, RoundState ],
[ PlaceBetState, RoundStartState ],

[ RoundStartState, RoundState ],
[ RoundState, RoundStopState, RoundInterruptState ],
[ RoundInterruptState, PlaceBetState ],
[ RoundStopState, PlaceBetState ]
];

Visual Representation

Dynamic State Management

The state machine allows for flexible runtime modifications. You can dynamically add transitions and change states without predefining them.

Adding Transitions at Runtime

To define new transitions dynamically, use appendTransition() or appendTransitionsList(). These methods allow you to expand the state machine's functionality during runtime by appending valid state transitions dynamically:

stateMachine.appendTransition(MainScreenState, RoundRestoreState, PlaceBetState);

stateMachine.appendTransitionsList([
[ RoundRestoreState, BonusState ],
[ BonusState, RoundState ]
]);

Changing State Dynamically

You can change states at runtime using changeState(), even if the state was not predefined. This enables adaptive game mechanics where states are determined by real-time player interactions, game events, or external conditions:

stateMachine.changeState(BonusState);