Blog 4 (11/5-11/19) - Systems, Behaviors, and Bugfixes

Introduction

As the name suggests, these past two weeks had me working on new systems, new AI behaviors, and some bugfixes as well. Let's dive into it!

Meetings (4 hours)

Two meetings. Two hours each. You know the drill.

Finishing the AI Tile System (5 hours)

Last week, I teased that I was working on a new system that would allow the AI to evaluate the state of the board to find the best positions to place its units. These last two weeks gave me the chance to finish them!

The system works by iterating through each tile on the map and calculating information about those tiles. The system will account for nearby objectives, nearby enemies, and how dangerous a tile is. Once these values are calculated for each tile, the actual tile score is dependant on the unit which is evaluating that position. For example, units that prioritize objectives are more likely to move towards tiles near objectives. Units with low health, will avoid dangerous tiles.

To help me debug, I also created a nifty editor tool which takes a unit type and health as input. The tool will then highlight tiles on the map based on how units score that tile, with red squares being more valuable and blue squares being less valuable. Hopefully, this tool will give designers a better understanding of how the AI is making its decisions so we can make it as smart as possible.

One downside of the system is that it is rather computationally expensive. I will have to make improvements to make it more efficient in the coming weeks.

Archmage Teleport Behavior (6 hours)

The largest task I had this week was working on a behavior so the AI could use the Archmage's special ability. Unlike the other two specials, the Archmage's behavior cannot easily be created using other behaviors. Instead, I had to create two brand new behaviors.

Since this was a rather complex task, I had to break it down into smaller, more digestible chunks. The AI first needed to move the Archmage near two ally units. The Archmage then needed to pick a valid square to teleport to once it was adjacent to enough allies. Finally, the Archmage would have to teleport itself and adjacent allies to the square it deems best.

Once I understood what I needed to do, the problem became much more approachable. I began with the question of how the AI should pick the square to teleport to. Thankfully, since I had already been working on the tile weighting system, this was pretty easy to implement. The Archmage would pick tiles near objectives and enemies.

I next worked on the mechanics of executing the behavior. To do this, I tracked the list of adjacent allies in an array along with the directions they were from the Archmage. Once I had this data structure set up, implementing it was as easy as moving each unit alongwith the Archmage.

Lastly, I created a simple behavior that would check for nearby allies that were grouped up. If the Archmage could move near them, it would. This video shows the results from my work!

Healing, Key Locations, and Artifacts (3 hours)

I had some other smaller AI behaviors assigned to me as well. One was a behavior that would allow the AI to move its units to its cities when they are low on health. This strategy was pretty simple to implement, requiring me to check if a unit's health is below a certain threshold. The lower a unit's health, the more likely it is to retreat to a city to heal. I also had to make the AI consider key locations and artifacts in its strategies. Since key locations and artifacts behave similar to cities, I chose to create a new data structure called a AICapturable state. This base structure would contain the tile a capturable belongs to, a list of nearby allies, and a list of nearby enemies. I then created children of this data structure for each type of capturable (cities, key locations, and artifacts). Once this structure had been created, scoring for behaviors could be reused across different types of capturables.

AI Movement Bugfix (1 hour)

The last thing I worked on this week was a bugfix that had been haunting the AI for some time. Basically, units would sometimes ignore their movement limitations and hilariously treck across the entire map in a single move.

This behavior was curious since the AI was supposed to find the best intermediate for a square if the AI could not reach its target tile in one turn. While diving into the code in the debugger, I found that the intermediate tile was not being properly set, causing the AI to still move to its goal destination even if it was outside a unit's move range.

The incorrect movement behavior. Look at those units go!

The correct movement behavior.

Conclusion

I spent a total of 19 hours this week. I am looking forward to finishing out the project and the semester in the coming weeks!