
Little Timmy's Hide & Seek Spooktacular: Enemy AI

Little Timmy sports several types of enemy, powered by the same behavioral state machine architecture. They're passive by default, but grow more aggressive as they detect the player. The machine offers a high degree of customization in the inspector, allowing for granular variations in NPC behavior without the need to touch any code. Eight states are supported.

Patrolling State

-
NPCs travel along designer-specified lists of waypoints
-
It's possible for NPCs to collide and 'lock horns' while patrolling
-
To resolve collisions, one is randomly selected to give up and let the other pass
-
-
If the player is briefly seen, the NPC will turn as if glancing at them, without transitioning to another state
-
If the player is seen for long enough, the NPC transitions into the noise state, investigating the player's last known location
Noise State

-
NPCs move toward the last known position of the player
-
If the investigation point is inaccessible, the NPC will move toward the nearest accessible position
-
Last known position is updated whenever the player is seen
-
If the player is seen for long enough, this transitions into the chasing state
-
If the player isn't found before the target is reached, it transitions into the suspicious state
Suspicious State

-
NPCs look around the last known position of the player
-
When the last known location of the player is reached, positions near it are semi-randomly selected to be searched
-
Investigation begins near the last seen position and gradually moves outward
-
The result is an unpredictable pattern of movement within an area near the player, possibly finding them hiding
-
If the NPC spends long enough in this state without finding the player, it will revert to its default state (usually patrol or idle)
-
If the player is seen, it immediately transitions into the noise state with the player's current location as the search point
Chasing State

-
NPCs run toward the player
-
Player location is always known in this state
-
If the player stays out of the NPC's FOV for long enough, it will revert to the noise state, moving to the player's last known location
-
If the player is caught, they take damage, and the NPC is rendered unconscious for a few moments so they can get away
-
If the player respawns or enters a closet, all NPCs in the chase state will immediately revert to suspicious
Unconscious State

-
NPCs are harmless, unable to see, move, or hurt the player
-
An NPC enters the unconscious state when they damage the player on contact
-
When an NPC wakes up after a few seconds, it will enter the suspicious state and investigate the area around it
Idle State

-
NPCs can see and hurt the player, but stand still in particular positions facing particular directions
-
If an idle NPC isn't in its specified position / rotation, it will move and rotate accordingly
-
If an idle NPC sees the player for long enough, it will enter the noise state and move toward their last known position
Paranoid State (Disabled)

-
NPCs move in an erratic but internally consistent pattern
-
When half of the enemies on a given level have died, the remaining half have their default state replaced with paranoid, and all transition times are halved
- If the player is seen long enough in this state, the NPC will transition to noise and move to their last known position
- This state and its associated system are currently disabled. While it was functional, I felt that it added too much randomness and discouraged strategic thinking from the player
Frozen State (Debugging)

-
NPCs are frozen in whatever state / action they were last performing
-
State and physics information is stored and loaded to ensure no disruption to NPC behavior while frozen
-
Can be applied selectively different NPCs
-
Helpful for reducing enemy interference when testing