The Infected Dungeon




The video below shows a typical play through of The Infected Dungeon.



Game Summary

Goal
My goal for this project was to make a first person shooter game that could generate a different experience every play through. Initially, I wanted to accomplish this by procedurally generating a dungeon level. As I created the game, I realized this may have been too ambitious for the time alloted. Instead, I decided pivot my goal and create a game that players of all skill levels could have a similar experience. I think this is an important feature for newer players to enjoy games where there is a significant skill gap (most FPS games have this skill gap!). The downside is it may create a stale experience for higher skilled players. In my game, I implemented dynamic round difficulty to attempt to match the skill level of the player to the difficulty of the game.

Summary
This game is a zombie survival first person shooter. It is a round based game, where zombies spawn in fixed positions and the player must kill all of them to advance to the next round. The game starts by the player spawning in a large room with 1 zombie. Once the player kills this zombie, round 2 begins. The first 3 rounds are meant to gradually introduce the player to the mechanics of the game. One zombie is added each round until round 4. At round 4 the game begins to dynamically adjust to the player's skill level. This is described in the section below. Additionally, the player can explore the level by opening doors (in exchange for points). When the player opens doors, more zombie spawn points are added to the next round. As the player opens more doors, more zombies will spawn. The player is incentivized to open these doors to obtain the powerups or guns that are placed throughout the level. These are described in more detail below. The overall goal of the game is survival as long as possible, while obtaining the highest score.

Weapons

There are 3 weapons in this game. The first is the pistol, which the player spawns with. This gun has 5 shots per clip, shoots at a medium rate, and does a medium amount of damage. The second gun is the shotgun. The player can unlock this gun for 100 points. It has 2 shots per clip, shoots at a slow rate, and does a high amount of damage. The shotgun can be seen in the video below. The third gun is the machine gun. The player can unlock this gun for 150 points. It has 50 shots per clip, shoots at a fast rate, and does a medium amount of damage.

Enemies

There are two types of enemies in this game. The main type of enemy is a zombie. Zombies move slow and do a low amount of damage, but they are deadly in numbers! The second type of enemy is a zombie dog. The zombie dogs spawn every 5th round. The are fast and do a high amount of damage.

Powerups

There are two types of powerups in this game. The first, is additional health. The player can buy health for 30 points. The second type of powerup is additional ammo. The player can buy additional ammo (for any gun) for 10 points. These powers are used to aid the player as well as incentivize the player to explore the level.

Project difficulties

This was the first game I made in Unity! Part of this process was figuring out how to use the editor and scripts to accomplish what I wanted to do. This was a fun difficulty and I am glad I took the time to learn it. Another issue I had when making this game was modeling. I have never made any 3D models before, so I was worried the game would not look good. Luckily, I found some blender tutorials on how to create a FPS level, and used a lot of assets from the Unity asset store. I am pleased with how it turned out. A huge difficulty I had when making this game was creating the dynamic round difficulty. I wanted to make sure that my implemented system would accurately scale to the player's skill, while also not easily taken advantage of. The first system I implemented was too trivial, so players could purposely do worse to live longer in the game. To fix this I changed my implementation to something slightly more complex, which is described in the section below.



Algorithms

Dynamic round difficulty

The dynamic round difficulty in this game is based on the paper by Robin Hunicke, The Case for Dynamic Difficulty Adjustment in Games. In this paper Hunicke described a general algorithm for detecting when the player is in trouble, and suggested a few adjustment policies to aid the player. The paper was intended for FPS games, so it fits perfectly for my game. I will describe her algorithm and the differences in my implementation. First, Hunicke explained that the amount of damage a player takes over a series of measurements can be represented as a gaussian.

Calculating the gaussian error integral enables us to know F(d), the probability of recieving d or less damage at a given tick.
This is a continuous function, however it can be approximated using the C/C++ erf() function (I found an implementation in C#). This results in the formula:
to calculate the probability of recieving d or less damage at some time t. This formula is in terms of the player's health (h), mean damage rate (μ), and the standard deviation (σ) of damage rates. I implemented this formula to detect when the player is struggling after each round. This formula works well in the early rounds of my game, however it does not work well as the game goes on. This is because it takes 1 measurement of damage per round. So, as the game goes on the 1st round is weighted the same amount as the most recent round. This is an issue because the most recent round is supposed to be the most difficult. This causes the game to never scale down, no matter how hard the previous round was. To fix this, I changed the calculation of the mean. Instead of a normal mean calculation, my calculation weights the most recent round equal to all previous rounds:

μ = .5(prevRoundMean) + .5(lastRoundDamage)

This calculation weights the damage taken in the last round equal to the damage taken in all previous rounds. This ensures that the most recent round is the most influential in calculating F(d). I found calculating the mean this way works much better for my game. The adjustment policy I implemented is fairly simple. If F(d) > .4, then the game should scale down (get easier). The variables that change are the zombie speed and health. When F(d) > .4, both zombie speed and health are decremented. When F(d) < .4, the game scales up (gets harder). Either zombie speed or zombie health is incremented, each with equal probability. I found these numbers to work well through trial and error. The video below shows an example of dynamic difficulty in action. In round 4, the zombie's speed is noticably slower and they can be killed in 2 shots (instead of 3 in rounds 1-3).


I have found dynamic difficulty to work successfully without the player using it to cheat. In my game, more points are awarded for enemies of higher difficulty. This way, player is never incentivized to do bad intentionally.

Zombie pathfinding

The enemies in this game walk towards the player. Every enemy knows the player's location at all times. The enemy is defined as a Unity "Nav Mesh Agent". This means this entity can traverse a map known as a "Nav Mesh". The Nav Mesh is a data structure that stores the walkable surfaces of the level. The agent then uses this data structure to compute A* to find the shortest path to the player. This functionality is built-in to Unity. More information can be found here

Limitations and Future Work

The one area I would like to improve on this game is to create more variablity. Right now the enemy spawn points, powerups, and weapon pickups are all fixed. I would like to randomize these so each play through is different. Also, as stated above, I was not able to procedurally generate a dungeon level. One difficulty in accomplishing this (as mentioned in class) is that way the zombies move. The zombies have a "Nav Mesh" which specifies the walkable areas on the map. This nav mesh would not be available when procedurally generating a level. Despite this, I still believe it is possible to add procedural generation and it is something I would like to add in the future.

Lastly, I would have liked to add more "polish" to the game. This includes adding particle effects, impacts (blood?), sound effects, hit markers, grenades, more guns, more enemies, and more objects to interact with in the game. I also think adding multiplayer would make the game more complex and fun.






Unzip the zip file, click "zombie.exe" to play

Download