Flicker of Hope

Flicker of Hope is a Fixed Perspective, Stealth Horror game featuring a cute candle protagonist in a plagued world. The player must bring light back to a dark cathedral while avoiding plagued mosquitoes and the evil caretaker, Mara.

During the life cycle of Flicker of Hope, I was responsible for prototyping and scripting AI, converting blueprints into C++ files, and scripting stealth gameplay. In addition to these, I also created an animation controller for one of the AI I had prototyped.

Role: Technical Designer

Project Details:
• Team Size: 18
• Project Life Cycle: 7 months
• Game Engine: Unreal Engine 4

Highlighted Contributions:
• Designed and Scripted a Swarming AI
• Prototyped a Decision Making Tree AI
• Created an Animation Controller
• Scripted and Implemented Stealth Player Mechanics

Enemy AI

The Design Lead for Flicker of Hope had a specific vision for the Swarming AI that would serve as the basic enemy type. However, as a Technical Designer, I was given the opportunity to expand on my Lead’s design and take the AI one step further by adding a flocking behavior to their routine. 

Swarming AI (The Legiones):

Design:

The design of the Legiones is intended to represent plague-ridden mosquitoes. However, their behavior deviates from typical mosquitoes in order to fit the theme of the game. In Flicker of Hope, these mosquitoes are attracted towards light, including the light that comes off of the player’s flame. When the light of the player’s flame overlaps the mosquitoes they begin their attack. The Legiones attack by dive bombing the player and exploding on impact. The player is able to stun them with their melee attack, but are unable to get rid of the enemy completely.

Flocking Behavior:

My biggest contribution to the design of the Legiones is their flocking behavior. When I initially prototyped the AI, each enemy acted independently from one another. I felt the way they had been moving felt stiff and they did not feel like living, breathing creatures belonging to a horror experience. To resolve this, I wrote a flocking algorithm. Then they started moving as a unit, but I still felt they were missing something. I decided to write a function that would have them to swarm around one another. The result has the mosquitoes moving in tandem while swarming around one another, becoming very terrifying to play against in larger groups.

Enemy Spawner Tool:

Design:

The primary function of the mosquito enemy type is to diversify gameplay in sections of the game where the player would be sneaking around the primary antagonist or taking a breather in the rest areas. Encounters with the Legiones would be happening throughout the game, so something needed to be done to diversify each encounter with them. I decided to create a tool that would allow our Level Designers to scale the difficulty of of the Legiones for each encounter. The resulting creation went far beyond a standard enemy spawner. The Level Designers were give full control over how often the mosquitoes could attack, how far they were allowed to chase the player, how fast they were allowed to move, and many more settings as shown in the picture above.

Accessibility:

Creating a tool with a vast number of settings required a bit of tweaking to make it accessible to the Level Designers. In addition to taking careful consideration towards providing all the instance editable variable clearly defined names, I also added tool tips to each one. If a Level Designer forgot which variable adjusts what, they could simply hover over that variable in editor and helpful description would pop up. In the months proceeding the addition of these accessibility features, a Level Designer never had to reach out to me for clarification on how to use the tool.

Decision Making Tree AI (Mara):

Design:

Before the idea of Flicker of Hope had been conceived, I had pitched a drastically different horror game to my team called “Phantasm.” This game featured a ghostly antagonist that would hunt the player throughout the experience. Although Phantasm was not the game our team ended up developing, everyone loved the idea of this AI and decided to build Wick around it. The shift to a different game required some changes to its design. One big change was how the AI needed to track/hunt the player. Since our protagonist is a candle, it makes sense for him to “melt.” As the player’s flame burns, their wax body melts, leaving a trail of wax droplets behind them. The AI needed to be able to follow this trail.

Prototype:

As the one who pitched the original version of the AI, I was able to prototype the new one. The first step was to create a patrolling AI that would chase the player on sight. However, this AI needed to do more than patrol, it needed to hunt. I scripted an “Area Manager” that would keep tabs on which part of the level the player was currently in. This way, the AI will always patrol in their general vicinity, conveying to the player that danger is always a step behind them. Patrolling and swapping areas increases the chances for bumping into each other, but I needed to get the AI to hunt the player. I then gave the AI the ability to follow the player’s wax trail. The further away each droplet of the player’s wax trail was from one another, the longer it would take for the AI to follow it. Same goes for if the next wax droplet rounded a corner. Once the prototype was finished, I handed it off to a Programmer to iterate one while I moved on to the next AI.

Refactoring Blueprints

c++ logo

The Swarming AI’s design changed a bit throughout the life cycle of the game. After internal play testing, we arrived at a final iteration for the AI. From here, there was no need to keep the AI in blueprints. C++ code is drastically more efficient than blueprints in the Unreal Engine. With numerous swarming mosquitoes buzzing around the screen at one time, keeping them as blueprints was going to start taxing performance.

Before Flicker of Hope, I had experience with C++ on smaller, personal Unreal Engine projects, but I saw this as an opportunity to truly take a deep dive into the programming language. Instead of using built in Unreal Engine conversion tools, I decided to rewrite the AI in C++ by hand. I find that typing everything out by hand helps me retain the knowledge better than taking short cuts and reviewing the work later.