Whether you like it or not, life, the universe, you, and your loved ones can be quantified into a very large series of 0’s and 1’s, on’s and off’s, true’s and false’s. This may sound bleak and a bit nihilistic, but I actually think it is quite beautiful. Sometimes, I’ll walk down to the river and look at something–some thing or some system of things–and think about what “if-then” statements make that thing operate how it does. The same analysis can be applied to creating compelling and seemingly human artificial intelligence in video games.
To put into context where this is going, I am working on a local-multiplayer side scrolling deathmatch game called ChargeShot. We recently both got ChargeShot greenlit on Steam and showcased it at the Indiecade @ E3 booth last week. The response was overwhelmingly positive, but the question kept coming up: Is there going to be single player? ChargeShot was designed around the fact that it would be local-mulitplayer only, but I simply cannot conjure up a viable reason to deny those who buy the game the ability to at least try it out if they bought it with no friends around.
So I started making bots. At first, the idea scared me. I’ve hardly done AI. What if the bots are clunky and weird? What if they are too stupid or two smart? What if the single player is so bad that it brings down the entire perceived quality of a primarily multiplayer-centric game?
But I got to work, and within a day, came up with something I was proud of. ChargeShot is a very human game. The controls are very weighty; simple, but difficult to master. Really good players can lose a round through an unperceived threat or a simple mistake. I came up with a method to create something that feels as though it is being controlled by a real world human being. Basically, the process goes like this:
- Make a huge list of every instant that a human player would press a button.
- Categorize these by the goal of pressing the button (in example, press “Up”, “Left”, and “Right” to pursue another player).
- Feed the AI these goals and make them push buttons on a virtual controller rather than behaving on a contrived pattern.
In my case, I calculate a path from the bot to the bot’s target, which is a dynamic reference that changes based on a few rules. Which potential target is closer? Is a player close to winning or does he pose a great threat? Then, rather than simply moving the bot along the path to the target, I have it input buttons to reach the next cell on the path to the target. Because the game has a lot of weight and acceleration, sometimes this destination is overshot, and in real time the path updates. On top of that, the target may be moving, so the path has to adjust for that, too. This creates a relatively nice navigation system. The AI behaves perfectly imperfect to reach its goal, much like a human player would. But that’s only navigating. What about competing? ChargeShot is a game about shooting and reflecting bullets with a momentary shield. After input is pressed, a separate set of rules with the goal of killing one another and staying alive are fed to the brain of the bot.
Q: When does a human player press the shoot button?
A: When there is another player in his line of sight and nothing obstructing the shot.
Q: When does a human player press the shield button?
A: Either when he recognizes a bullet coming his way, or when he is on top of another player (in order to “bump” the player away).
The shots in ChargeShot have an immense amount of kickback, so doing this alters the path to the target. The shield temporarily disables the jetpack, causing the player to lose upward velocity, which causes the path to change. Being “shield bumped” sends you flying across the screen, which, again, adds dynamics to the positions of both the bot and the target pathfinding destination. Finally, so that the bots aren’t perfect in their reactions, a reaction time variable is used to determine how quickly they make decisions. Rather than have this be a fixed time, to make things a bit more interesting, I use a percentage. A perfect bot reacts exactly at the times that stimuli are processed. A high-functioning bot has a 80% chance per frame (at 60 fps) to react to the stimulus. A low-functioning bot may have a 40% chance per frame to process the stimulus. What this does is make it so that if you pin 2 bots with the same reaction time together, they won’t behave identically. They have a much higher chance of reacting in time, therefore, statistically, they will react in time. People may argue the whole RNG is bad thing, but this is actually how human reaction time works too. You don’t always, every time, react at 20ms delay. Not even pro players.
(Below: what happens if two bots have identical reaction times)
The “still left to do” list includes stacking rules on top of rules. Finding more of those “When do players do ‘x'” things and applying them. Avoid level hazards, when the wind picks up on a particular left, press in the opposite direction to fight it, never try to navigate through lava, etc.
In conclusion, convincing AI isn’t to difficult if you are willing and able to take the time to think about the rules by which human beings operate a video game. AI that is supposed to represent human play is not objective, it is very very subjective. Regardless of how much to win, you know that in order to win you have to do this at that time. Bot AI should reflect that, not a murderous desire to hunt down the player. Virtual Controllers bro, get on it.