Otakon 2017 and Play NYC are both right around the corner, and we’ve been busy over the past few months improving Modern Knights and Dani AI based on the current testing feedback. In the meantime, we’ve found the time to post about jump into the thought process of creating reusable AI.
The Scale is to Understand the Issue
As mentioned in the previous post, there are times when a non-player character (or NPC) needs to be less robotic and do more than “if A is true, then do B”. What we mean by that statement is that given many different scenarios that the NPC will encounter, it is relatively difficult to define the conditions for each scenario. Additionally, it would be harder to scale up and try out new ideas for the character.
For our knights, we’ve had this dilemma with the interaction between the knight and the player. The knight is an NPC with its own set of decisions. The player is well, a character in the game controlled by a complex system of cells using a physical interface known as a mouse, keyboard, and screen. Simply speaking, it’s pretty obvious for the knight to “remember” the player and periodically check if the player is doing anything.
Logistically, it leads to some issues:
- Should the knight really know if the player is moving? If so, what about crouching and sprinting? Rolling?
- If a knight is far away, should it check what the player is doing?
- When the player makes a sound, should every knight check if they heard it?
- Should the knight even know what a “player” is?
As the player mechanics become more complex, adding new code to the AI to compensate becomes harder to do. For example, sprinting generates more noise for the knights to hear, so we need to add a check to see if the player is sprinting. Shooting also generates noise, so we add another check for shooting. Eventually, the number of checks become rather too much to manage and bugfix. Additionally, all the effort placed into those checks are wasted when the knight loses a reference to the player (“forgetting” that the player exists).
From a designer’s point of view, it’s very worrisome, since there would be a lot of downtime to get the mechanics in place to ensure that the AI is still working as intended. From a programmer’s point of view, it’s a lot of unnecessary work that can be better spent on other parts of the game.
It begs the question: How can we build this AI to ensure that it works, even if we’re modifying the player?
To Perceive is to Survive
The solution takes a simple approach: What about the player does the AI care about and how do we model it? No matter what the player is doing (running, sneaking, shooting, bashing heads with shields and swords), it boils down to three cases:
- Player is visible
- Player makes sounds that the knight can hear
- Player is a threat
A threat in this case is anything that can harm the knight. Just like real life, threats are generally a momentary thing, and we often go back to our daily lives once the threat is over (like dealing with mosquitos in the hot summer). By making a player a generic “threat”, we don’t have to make the AI think about the player directly, freeing up the player for the designers to move forward with new ideas.
But that leaves the question: A threat is a “thing” that a knight can detect, how do visuals and sounds work in this idea?
A threat is a perceived notion, and the knight that perceived it is going to react accordingly. To do so, we created a simple perception model for each threat. The model contains a reference to the source threat, as well as a number from 0 to 1 to show how well known the threat is to the individual knight, otherwise called it’s awareness.
When the player shoots, it emits an intriguing event to nearby knights, whether that’s a sound or a visual notion. This event is simply a fraction between 0 and 1 that diminishes with distance. The farther away the knights are, the smaller the value they receive from the event. This value is then added to the knight’s total awareness value. Overtime, should the player no longer emits any kind of event (death or too far away), the awareness value decreases until the knight is no longer interested. This opens up to new moments where the player needs to be clever on how to escape as opposed to just stepping outside of the combat range.
By setting up this perception system, the knight only needs to listen to a threat and do actions to raise its awareness. The player only needs to emit its presence through events. Should we decide to add friendly AI, they too would need to emit its presence, all without ever touching the knights.
Knights detecting the player after a few gunshots. The knight on the right noticed faster due to its proximity and loudness of the gun.
That pretty much covers what we wanted to say for Part 1. For Part 2, we’re thinking of covering the topic of combat AI, so stay tuned for that!
— initialPrefabs Team