A Functional State Machine for Islands

Learn how to create a state machine for the game.

We'll cover the following

:gen_statem

Many language ecosystems provide ready-made state machine packages that we can customize to fit our own applications. Elixir is no exception to this since OTPOpen Telecom Platform (a collection of useful middleware, libraries, and tools written in the Erlang programming language) has a built-in finitmicre state machine called :gen_statem.

We can use :gen_statem to implement our state machine, but we’re going to build our own from scratch instead. We’ll be able to do it in much fewer lines of code and won’t need to spin up a new process for each state machine, unlike with :gen_statem.

Instead, we define a new module, multiple clauses of a single function, and a data structure to represent the state. Each time we invoke the function, we pass in the state as well as an event. The function decides whether or not to permit that combination of state and event. It also decides whether or not to transition to a new state.

If we return a tuple tagged with :ok, that means the combination is permissible. By returning :error, we signify that it is not. In effect, we create a whitelist of permissible state/event combinations.

This may all seem a little abstract at the moment. Hang in there. It’ll become clear as we go along. Let’s get started!

Defining the rules

We’re about to see just how flexible a data structure and a single function can be. We can use this same pattern to create state machines that fit the needs of any application we’re working on.

Before we write any code, it’s helpful to have a picture of what we need to build, what the pieces look like, and how they fit together. Here’s a representation of the state machine we need to implement, including all the states and the direction of the transitions between them:

Get hands-on with 1400+ tech skills courses.