584. Lesson identity
This lesson defines enemy behavior through observable states and explicit rules for moving between them. The goal is not to make an enemy appear generally intelligent. The goal is to make its behavior legible, testable, and governed by a clear state-selection contract.
585. Learning objective
After this lesson, you can define the states, transition conditions, outputs, decision responsibility, and failure behavior of a small enemy state machine. You can represent that specification as a state contract table, an explicit transition table, and a matching directed graph or labeled edge list.
586. Why this matters
“Make the enemy smarter” is not an implementable requirement. It does not say what the enemy can observe, which behavior it may select, when that selection changes, or what should happen when required information or an operation is unavailable.
A state contract converts that vague request into inspectable rules. A state graph exposes permitted routes, missing exits, and unreachable states before implementation begins.
587. Prior knowledge
You should already be able to trace a combat event from intent to outcome, identify the system authoritative for a health change, and distinguish game state from presentation. This lesson builds on 2.1 L2 — Trace damage from intent to outcome. You do not need a completed enemy controller.
588. State, transition condition, and output
A small state machine contains three elements you must distinguish:
- State: the current behavioral mode, such as
IDLE,CHASE, orATTACK. - Transition condition: an observable fact or named event that permits a state change, such as “target distance is at or below attack range.”
- Output: a request or observable action produced while a state is active, such as “request movement toward the target.”
Consider this rule:
While in CHASE, request movement toward the valid target. If the target is in attack range and the attack is available, enter ATTACK.
In that rule:
CHASEis the state;- requesting movement is an output;
- target in range plus attack available is a transition condition;
ATTACKis the next state.
An output is not automatically a resolved consequence. ATTACK may emit an attack request, but the authoritative combat system still decides whether the request satisfies combat rules and whether health changes.
589. A state is a contract
A useful state contract specifies:
- Entry condition: what must be true when the state begins.
- Observable output: what the state requests or exposes while active.
- Exit conditions: the facts or events that permit leaving the state.
- Decision responsibility: which component selects the state and evaluates its transitions.
- Failure behavior: what happens when information is missing or a requested operation fails.
CHASE is incomplete if it only means “follow the player.” A usable contract might say:
- Enter
CHASEwhen a valid target is detected outside attack range. - While active, request movement toward that target.
- Enter
ATTACKwhen the target is in range and the attack is available. - Enter
SEARCHwhen the target has remained unseen for a defined interval. - Enter
RETURNwhen the pursuit boundary is reached. - If movement fails, expose the failure and follow a declared fallback instead of retrying silently without a limit.
Decision responsibility means responsibility for selecting behavioral states. It does not imply authority over movement results, health changes, animation playback, or rewards.
590. State contract table
Use a table before requesting an implementation:
| State | Entry condition | Observable output | Exit condition | Decision responsibility | Failure behavior |
|---|---|---|---|---|---|
IDLE |
No valid target | Wait or request patrol behavior | Valid target detected outside attack range, or valid target detected inside attack range | Enemy decision controller | Remain idle; do not invent a target |
CHASE |
Valid target detected outside attack range | Request movement toward the target | Target is in range and attack is available, target remains unseen for the loss interval, pursuit boundary is reached, or movement fails | Enemy decision controller | Stop and re-evaluate or enter a declared fallback |
ATTACK |
Target in range and attack available | Request an attack | Attack completes, target leaves range, or target becomes invalid | Enemy decision controller selects the state; combat resolves consequences | Leave or cancel the state; do not apply unvalidated damage |
SEARCH |
Recently detected target is no longer visible | Request movement toward the last known position | Target reacquired, search expires, or position is invalid | Enemy decision controller | Enter RETURN or another declared fallback |
RETURN |
Search expires or pursuit boundary is reached | Request movement toward the assigned area | Assigned area reached and no valid target exists, a permitted target is detected, or movement fails | Enemy decision controller | Stop at a safe location and expose the movement failure |
The table identifies the component responsible for state selection. It does not transfer authoritative resolution to that component.
591. State graph
The table defines each state contract. The directed graph defines the allowed transitions between states.
Draw one node for every state and one arrow for every permitted transition. Mark the initial state and label every arrow with an observable guard.
Use this form:
CURRENT STATE + OBSERVABLE FACTS + GUARD → NEXT STATE
For example:
CHASE + target distance ≤ attack range + attack available → ATTACK
“The enemy feels ready” is not a useful guard. “The target has remained unseen for 3 seconds” is measurable and testable.
A guard enemy might include these edges:
IDLE → CHASE: valid target detected outside attack range.IDLE → ATTACK: valid target detected inside attack range.IDLE → IDLE: in-range attack request rejected by combat; health unchanged.CHASE → ATTACK: target is in range and attack is available.ATTACK → CHASE: target remains valid but leaves attack range.CHASE → SEARCH: target remains unseen for the loss interval.SEARCH → CHASE: target is reacquired.SEARCH → RETURN: search duration expires.CHASE → RETURN: pursuit boundary is reached.CHASE → RETURN: movement request fails; expose the failure.ATTACK → CHASE: attack request rejected by combat; health unchanged.ATTACK → SEARCH: target becomes invalid during attack.ATTACK → ATTACK: attack completes, cooldown remaining > 0, target still valid and in range.ATTACK → ATTACK: attack completes, cooldown remaining = 0, target still valid and in range.SEARCH → RETURN: last known position is invalid.RETURN → CHASE: permitted target detected.RETURN → IDLE: movement fails; stop at a safe location.RETURN → IDLE: assigned area is reached and no valid target exists.
The table and graph must describe the same machine. If the table says SEARCH → RETURN is possible but the graph omits that edge, the artifacts disagree. If a graph edge has no documented guard, the transition contract is incomplete.
592. 8b. Transition table
The state-contract table describes each state. Graph parity is checked against this transition table, not against aggregate exit-condition cells. A labeled directed edge list is an accepted equivalent to a drawn graph.
| Current state | Observable guard / event | Next state | Requested output | Failure / fallback |
|---|---|---|---|---|
IDLE |
valid target detected outside attack range | CHASE |
request movement toward the target | do not invent a target |
IDLE |
valid target detected inside attack range | ATTACK |
request an attack | if combat rejects the request, remain IDLE via the IDLE → IDLE rejection edge; health unchanged |
IDLE |
in-range attack request rejected by combat | IDLE |
stop the attack output; health unchanged | remain IDLE; do not invent a target |
CHASE |
target in range and attack available | ATTACK |
request an attack | if combat rejects the request, health is unchanged and the rejection row applies |
CHASE |
target unseen for the loss interval | SEARCH |
request movement toward last known position | if that position is invalid, enter RETURN |
CHASE |
pursuit boundary reached | RETURN |
request movement toward the assigned area | if movement fails, stop and expose the failure |
CHASE |
movement request fails | RETURN |
stop chase movement; expose the failure | no unlimited silent retry |
ATTACK |
attack completes, cooldown remaining > 0, target still valid and in range | ATTACK |
keep attack selected; request no new attack until cooldown reaches 0 | combat remains authoritative for health |
ATTACK |
attack completes, cooldown remaining = 0, target still valid and in range | ATTACK |
request next attack | combat remains authoritative for health |
ATTACK |
target remains valid but leaves attack range | CHASE |
request movement toward the target | do not keep an attack output after range-exit |
ATTACK |
attack request rejected by combat | CHASE |
cancel attack output; health unchanged | this is the rejection route; do not apply unvalidated damage |
ATTACK |
target becomes invalid | SEARCH |
stop attack output | do not invent a target |
SEARCH |
target reacquired | CHASE |
request movement toward the target | — |
SEARCH |
search duration expires | RETURN |
request movement toward the assigned area | — |
SEARCH |
last known position invalid | RETURN |
stop search movement | enter RETURN immediately |
RETURN |
assigned area reached and no valid target | IDLE |
wait or request patrol | — |
RETURN |
permitted target detected | CHASE |
request movement toward the target | — |
RETURN |
movement fails | IDLE |
stop at a safe location; expose the failure | do not invent a path |
Every permitted edge and every declared failure route must appear as a row. "Follow the specified rejection transition" is not a row.
593. Decision responsibility and authoritative resolution
The enemy decision controller may select ATTACK and emit an attack request. It has then selected a behavior and produced an output. It has not necessarily resolved damage.
The authoritative combat system must still validate the request according to the applicable combat rules before changing health. Likewise, an animation may present an attack without determining whether damage occurred.
For this lesson, identify these responsibilities at the contract level:
- the decision controller selects the behavioral state;
- movement, combat, and presentation requests are outputs;
- the system responsible for a consequence validates and resolves that consequence.
Detailed subsystem boundary diagrams and transition acceptance criteria belong to the next lesson.
594. Failure behavior
Failure behavior belongs in the contract rather than in an unwritten implementation assumption. Define what happens when:
- the target reference is missing or invalid;
- a movement request fails;
- an attack request is rejected;
- the target remains unseen beyond the loss interval;
- the pursuit boundary is reached.
A fallback must preserve valid game state. A rejected attack leaves health unchanged. A movement failure should not cause unlimited silent retries. A missing target should lead to a declared state or fallback rather than an invented target.
For every failure case, ask:
- In which state can this failure occur?
- How is the failure observed?
- What output stops or changes?
- Which state or declared fallback comes next?
If the contract cannot answer “what happens next?”, it is incomplete.
595. Common mistakes
Treating states as animation names
ATTACK_ANIMATION describes presentation, not why an attack is permitted, which component requested it, or what happens when the request is rejected.
Using intentions as guards
“When the enemy feels threatened” is not inspectable. Rewrite it using observable facts such as a detected event, a distance, a timer, or a declared threshold.
Omitting the graph
A table can appear complete while hiding an unreachable state, a missing failure route, or a state with no exit. Compare the table and graph edge by edge.
Letting an output imply a consequence
“Request attack” is an output. “Reduce target health” is an authoritative combat consequence. They are not interchangeable.
Using responsibility and authority as synonyms
A component can be responsible for selecting ATTACK without being authoritative for health changes. State selection and consequence resolution are separate claims.
596. Guided practice
Specify a small enemy that:
- begins without a target;
- detects a player at a defined distance;
- approaches but attacks only inside a defined range;
- loses the player after a defined unseen duration;
- stops pursuing at a defined boundary.
First, complete a state contract table with at least four states and the six columns used in this lesson.
Second, draw the matching directed graph or supply a labeled directed edge list. Include every table state, mark the initial state, and label every edge with a measurable guard.
Third, annotate one state, one transition condition, and one output.
Finally, decide whether losing the target leads to SEARCH, RETURN, or IDLE. Justify the choice using the intended encounter behavior, and include the selected route in both artifacts.
597. Validation and evidence
Submit the table and graph through the attached practical assessment. The artifacts are ready for review when:
- the table contains at least four named states with distinct observable outputs;
- the graph contains the same states and marks the initial state;
- every transition uses a measurable guard;
- every documented transition appears in the graph;
- every graph edge has a corresponding transition-table row;
- one component is identified as responsible for state selection;
- attack selection remains separate from authoritative combat resolution;
- missing target, movement failure, rejected attack, lost target, and pursuit-boundary cases have declared routes;
- at least one state, transition condition, and output are correctly labeled.
A reviewer should be able to begin at the initial node, trace every listed normal and failure case, and answer “what happens next?” without inventing a missing rule.
598. Key takeaways
- Replace “smarter AI” with observable states, transitions, and outputs.
- A state contract defines entry, output, exit, decision responsibility, and failure behavior.
- The table specifies state contracts; the graph reveals permitted routes and missing edges.
- Responsibility for selecting
ATTACKdoes not grant authority to resolve damage. - Every important failure needs a deliberate route or fallback.
599. Next lesson
Next: 2.2 L2 — Separate deciding from doing.
600. Knowledge check
Answer these items for yourself before reading the answers.
A contract says: “While in CHASE, request movement toward the target. When target distance is at or below attack range and the attack is available, enter ATTACK.” Which classifications are correct?
Show answer and feedback
Answer: CHASE is the current state.; Requesting movement is an output.; Target in range plus attack available is the transition condition.
Why: CHASE is the current state, movement is the output, and the observable range and availability facts form the guard. ATTACK is a next state, not a resolved damage consequence.
Which proposed CHASE → SEARCH guard is sufficiently measurable for the contract?
Show answer and feedback
Answer: The valid target has remained unseen for the declared loss interval.
Why: A declared unseen interval can be observed and tested. The other options rely on vague judgment or presentation.
The enemy decision controller selects ATTACK and emits an attack request, but the combat system rejects it. Which contract interpretation is correct?
Show answer and feedback
Answer: Health remains unchanged, and the state contract follows its declared rejection route.
Why: The controller is responsible for state selection, while the authoritative combat system validates and resolves combat consequences. Rejection therefore leaves health unchanged and invokes a declared fallback or transition.
A table documents SEARCH → RETURN when the search interval expires, but the graph has no such edge. What must be concluded?
Show answer and feedback
Answer: The artifacts describe different transition sets.; The failure route cannot be traced completely in the graph.
Why: The table and graph must specify the same machine. An omitted edge creates an artifact mismatch and prevents the documented route from being traced in the graph.
While in CHASE, movement fails and the contract contains no fallback or outgoing transition for that failure. What is the best assessment?
Show answer and feedback
Answer: The contract is incomplete because it does not define what happens next after an observable failure.
Why: The movement subsystem may resolve the request, but the state contract still needs deliberate behavior for the reported failure. Without a next state or fallback, the behavioral specification is incomplete.