top of page

Your Average Bear

Project Type:             University

Project Duration:    1 year

Group Size:               ~ 20 people 

Software Used:        Unreal Engine 5.0.3

Languages Used:     C++, Blueprints

Primary Role(s) :      Gameplay/AI Programmer

About:

In this goofy sandbox third-person stealth game, you play as a bear who delivers food to the local wildlife through a phone delivery app "UbearEats". To obtain the food requested by the local wildlife, the bear must steal food from a nearby campsite run by the paranoid Ranger Mike. The bear must take precautions in delivering orders as the camp has a large amount of security, preventing their precious food from being taken.

Steam page: https://store.steampowered.com/app/2349870/Your_Average_Bear/

Your Average Bear was developed during my final year at the University of Utah as an undergrad. It was developed over the course of two semesters. My role was to work on enemy NPCs but I also helped develop the player avatar and other gameplay systems.

Contributions:

  • Custom Sight AISense

Making a stealth game, my team and I knew right away we needed a system that would handle enemy perception. Enemies would need to mimic the ability to hear and see things in the environment. Fortunately, Unreal made this easy for us by providing the Perception System. However, I wasn't happy using the default sight sense implementation for our game. The default implementation just used a cone to determine if an NPC was able to see an object. This wasn't ideal for our game because our maps were bigger open-ended levels. The cone shape also favored enemies detecting the player from further away rather than closer.

So I write my own custom AI Sense for sight. Instead of the standard cone, the sight was broken into three volumes. Primary sight, secondary sight, and wings. The primary sight is a cone shape that would be typically small in comparison to the other two volumes. When something intersects with this cone, it would be detected very quickly. The secondary sight volume is the shape of a coffin which would handle more far sight detection. Lastly, the wings are much like peripheral vision or "sixth sense". This volume is located at the sides of the character to mimic seeing something in the corner of their eye.

PerceptionVolumes.png
AdvancedSightSettings.png

This approach was heavily inspired by the approach of AI perception in Splinter Cell: Blacklist

http://www.gameaipro.com/GameAIPro2/GameAIPro2_Chapter28_Modeling_Perception_and_Awareness_in_Tom_Clancy%27s_Splinter_Cell_Blacklist.pdf

With my custom sight implementation, I was then able to feed information into my Target Tracking system to have the enemy NPCs detect the player at different rates depending on the volumes they are intersecting with.

  • Target Tracking System

For most games, NPCs do not perceive one thing at a time. Most of the time they have to manage and handle multiple senses and make decisions based on that information. That was also the case for Your Average Bear. With Unreal's Perception System, it solves the problem of whether something is being detected or not. Now, we needed to write a system that helps NPCs make decisions based on the things they are perceiving. I adopted Crytek's Target Tracking System for this project.

http://www.gameaipro.com/GameAIPro/GameAIPro_Chapter31_Crytek's_Target_Tracks_Perception_System.pdf

Below is a working example of my target tracking system at work. The player will throw a rock and distract the enemies. At this moment the rock is the target that is prioritized (because there is nothing else being sensed). Then when the player decides to click the roar button, it has a higher priority than the rock, so the enemies turned around and faced the location in which they heard the roar. Within seconds the enemy AI detects the bear and now the bear is the highest priority target. I would continue to throw rocks to distract the enemies but they are not prioritized so the enemies continue to hunt down the player.

For each sense that we want the enemy to track there needed to be a corresponding configuration file. These config files can be easily changed to alter how an enemy tracks a target. The picture below shows the configuration for tracking an object by sight. I won't go into every detail because the paper by Crytek talks about this more in-depth, but the configuration can be tweaked to change how fast an enemy loses and gains detection of a target. It also helps determine which target would be considered to be a higher priority than others. "Peak Value" describes the max possible value for tracking the target. This information can then be read elsewhere. One example would be the UI for when the player gets detected. It uses the target tracking information to determine the state of the UI.

TTConfig.png

Another important part of the Target Tracking System is the concept of modifiers and pulses. Modifiers can be used to alter the default target tracking configuration dynamically. In our case, we made a modifier for the enemy Tracker (the person who shot a ton of bullets above). The modifier allowed Trackers to see the player through bushes at a slow rate while other enemy characters couldn't.

Pulses are also very useful because it allows for the target tracking to maintain its state. This is useful in the case where enemies should "stick to" the player when chasing them down. We don't want the enemies to lose sight of the player immediately. This is one way to fake the illusion that the enemies can guess where the player is going.

  • Reaction Component

Another important thing in making AI feel more responsive and polished is reactions. A reaction is something that is triggered and run immediately. A reaction should persevere or change the enemy state after being triggered. A reaction could be as simple as playing a one-off animation to simulating physics for a timed interval. Playing a reaction should also happen almost immediately when being requested so that the enemy NPCs feel very responsive to the world around them.

 

