The past couple of weeks have been extremely busy and arduous, to say the least. As I’m rebuilding Legend Bowl from the ground up, I’ve set a priority on gameplay and building a robust artificial intellligence (AI) engine as its foundation.
Let’s talk about AI and what it means to a video game as complicated as sports and a sport such as football to be exact. There are various concepts out there when it comes to AI in games, but the one that stands out the most is a concept called “Steering Behaviors” developed by a fellow named Craig Reynolds. Just google it and you’ll find thousands of interesting articles and videos describing these concepts and how much power they can have on your game while eliminating much of the overhead used in complex AI systems.
Seek and Flee
Pursue and Evade
My previous build of Legend Bowl included these steering behaviors as the core movement system throughout the entire engine. As I moved further into the development of the game, I began to notice weird behaviors coming from my agents. For example, there would be oscillation when a player was flipping back and forth while deciding on what direction to move in next.
Crowd Path Following
Another issue was related to the positioning of players and many times players would get locked up when trying to move to a location as other players were blocking their path. There were several other issues I won’t bore you with in this blog, but needless to say the AI system just wasn’t organic and cleanly enough for a complicated sport such as football and I knew I needed something better to take its place.
My “Home Grown” AI System
My intial approach was to try and build my own “home grown” AI system for a ball returner to see if that would be any better. You can see that in the image below where I was creating a rectangle that turned at the same angle the player was turning and then would check for collisions to avoid tacklers.
Then I moved on from making my own custom rectangle/box collision system using vectors and points to something a member of the GMS2 community created for these types of wide-range collisions. This was great because you could easily change the dimensions of the rectangle collision object to your liking and anything that would collide to it would be detected without needing to code up a sophisticated system to detect all of these collisions.
The overhead of creating “raycast” lasers to check every point would bring any game to a crawl and this seemed like a creative solution to try out in Legend Bowl.
Even though this was an improvement from both a performance perspective, but also was robust enough to use everywhere it still seemed like I needed more.
Context Map Behaviors
Fast forwarded 6 plus months later and now being back on Legend Bowl I began to research how to fix some of the AI issues I was experiencing. As I was looking through articles, I ran into a concept I once heard of while researching Steering Behaviors called, “Context Map” behaviors which seemed to simplify the process and think of decision-making AI as something less complicated, but gave the power and organic nature of a real human decision making system.
All of this research lead me to a man by the name of Andrew Fray, who’s an AI engineer on several AAA game titles, but notaby for F1 racing. I believe he came up with this AI concept and shows how powerful it can be when used for agents making decisions in a crowded space where steering behaviors could not cut it. He has some articles explaining Context Behaviors on his website if you wish to read in more detail and also did a GDC presentation in 2013 about AI and goes in depth on the system.
The concept just blew my mind and made it crystal clear that this was the choice for Legend Bowl’s AI system. So without much hesitation, I began the process of building a prototype of the AI using Game Maker Studio 2.
Let’s just say I had MANY questions on how to accomplish his simple, yet very complex theory. One question was how to determine the number of “antennas” as I like to call them would serve my game. Another was how the hell to code this and make it morph into what I need. So I rolled up my sleeves and began typing away, while researching more on the topic and getting as familiar with it as I possible could. I quickly began to put things together and found another article by James Keats who did this for a school project. This is where I could test the AI out using his demo to get a feel for what I could build in GMS2… that’s why they look so familiar!
Even though I had something I could tinker around with and play, it still wasn’t enough to show me how to “code” it into my engine. He didn’t share much code and there were still many gray areas I was missing. Long story short, I pounded my way through it and finished my first prototype somehow.
Legend Bowl AI Prototype
My plan to develop a prototype was to start up a clean empty GameMaker Studio 2 project and build the context behavior AI for a ball carrier. I started out with building the lists to hold the various danger and interest spots for each player. Then I moved on into building the script to evaluate the closest danger players in 8 directions and rank them in some sort of weighted scale.
The next step was to grab the closest interest object and move away from the most prominent danger directions to come up with a final direction to pursue. This was all hardcoded to 8 directions and after several attempts and tweaking I was able to get something that started to look like a football player running with the ball, while avoiding tacklers!
Early prototypes below illustrate the player arrow moving towards the green interest objects and trying to avoid the red danger objects.
The next steps were to tune and tweak the logic so the player could see further and adjust to danger in a more realistic fashion. I also began adding more realistic danger objects to see if the player could sift through the field without getting touched by defenders.
The final step in the prototype was to refactor it so I coudl dynamically adjust the number of directions for testing when I ported it over into Legend Bowl. It took me a full day or so, but I was able to reduce the number of lines of code by 70% while adding a much more dynamic system that could expand and collapse to whatever number of directions needed for testing.
Increasing the number of “antennas” as I like to call them really didn’t always make for much of an improvement and in some cases made the players try to “squeeze” through too small of holes, instead of going around the crowd of defenders. Although it was nice to have the option of allowing less or more paths for the player to take depending on the situation.
In summary, Context Map Behaviors started to feel like the obvious choice based on my prototypes. I was really happy with the results, but wasn’t sure how well they would translate into the actual game.
In the next blog post, I’ll share how all of this prototyping and testing made its way into Legend Bowl. Thanks for reading and stay tuned for more news and information in the coming weeks!
Download the demo: Context Behaviors Demo
Be sure to join the Discord server for the latest!