Game Dev 101
Progress
0/22

Lesson 15 of 22, in world 5: Game Architecture

State Machines

Time
About 20 min
Builds on
Gravity, Jumping & Collision ResponseHandling InputSprites & Animation

Your player can idle, run, jump, fall, dash, attack, get hurt and die. Each of these behaves differently, and only some changes make sense (you can’t jump while dead). Managing this with booleans quickly becomes a bug farm. A finite state machine (FSM) tames it.

The boolean soup problem

JavaScript
// 😱 Which combinations are valid? isJumping && isDashing && isDead?
if (isJumping && !isDashing && !isHurt) { ... }
else if (isDashing && !isDead) { ... }
else if (onGround && !isJumping && isMoving && !isAttacking) { ... }

With 5 booleans there are 32 combinations, most of them nonsense, and every new feature touches every if. An FSM replaces all those flags with a single variable: state.

A finite state machine

  • The object is in exactly one state at a time.
  • Each state has its own behaviour (update logic) and its own transitions (when to switch, and to what).
  • Optional enter/exit hooks run once on change — the perfect place to start an animation, play a sound, or apply a jump impulse.
LiveA player state machine, live

Move ←→, jump Space, dash Shift (once per jump). The diagram lights up the current state and flashes each transition as it happens. The player can only ever be in one state, and each state only checks the transitions that make sense for it.

JavaScript
function update(dt) {
  switch (state) {
    case 'idle':
      if (input.jump) change('jump')
      else if (input.move) change('run')
      break
    case 'run':
      player.vx = input.dir * SPEED
      if (input.jump) change('jump')
      else if (!input.move) change('idle')
      break
    case 'jump':
      applyGravity(dt)
      if (player.vy > 0) change('fall')
      break
    // ...
  }
}
function change(next) {
  exit(state)          // e.g. stop the run dust particles
  state = next
  enter(state)         // e.g. vy = -JUMP_SPEED; play('jump'); sfx('jump')
}

Where FSMs show up in games

  • Player controllers — like the demo.
  • Enemy AI — patrol → chase → attack → flee (lesson 18).
  • Animation — each state plays a clip (lesson 11).
  • Game flow — title → playing → paused → game over (lesson 20).

Key takeaways

  • Replace piles of booleans with one state variable.
  • Each state owns its behaviour and its outgoing transitions.
  • Use enter/exit hooks for one-time effects (impulses, sounds, animations).
  • FSMs drive players, enemies, animation and whole-game flow.

Check yourself

Q1. Where is the best place to apply the jump impulse (vy = -JUMP)?

Q2. In the demo, why can’t you dash twice in one jump?

Q3. A character can run and shoot at the same time. Best structure?

Exercises

  1. Draw the diagram for a door: closed, opening, open, closing, locked. Which transitions need a key?
  2. Add a "crouch" state to the demo on paper: which states can enter it, and how does it exit?
  3. Design an enemy FSM: patrol, chase, attack, return. What condition triggers each transition?