Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

"LIVE!" - Luke Cardelli | 26 October 2023

The Problem:

This week, I decided to add in an Enemy Healer to my rouge’s gallery of enemy variants. This enemy type would essentially be a derivative of the ranged enemy type. Instead of firing arrows or lethal magical spells, the healer would instead heal enemies as their health hit below a certain threshold. Going into implementing this functionality, I had determined the method that made the most sense would be to loop through all the enemies and store them in an array. This function would later be called in a behavior tree node in order to dynamically update the list every few seconds to account for the enemies who were slain.

I wanted to ensure that the healer was unable to heal themselves as I found this to be too extreme for what I was trying to do. As a result, I put an if check to see whether or the not the array element was the caller. If so, then ignore them. Once the array was made, I then called a second function that would handle the healing functionality. Issues began to arise when I noticed the healer refused to move from their starting location, giving off the impression that their behavior tree had broken. Upon further review, I discovered that in fact the healer was getting stuck in heal function and therefor not meeting the criteria to call the event dispatcher, ending the behavior tree node task.

After some tinkering, I had discovered that the if check was reversed, only storing the healer vice the other enemy types. Once I fixed this a new issue arose wherein the healer would be stuck the first time it would loop through the list of enemies, not completing the criteria needed for the behavior tree to move onto the next task. After several hours of work and collaboration, I had created a healer that needed to get hit initially in order to ‘wake him up’ before they would start healing injured enemies.




<Reference Images of the original implementation>

 

The Solution:

Agnostic to my efforts, I had determined after several iterations that making an array of enemies was causing more issues then desired. As a result, I decided to forgo the use of an array and instead opted to use a for each loop, breaking out of the loop only after finding an enemy whose health was below the threshold.

Instead of doing an if check to see whether the looping element was the caller, I instead used a ‘cast to healer’ check instead. I found when debugging, the if check doesn’t work when there are multiple healers in the environment as the caller will ignore themselves, but they will then store the other healers. Using a cast appears to work better. Naturally, when the cast fails, I then check to see if the enemies health is below the threshold, if it is, then call the heal function.


<Reference Image of current implementation>

The last change I made was to the behavior tree. I added a cool down to the task node that calls these functions so that the healer can heal enemies at a pace that prevents the player from spamming the attack on a single enemy. In the current implementation, if the player were to spam attack a single enemy, the healer is able to heal at a pace greater than what the player is able to deal, pending the player doesn’t have any buffs. This is intentional as I want to force the player to prioritize the healer vice the other enemies as a means to introduce additional layers of complexity to the combat system.


<Reference Image of the Behavior Tree that handles the logic>


<Reference Image of the healer healing an enemy mid game>


Support this post

Did you like this post? Tell us

Leave a comment

Log in with your itch.io account to leave a comment.