Sicaria is a third-person stealth game set in Antwerp during the 80 years war. You play as a girl who is trying to prevent Antwerp from being destroyed. I was an AI programmer. I was also responsible for the performance of the game.
This is a project that is being made in my third year of CMGT at Breda University of applied sciences. The team has a size of 35, of which 8 are programmers.
Sicaria has won the Rookies Excellence award, and became a finalist for "Game of the Year". In addition, we became a finalist for both "Best student game" and "Best hobby game" at the Game Development World Championship
The team structure is very different in such a large team. As a result I learned a lot about how larger teams are managed, and how to keep everyone working efficiently.
This was my first project that needed complex AI. I improved at using behavior trees, and learned new things like EQS and group behavior.
Being responsible for performance taught me a great deal about profiling in unreal engine, and how different render settings affect the project. For future projects, I will have a better grasp on which things I am working on could potentially cause performance issues. I now learned to regularly profile, even if I am not getting bad frames as a QA measure.
This was my first experience releasing a game on steam, and everything that comes with it.
The alert behavior triggers when the enemy loses you after chasing, and is designed to try to find the player again. It runs an EQS query that dictates where the enemy will search.
An EQS query generates points in a specifiable shape (in this case a cone). Those points are scored based on some parameters. The point with the highest score is where the enemy will search. Points that have a line of sight with the enemy are discarded, as the enemy would already know if the player is there. Points are scored higher if they are close to the player's last known location. Points are scored lower, if the enemy has searched the area near the point already.
This way, the enemy looks in spots that are logical, and does not search the same area over and over. This makes the behavior relatively realistic.
The default unreal AI perception is not very customizable. For a stealth game we needed a very specific way of doing perception, detecting the player faster based on whether they are in direct line of sight or peripheral vision.
At first, we used custom meshes as colliders for the perception. After profiling, I found that this is extremely inefficient. I rewrote the system to use dot products instead to determine whether or not the player is within a certain angle of vision. This uses different calculations for the direct line of sight cone, and the peripheral cone.
If the player is within these angles, 5 rays are shot to the player from the enemy their head. These rays are shot towards the head and the 4 limbs of the player. Depending on how many rays hit the player, we add detection level.
As stated earlier, I am responsible for the performance of Sicaria. This involves constantly profiling, optimizing parts of the project I am familiar with, and delegating other optimizations to team members with better knowledge over certain features. I set up a pipeline for artists to follow whenever they important assets and set dress. This pipeline for example states to make sure nanite is enabled, to check the collision settings, group objects together, and to disable unnecessary shadows, among other things.
In our project, the enemies were taking the most resources. This is due to their large perception colliders, and a heavy animation blueprint. To make levels more scalable, I created an enemy unloader that disables their collision, animation and tick function if the player is not in range.
I optimized countless different things that are too small to name here. Eventually I managed to take an un-set dressed level at 20fps, to a fully set dressed level at 60fps (this is on an RTX 3060 and Ryzen 7). There is still a lot to do, but it has made a significant impact so far.