Layered Slot Client Architecture and State Machine Design

Building a reusable client framework so every new game only ships what makes it different

A three-tier breakdown of a reusable slot client: generic engine, slot framework and game layer, plus the finite state machine driving one spin end to end.

What Problems Does a Slot Game Client Have to Solve?

Building the client for a slot game is far more than "a few reels spinning on screen." From a technical standpoint, a mature slot client has to solve at least the following core challenges:

These challenges are not independent of one another. This article first deals with the two most fundamental structural questions: how the code is layered, and how the flow of a single round is described in an orderly way.

A Layered Framework: Build Once, Reuse Many Times

To keep code quality and development efficiency high while continuously shipping new games, we organize the entire client system with a three-layer architecture:

The three client layers Game application, slot framework and generic engine from the top down, growing more general and more reusable with each layer. Game application theme assets / special features / custom animation Slot framework reel engine / state machine / win presentation / paylines Generic engine render pipeline / asset loading / audio / networking / events The lower the layer the more general it is: a new game rebuilds only the top one
The point of layering is build once, reuse often: a new game leaves the lower two layers untouched.

General Engine Layer

The bottom layer holds capabilities that have nothing to do with the genre: the render pipeline, the asset loader, audio playback, protocol encapsulation, the event system, timers and animation tweening utilities, and so on. Code at this layer applies to any kind of game, not just slots.

Slot Framework Layer

The middle layer encapsulates the logic common to the slot genre: the reel engine, the state machine, win-presentation scheduling, payline rendering, the autoplay controller, the history panel, and so on. Every slot game shares the code in this layer, so when the framework fixes a problem or improves performance, all games benefit at once; the more games there are, the greater the return on each improvement.

Game Application Layer

Only the top layer contains what is unique to each game: themed art assets, special mechanics (expanding wilds, progressive jackpot trigger conditions, and the like), custom animation and audio. When building a new game, engineers only need to focus on this layer, which dramatically shortens the development cycle.

What Should Sink Downward?

The place a layered architecture most easily breaks down is deciding which layer a new piece of logic belongs to. We follow three criteria:

How the Architecture Evolved

This layered architecture was not in its finished form from day one; it went through several stages of evolution:

The Game State Machine: The Full Lifecycle of One Spin

Each round of a slot game looks simple (press the button, the reels spin, the result appears), but the state management behind it is genuinely complex. We use a finite state machine to manage the full lifecycle of a round:

The life cycle of one spin Six states from starting a round through to settlement, which returns to the start and closes the loop. Start round Start reels Keep spinning Stop and Show win Settle Settlement returns to the start of a new round A state machine makes the entry and exit condition of every step explicit and testable
The cycle does not always complete cleanly: quick stop, disconnection and timeout each need a defined recovery path.

Why Not Flags and Callbacks?

The most intuitive approach is to track the current situation with boolean flags: whether it is spinning, whether the result has arrived, whether the win animation is playing. But five independent flags already yield thirty-two combinations, the vast majority of which are illegal states that should not exist, and yet nothing in the code explicitly forbids them. A state machine narrows the legal states down to a finite, enumerable set and hard-codes the transition rules. A transition that should not happen is intercepted at that moment, rather than being discovered only after the player sees something wrong on screen.

Responsibilities of Each Stage

Extensibility of the State Machine

The design of the state machine allows custom logic to be inserted between any two stages. For example, if a particular game needs to trigger a "symbol transformation" animation after the reels stop, it only has to register an extra state handler between "stop the reels and write in the result" and "win presentation," with no changes to framework-layer code at all.

This mechanism relies on the observer pattern: every stage emits events on entry and exit, and an upper layer that subscribes can insert its own node. The key is that an inserted node must be able to signal completion asynchronously. The state machine waits for it to report done before advancing, so a custom animation several seconds long can be embedded into the lifecycle naturally, without the framework layer needing to know in advance that it exists.

Multiple Flows and Exceptional Interruptions

Slots frequently involve switching between multiple flows: transitions between the main game and free games, entering and exiting special feature modes. We give each flow its own state machine instance, with the instances communicating through explicit enter/exit events to avoid state contamination between flows.

The lifecycle does not always run to completion smoothly either: the player may hit quick stop partway through, and the network may drop while waiting for the result. So every stage has to mark whether it is interruptible: presentation stages can usually be skipped, while stages involving data consistency must run to completion. A skipped stage is not simply thrown away but told to "finish immediately," which guarantees that the screen after the skip matches what the normal flow would have produced.

Layering and the state machine form the skeleton of the client. On top of that skeleton there are two more topics worth going into: the reels' animation curves and stop control, and the supporting systems for communication, assets and interface layering. We cover each of them in the other two articles of this series.