Basic

A state machine for anything with modes

A player that can be idle, running, or jumping is a set of named states and a set of allowed moves between them. Writing the machine makes the illegal moves impossible instead of untested, which is where most game bugs are hiding.

What you will see

false and idle. If it returned true, the table is not being consulted.

About 1 min of reading

Try It

Write a three-state machine

1

Name the states

printf 'const STATES = ["idle", "run", "jump"]; ' | tee game/machine.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Three names. No booleans, no numbers, just names.
2

Write the allowed moves

printf 'const ALLOWED = { idle: ["run"], run: ["idle", "jump"], jump: ["run", "idle"] }; ' | tee -a game/machine.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Every state has a list. A state with an empty list is a trap and should be named as one.
3

Write the one entry point

printf 'function to(w, next) { if (!ALLOWED[w.player.mode].includes(next)) return false; w.player.mode = next; return true; } ' | tee -a game/machine.js

Before you run it, say out loud what it will print. Then open the answer.

What it prints
One function that consults the table. Illegal moves return false and change nothing.
4

Prove an illegal move is blocked

node -e 'const m=require("./game/machine.js"); const w={player:{mode:"idle"}}; console.log(m.to(w,"jump"), w.player.mode)' 2>/dev/null || echo 'idle to jump must be false and mode stays idle'

Before you run it, say out loud what it will print. Then open the answer.

What it prints
false and idle. If it returned true, the table is not being consulted.
Do not assign the mode directly anywhere. Every change goes through the entry point, or the table is decoration and not a rule.

Data Flow

Request to a legal state change
1 Ask for a change of state
↓
2 Look up the pair in the table
↓
3 Found: apply and record
↓
4 Missing: reject and keep the old state
Why this works
What the table buys

It turns a question into a lookup. Is this move legal becomes is this pair in the table, which is checkable and printable.

Where a machine is too small

If two modes differ only by a number, that is a parameter, not a state. States are for behaviour that differs, not for values that differ.

Examples

Name the states

Give each mode a name and store the name, not a flag per mode. Two flags true at once is a state the design never intended.

Write the allowed moves

A table of from-state to allowed to-states. Anything not in the table is rejected by the code, not by a test.

One entry point for a change

All mode changes go through one function that consults the table. A direct assignment anywhere else bypasses the rules.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← What is beyond the canvas
Previous Lesson
What is beyond the canvas
Next Lesson
The game loop and time that is not frames
The game loop and time that is not frames →