For the last project of the first year and the last project to use the school's in-house engine Tga2D I decided that I wanted to deep-dive into designing the enemies and their AI since that was an area I had not touched on much before.  

  • Engine: TGA2D (Schools in-house 2D C++ engine)

  • Genre: Top down action exploration game

  • Time: 7 weeks half time

Improvements of animation system

With more animations required due to the player needing multiple sets of animations for the different orientations as well as the linking of animations to a more advanced combat system I felt that I needed to polish up the animation system I had originally made for project 3. 

Among the things added was the ability to bind functions that would be called on a specific frame of the animation and the ability to set the time of individual frames instead of a general frame rate. 

The tool for the enemies let you interface with the new animation features such as frame specific times and the ability to call a callback on a specific frame (to activate the attack colliders).

Complete with a preview of the animation

Node graph for pathfinding

Being a 2D-game, we did not implement a navmesh for the navigation of enemies, instead I designed a system for node graphs to be used instead. These graphs were created by hand in our level editor, Tiled, by placing out polyshapes/polylines around the level where any overlapping points would still be handled as a single point when parsed into the game. I then used A* for the pathfinding using this Node graph. 

Enemy AI

I spent most of the project working on the enemies and worked closely with the level designers to make them feel as good as possible.  

The general structure for the AI was handled by a state machine system 

One of the tricky parts was to make the enemies interact with/be stopped by terrain in a believable way, especially when they performed attacks that caused them to move in a straight line, I solved it by using raycasts to determine if the enemy is up against a wall and then “deflecting” the movement away alongside the wall while keeping the original speed. 

To reduce the frustration of enemies constantly chasing the player I made it possible to assign a certain area in Tiled that an enemy should be restricted to and they would then ignore the player if they stayed outside that area and stop chasing them if they ran out of it. This also made the enemies feel a bit more alive since the player was no longer the one and only thing they cared about, it felt like they were more defensive of their territory.

I also created an in-depth tool to customize and tweak the different enemies. It included a lot of simple values related to general stats and state-switching conditions but also a more complex section related to the attacks. You could tweak the duration of all the animations to make them feel just right, with a little preview window as well, and you could also set which frames the attack colliders would be enabled and disabled.