top of page

Caves of Nod

About

Caves of Nod is a first person shooter. You delve into a cave that is infested with gruesome creatures. In the game you yield a weapon that allows you to perform not only killings by shooting the enemies, but also solve puzzles and interract with different objects.

Project Info

  • Role: Gameplay and AI Programmer, 

  • Time: 7 Weeks

  • Team Size: 8

  • Engine: Unreal Engine

  • Engine Experience: 4 months

  • Programming Experience: 19 months

Background

This project was daunting to get into. It held a lot of pressure from the very beginning. First of all, it was the longest project in our education. Secondly, this was the project where we needed to use Unreal Engine. The engine that was unfamiliar and new to all members of my team, we only had a single course to learn the engine which was the challenge on its own. Last but not least, group projects in general are stressful experiences. 

​

We settled with first person shooter since it seemed like the easiest genre to implement in this engine as it was designed for it. In addition to that, I didn't have anyone who wanted to do animations which are very important in non-first person games.

​

In this project, I spent a lot of time working on AI movement. The goal was to make insects that could move in 3D space. This was a big challenge. Moreover, I worked very closely with my project owner and designer Dominik, to implement the features that were required to make the game feel good.

Movement in 3D space

 Task

This is hands down the most complicated type of movement I needed to implement.

In my team we agreed to have insect like creatures as enemies. Most insects are able to crawl on floors,walls and celings all the same. In unreal engine there is a navigation system, however it doesn't support such movement, basically Unreal's navigation wants to keep pawn's head pointing upwards therefore it doesn't need to build navigation on walls or ceilings.

How I solved it

There is a class called "EnemyBase" that is responsible for controlling the movement. However, the calculations for the movement happen in PathTracer ActorComponent. In addition to that, there is CustomGravity ActorComponent that is responsible for gluing the insects to the surface when needed.

​

I'll explain the way it works very briefly.

Basically I need to rotate the actor correctly according to the surface it's on and then move forward. In order to calculate the rotation, PathTracer performs line traces.

Line Traces

PathTracer performs Line Traces to calculate the Move Direction and appropriate Rotation.​

​

It's difficult to explain in few words how the calculations are happenning. Very simply I perfrom LineTraces and store HitResults (I call them HitForwardCloser, HitForwardFurther and HitRight).

 

In order to calculate Move Direction I get a direction from the actor location to HitForwardCloser (with some adjustments to get away from the ground).

​

Rotation proved to be more challenging. I needed to get three vectors: Up, Forward and Right. When I have those I could get the appropriate rotation that aligns with the surface. I calculate those vectors by using the stored HitResults. 

  • Forward = (HitForwardFurther - HitForwardCloser).Normalize

  • Right = (HitRight- HitForwardCloser).Normalize

  • Up = HitForwardCloser.Normal

​

I do take into consideration that surfaces can be concave and convex. Firstly, I assume that the surface is Convex and if any one the linetraces fail, then I perform other line traces to get HitResults from Concave surface.

Result

HitForwardCloser(Yellow), HitForwardFurther (Blue)

HitRight(Pink)

Concave surface

AI - Behaviour

Challenge

This was the first time I used behaviour trees. I had always wanted to experiment with them and see what is possible. Even though, my task could be achieved with simple state-machine, I decided to use behaviour trees regardless.
​
Therefore, my challenge was to learn how behaviour trees work. I also found it difficult to understand what should be responsible for what. There was a controller class, character class and now behaviour tree.

States

The behaviour of the insects is rather simple. There are only 3 states: Patrol, Attack and Chase.

​

  • Patrol - Picks random rotation to align to and random duration. After that continues moving forward for that duration.

  • Attack - if within attack reach(use sphere collision) then performs attack on the player.

  • Chase - Moves towards the player.

Gameplay

Initiative

I was not responsible for anything that has to do with the player character, inputs or anything player related. The way we split our work, I was solely responsible for AI. However, there were things that weren't working as intended and couldn't provide the feeling my designers were trying to achieve. For example, one of those things was the way the player was interracting with stabbable objects. It wasn't responsive enough. 
​
I decided to get lend a hand and improve the existing code to achieve the vision of my designers.

Interfaces

I refactored our code and added several interfaces to imporve gameplay: Hittable, Stabbable and Explodable.

​

  • Hittable - Things that can receive damage.

  • Stabbalbe - In the game there are several things that can be interracted with by being stabbed.

  • Explodable - Things that are affected by explosions.

Interface Example - Stabbable

There are three stabbable objects in this video: 

  1. Dead insect - replenish ammo

  2. Eggsplosive - Attach to weapon

  3. Heal Egg - Heal player

​

There is one more stabbable object in the game and that's Alive Insect. Stabbing alive insect replenishes your ammo and also damages the insect.

Boss

Hard situation

The game was supposed to contain a boss fight at the end of the game. However, when we were approaching the deadline, we realised that our boss fight nowhere near to be finished. I wasn't responsible for working on it at that time, but I took initiative once more to save the hard work of my teammates. There were a lot of things done for the boss, e.g. animations, assets, level, cinematics and even the level itself. The thing that was lacking was the fight itself.

​

So, I took it upon myself to implement the whole thing, however since we had so little time and it would need to be tested, I could only be given one day to implement the whole fight... So I did...

Features

The good thing is that I didn't need to implement new features rather use the existing ones. The boss fight is the test of what the player has learnt.

Damaging Player and Other insects

Completing a sigil exposes weak points

Weak points + detaching the limb

Utilized explodable Interface + VFX

Takeaway

During this project I learnt a lot about Unreal Engine. I learnt how to work with blueprints and C++ and make them work together. I spent a lot of time working with behaviour trees. 

​

I wish I had read an article about how A Plague Tale(2019) implemented their rats before we started the project. I understand that my movement in 3D space isn't a good solution, but it was something I came up and implemented fast. In Plague Tale they make floors perform pathfinding to the player using FlowCharts and I believe I could implement similar feature for our insects.

​

Still, I find this project very successful as we managed to finish the game and I learnt a lot. After the project I knew much more about Unreal Engine and its components, therefore I could better structure my future projects.

bottom of page