SIEGE

This is a melee focused game in 3rd person that comprises of game modes such as Team Death Match, Conquest and Siege modes wherein you hold off an attacker for a certain time to win.

The enemy AI in this game built from the ground up, I did not opt to use the systems supplied by Unreal Engine such as EQS, and behavior tree, and opted to use my own, building a new system from the ground up, as I had a target amount of characters in an arena and wanted to streamline certain features to save performance

SPLIT SCREEN IMPLEMENTATION

I created a new controller class that would be independent of any player character. In doing this, the controller is able to possess different types of character Classes while maintaining its original variables from a game mode and It’s begin play events. 

I also created a dynamic spawn system based on the options in the main options menu this was easily simplified as there are mainly only four different scenarios. Since most game modes comprise of A skirmish between two factions so there were only four scenarios,

  • Scenario one – Player is Templar faction play in single player

  • Scenario two – Player is Saracen faction play in single player

  • Scenario 3 player is Templar play in split screen

  • Scenario 4 player is Saracen play in split screen

Given that there are really only four scenarios an enumerator variable was a more convenient and stable option and based on this variable, the code for the spawn system can vary.

In order to decide spawn location, I created a unique actor class with a tagging id. In begin play,, once the spawn occurs, The spawned character looks for this unique actor class that matches its ID then saves that ID ‘s world location and moves to that location. This allows me to iterate this system in different maps without having to do complex code for every level and simply place an actor with a specific id

Additional Properties

Conquest Mode

For the Team Deathmatch mode, no dynamic spawn swapping system is necessary since areas don’t need to be won over, but implemented an interface based system for enemies to reset and re-pool to it’s initial spawn point after a cooldown time for them to respawn in the level. While the enemy dies, it also communicates to the game mode that increments an integer value to indicate a score, in this game, each team is capped to a score of 50, the team who first reaches 50 kills wins.

ENEMY AI LOOP

For the Conquest based game mode, on top of the dynamic spawn system, dynamically moving them was necessary since modes like this require the player or enemy to lose it’s current area and defer to remaining uncaptured areas,

However, since the number of capturable points in a level are constant then this allowed me to base the conquest mode’s code around the number of points, I implemented this system for all perspective areas to add into either the Saracen or Templar’s options via an array depending on what they are assigned on the level instance. Here was the step by step implementation

- Implementation of Spawners for npcs to trigger in begin play
- Implementation to spawn players in respective location
- Implementation of code for all conquest points to declare their faction in begin play
- Game mode class saves stored conquest points in an array for each of the two factions.
- Delay Character spawn fires for all actors; whilst the player characters get to choose
the spawn via menu, now having an option bool from it’s game mode’s variable.
- Implemented a function to WIN OVER points and remove from it’s current array to swap over to the other faction.
- Implemented a point system for most conquest points, once the integer value reaches 5, which is incremented every time a conquest point is won, then the faction who reached 5 first wins.

Team Deathmatch Mode

For Enemy AI, there is only one necessary state since it is an arena or skirmish game,
Idling, Unaggressive, Searching modes were unnecessary, this greatly trimmed down any
possible code bloat that could occur, allowing for more characters on screen.

Only one phase was needed and only one loop to worry about, which is to transverse on assigned points on the map, but once the detection timer sensed the closest enemy actor returning a hit in it’s trace, then it prioritizes and heads over to the detected target actor.

Implementation of combat is very standard, centered around a focus point actor, which is the detected target actor of it’s initial collision trace. Once the actor variable returns valid, a combat logic timer triggers and pauses all detection functions,

Each actor has their assigned range threshold and while moving around the target, when the range is lesser or equal to the assigned range, then attacks either melee or range are performed,

I implemented a chance based system for all the AI, to easily iterate based on scaling, so stronger enemies can have more head on chances while weaker enemies have higher flanking chances.

This also allowed me to implement a dynamic difficulty system because of the chance based system to increase or decrease directness frequency based on the setting.

For Blocking and AI Dodging chances, I implemented a trace system called per annotation interface. Attack animations have a “signal annotation” which sends a collision sphere to enemy targets in the near range, again, using a chance based system, this allows AI to react or not based on the assigned block or dodge frequency. This allowed me to increase range regarding competent enemy anticipation or fodder based opponents and easily iterate difficulty assignment.