State machines are powerful because behaviour is always guaranteed to be consistent and relatively easily debugged due to how operational rules are written in stone when machine is started. The idea is that your application is and may exist in a finite number of states and then something happens which takes your application from one state to the next. What will drive a state machine are triggers, which are either based on events or timers.
It is much easier to design high level logic outside of your application and then interact with a state machine in various different ways. You can simply interact with a state machine by sending events, listening to what a state machine does or simply requesting the current state.
Traditionally state machines are added to an existing project when developers realize that the code base is starting to look like a plate full of spaghetti. Spaghetti code looks like a never ending, hierarchical structure of IFs, ELSEs and BREAK clauses and probably compilers should ask developers to go home when things are starting to look too complex.