E.T. Returns Postmortem(ish) Part 3: Attack Patterns


If you haven't read them yet, I recommend first checking out Part 1 and Part 2 of my E.T. Returns Postmortem(ish).

ENEMY ATTACK PATTERNS
E.T. Returns is a horde shooter where dozens of enemies simultaneously pursue the titular character.  When building the game, I wanted enemies to flock together into a massive horde that pursued the player while also having enough variability to make the game both challenging and fun.  To do so, I used a variety of steering behaviors that control enemy movement and attack patterns.  Steering behaviors are simply movement patterns that are applied to game characters to achieve some goal.  In this article I will review some of the core steering behaviors used in E.T. Returns and talk about a few things that could have been improved to get slightly better gameplay.

SEEK
The primary goal of all of the enemies in E.T. Returns is to damage and kill the player (in the this case the player is E.T.).   Enemies do not have projectile attacks so instead enemies must collide with the player to cause damage.  Seek is the primary steering behavior used by a majority of enemies to achieve this goal.  When using the seek steering behavior, enemies move directly towards the player in a straight line using a simple vector calculation.

enemyMovement = (playerTransform.localPosition - this.transform.localPosition).normalized * moveSpeed;

We take the difference between the enemy position and the player position, normalize it, and then multiply by a moveSpeed.  This is one of the simplest steering behaviors that is seen over and over in thousands of games.  

SEEK WITH OFFSET (SURROUND)
Seek with offset (or “surround” as I call it internally) is similar to seek, but instead of targeting the player position, enemies target a position that is offset from the player.  An enemy might target a position in front of the player, behind the player, above the player, etc.  This is similar to what the pink ghost does in Pac-Man.  Instead of targeting Pac-Man, the pink ghost targets a position that is 4 squares in front of Pac-Man.  This sort of steering behavior results in enemies that appear to cut the player off and block the player’s escape.

RANDOM ANGLE SEEK
Random angle seek is a seek variation where instead of moving in a straight line towards the player, the enemy moves towards the player in a more jagged, less predictable pattern.  To achieve this, I compute the movement vector from the enemy toward the player and offset it by a random angle.  

enemyMovement = (playerTransform.localPosition - this.transform.localPosition).normalized * moveSpeed * Quaternion.Euler(0, 0, Random.Range (-50f, 50f));

This results in enemies moving towards the player in a more chaotic, unpredictable pattern.

FIXED ANGLE SEEK
Fixed angle seek is similar to random angle seek, but instead of using a randomized angle, a constant angle is used.  

enemyMovement = (playerTransform.localPosition - this.transform.localPosition).normalized * moveSpeed * Quaternion.Euler(0, 0, 50f);

This results in the enemy moving in an enclosing circular pattern around the player.

SIGHT
Most enemies use a sight distance to determine when to switch between different steering behaviors.  A distance is computed from the player to the enemy.  If the distance is GREATER than the sight distance, then the enemy cannot “see” the player and the enemy does not change behaviors.  If the distance between the enemy and the player is LESS than the sight distance, then the enemy can see the player and may shift to a different steering behavior.  For example, a surround enemy might switch to seek when they get close enough to the player using this sight distance calculation.

PATROL
Related to the sight distance, some enemies use a patrol behavior.  The gameplay field is divided into 4 quadrants.  Enemies move towards the center of the quadrant and remain there (patrolling the quadrant).  Once the player enters the quadrant, the enemies switch to a seek pattern and pursue the player.  This is really just a variation on the sight distance calculation used by other enemies.  However, patrolling enemies result in mini-hordes that accumulate in each quadrant which causes an extra degree of stress for the player when moving about the playfield.


SPREAD
When a large number of enemies all use a seek steering behavior, enemies quickly clump together into a large mass.  On one hand, this is mostly what I wanted in E.T. Returns.  On the other hand, too much clumping makes it easy to shepherd the enemies into one large group that the player can avoid more easily.  To reduce clumping, I implemented a spread steering behavior.  Spread allows enemies at the edges of the clump to move away from the clump and find an alternate path to the player.  To implement spread, a circular raycast is performed from each enemy position.  The raycast is used to determine how many other enemies are in the adjacent area defined by a circle with radius x.  If we find 2 or more enemies in the adjacent area, then we assume that the enemy is part of a clump and needs to use a spread steering behavior to move away from the clump.  To determine the movement direction, we sum the vectors in the direction of each adjacent enemy and then move in the opposite direction of the sum if we are above some threshold.  This simple vector sum allows us to determine if the enemy is in the middle of the clump and should NOT try to spread (the vectors will mostly cancel out when summed and not hit our threshold) or if the enemy is on the edge of the clump and should spread (the vector sum will be large enough to indicate that we should move away from that direction).  This works well in practice as enemies on the edge of the clump will consistently break away and move in a different direction.  

OTHER ATTACK PATTERNS
I use additional steering behaviors and attack patterns to implement unique attack or movement patterns.  FBI agents and scientists move towards locations located in 45 degree increments from E.T. - essentially trying to avoid the player.  River Raid planes and Moon Patrol rovers move in the straight horizontal lines across the screen.  Dig Dugs form in a circle around the player, wait, and then use a seek behavior.  These patterns add variety to the game and make it harder for the player to avoid and attack the horde as they must also navigate other enemy attack patterns. 

IMPROVEMENTS
For the short amount of time I took to build E.T. Returns, I’m quite happy with the enemy attack patterns.  There are, however, a few things that I think could be improved.

  1. Better handling of spread.  The spread steering behavior helps break up the horde and make enemy movement less predictable, but it’s not always clear how long an enemy should spread, if the enemy should immediately return to seek, or how this should be balanced with other enemies who are also spreading.  For example, I could have set an upper bound on how many enemies can simultaneously spread to maintain the integrity of the horde.
  2. Better handling of enemies hitting one another.  At present two enemies can run directly into one another and get stuck.  This typically resolves itself as E.T. moves around and the enemy target location changes.  However, when enemies collide and get stuck it makes the AI seem clunky and dim-witted.  A simple check for collision with another enemy could have been used to reroute stuck enemies.
  3. Better wall handling.  The walls of combat tanks both limit and control the playfield boundaries.  Enemies check for the tank walls and move away from them when they hit them.  However, I could have added another calculation here to make the movement appear more natural.  Similar to the sight distance used with the player, a sight distance could be implemented for the walls allowing enemies to detect an approaching wall and move in another direction (rather than blindly slamming into them and THEN reacting).  This would make the enemy AI seem more real-world and intelligent.

For the most part the enemy attack patterns do exactly what I was hoping for: a huge horde of enemies swarm the player with enough variation to keep the game interesting.  There are, however, places where the behaviors could be tweaked to attain a more realistic enemy AI.  In part 4 I’ll talk about balancing the game difficulty.  Onward!

TL;DR: Steering behaviors are used to control enemy movement with seek and seek variations being the key to the enemy attack patterns.  Spread is used to reduce the density of the horde.  I got the result I was looking for, but there is room for improvement with enemy-enemy and enemy-wall collisions.

Get E.T. Returns

Leave a comment

Log in with itch.io to leave a comment.