In Your Average Bear, I implemented a Reaction Component that was placed on every NPC character. The component was treated like a black box where outside the component they may request a reaction. Inside the component, it manages which reaction to perform. This is nice because it avoids accidentally interrupting reactions even when we don't want to. We can put each reaction request into a priority queue and determine which reaction is the best to perform. In this implementation, the highest prioritized reaction would trump other reactions. This would be useful in the case where a character may be shot and exploded at the same time. In this scenario, it is okay to ignore the reaction to getting shot and to play the more violent reaction, exploding.

To ensure that the behavior tree of an NPC doesn't run while a reaction is occurring we set up our behavior tree so that it loops on the Perform Reaction task until there are no reactions to be performed.

ReactionBehaviorTree.png

Below are some examples of reactions used in Your Average Bear that I have implemented.

The Bucket takedown reaction plays an animation puts a bucket on the character and sets the enemy state to patrol. (With the bucket on the enemy's head they can no longer detect the bear.)

Both the beehive and banana peel set the characters to simulate physics (ragdoll). This reaction preserves enemy state, meaning that they will resume back to what they were doing before the reaction occured.

  • AI Coordinators

Now enemies react, perceive, and track objects in the world. However, something is still missing. They all seem to behave the same way and don't take into account what their buddies are doing. To make the enemy NPCs feel like they are more human I implemented small managers called "AI coordinators." The job of these coordinators is to manage and share information between a group of enemy NPCs. Basically, they are being coordinated. My implementation of coordinators is loosely based on Tobias Karlsson's paper on squad coordination in Days Gone.
 

http://www.gameaipro.com/GameAIProOnlineEdition2021/GameAIProOnlineEdition2021_Chapter12_Squad_Coordination_in_Days_Gone.pdf

Because Your Average Bear is a stealth sandbox it was difficult to determine when a group of enemy NPCs should be coordinated. I ended up going with the idea from Karlsson's paper where every enemy NPC had a coherency circle around them. If at any point a character was assigned to be coordinated this cohesion circle would check for intersections with other characters. When another character intersects with the cohesion circle that is tied to a coordinator, the other character would also be assigned to the coordinator. 

In this example, I am showing off the combat coordinator. The coordinator queries for combat positions and assigns these positions to each of the rangers. The rangers are also assigned a role in combat: flank, offense, or keep distance. The flankers choose positions on the side of the bear and choose to sprint in position. The offensive rangers shoot while walking and want to step in front of the player's view direction. Finally, in the keep distance role, rangers just stay at a certain distance from the player and shoot. The video showcases the coherency circles around each enemy NPC and when a ranger in combat overlaps another ranger's coherency circle they are then assigned to the combat coordinator as well. The structure helps give the appearance of new rangers joining in group behaviors.

Combat wasn't the only thing that I wanted to coordinate. It was also very useful to coordinate scared campers. This way I was able to guarantee each of the campers to spread out and run in random directions. I was also able to assign some campers to randomly feel brave and attempt to bear spray the player character.

The AI coordinators were dynamically spawned throughout gameplay. In total Your Average Bear made use of four different coordinators: alert, combat, investigate, and flee. However, it would be easy to expand and create many more coordinators to create various group behaviors. The coherency circles were used to assign NPCs, merge, and split coordinators dynamically. In the examples above, both merging and assigning were heavily used, but splitting could also be very useful if I were to implement a search behavior. Unfortunately, I was unable to implement this coordinator due to time contsraints.

  • Honorable Mentions that I worked on

  • Toolbelt Component 

    • This was just a simple tool manager for the player character and enemy NPCs. The player has a total of five different tools: Bucket, Rocks, Banana Peels, Skunk Bomb, and the Branches.​ The enemy just had the gun tool. Each tool is inherited from a base class Tool in which each tool would be run like a simple state machine. Engineers in my team were able to write their own custom tools using this system.

  • Intercom System

    • A simple system that would play intercom messages throughout the world. This was to make the world feel more alive and give opportunities to have some fun dialogue between Ranger Mike and their fellow campers.​ Some intercom announcements were played on a timed interval and some are queued up to be played at certain moments of gameplay.

  • Music System

    • A system that handles the transition between playing different background music. We ultimately had only three soundtracks: Combat, Ambient, and Main Menu. This system handled the transitions between the different songs playing. It would try to transition on a certain BPM so that the music transitions don't feel abrupt but natural.​

  • Patrol Paths

    • Created patrol paths for NPC characters to follow. The patrol path would consist of a spline that would direct the enemy NPCs and at each control point, they have a chance to wait and play an animation.​

Conclusion:

In conclusion, Your Average Bear was my most ambitious project. I had to tackle many AI systems within a year of release. This was made in my final year of undergrad and I had learned a lot. I had worked with a wonderful team full of talented people with varied backgrounds. It was a lot of fun to compile this project together.

bottom of page