Operation Exodus started out as a Senior Design Project between myself and five others: Greg K, Alex C, Eric S, Thomas S, and James S. After nearly thirty weeks of planning and development, our project made it to the final three across
all Computer Science Senior Projects at Drexel University. After Graduation, Greg and I decided to rebuild from the ground up.
The game is a Virtual Reality Cooperative Stealth game playable on the HTC Vive. It involves two players: One in the headset (the agent) and one on the computer (the operator). The operator is given access to the floor plan, and has
the vital role of helping the operator navigate through the level to find objectives. The operator can hack doors, cameras, lazor traps, etc to help the agent stay out of sight from the patrol robots.
Throughout the development of the project, most of my time was dedicated to four major componenets.
Each level is procedurally generated at runtime with a random seed. No two levels will ever be the same unless you load a seed.
Learn more »Each room is built to match an office aesthetic. Designed over 20 rooms that plug into the procedural generation.
Each enemy creates his own patrol route, will call for backup if alone, direct others to investigate and much more.
Almost every object from turkeys in the oven to computer towers can be picked up and thrown by the agent.
Learn more »One of the best features of this game is the procedurally generated levels. We came up with a simple algorithm that proved to be quite effective. I designed four level layouts with different sockets: square, rectangle, and elbow shaped.
As each level is loaded, our algorithm plugs in random rooms of the appropriate size into each socket. We implemented checks to ensure that no one-room layout would exist twice in the same map. Additionally, each level design has
an array of over 50 possible enemy waypoint locations and over 20 possible trap locations. Upon loading a level, a number of waypoints are randomly selected for each enemy as patrol points and a number of traps are spawned (the
number is relative to the difficulty level selected).
To make the game look as realistic as possible, we realized that we needed a vast number of room layouts, so each room would feel fresh and provide a unique experience. To go with our procedural generation algorithm, I created 7 to 8 room plans for each of the three shape layouts (square, rectangle, and elbow). I created open spaces, conference rooms, cubicles, bathrooms, offices, and even a fun secret room only attainable through ventilation ducts. Each room is equipped with fully interactable objects and at least one working door. Upon close inspection of the following images you may notice that some rooms have a number of green boxes. These boxes are potential spawn locations for objectives, like a keycard or a confidential file. As each level loads, it will pick one or two locations across all the rooms and spawn an objective at one of these green boxes. This encourages exploration and communication as the objectives will be in a new location almost every run-through. Additionally, each room has a potential location for a camera to spawn. When a player is caught by the camera it alerts the enemies and they are quickly on the player’s path.
The enemies are one of the most import features in the game. Each enemy has a list of waypoints to travel between throughout the map. Each waypoint is determined at run time and the enemy is able to use an A* algorithm to navigate
itself through the map to get from point A to point B. If an enemy notices something like a door open when it should be closed, a mysterious noise, or an object out of place, it will launch an investigation at that location. If
an enemy is alone and detects the player or goes through a major investigation, it will call out for help and receive assistance from the closest enemy. Additionally, enemies never forget when they have seen the player. Once the
player is discovered, the enemies are more alert and are much harder to avoid for the rest of the level.
Every room has a number of completely interactable objects. From monitors to coffee cups, almost everything in the game can be picked up and thrown. Each object has a specific weight and will make a noise sphere based on impact force.
A computer tower thrown against a wall, will make a much bigger noise than a tossed book. Any enemies that are inside the noise sphere will “hear” the collision and investigate the center of the sphere. Each object is assigned
a location. If an enemy comes across a book that is too far away from its original location, it will launch an investigation and the object's location is updated. The objects can also be used strategically to throw enemies off
of their patrol route or even to keep doors from closing all the way. In the event the player is caught, objects can be used to deflect the enemy’s bullets. However, objects have a small amount of resistance and too much damage
will destroy them.
Recently, I have been working on a new method for procedurally generating levels. With the original design, level originality depended on the layout of room sockets and the number of created room types. While this allowed for a large
number of technically unique levels, the layouts become repetitive very quickly. Now, levels are built entirely out of scratch at run time. First, the program will build walls around the outside of the map (dimensions can be determined
based off of the difficulty level). Randomly, the program creates hallways either left-right, or up-down, stretching across the entire map. From this hallway, the program creates two more hallways stemming from the previous moving
in opposite directions. This process continues until either the total space taken up by hallways exceeds a predetermined variable, or no more hallways can be created based on a specified minimum room size. This process helps create
an almost limitless variety of map layouts. Once the layout is created, the program goes from room to room spawning walls, doorways, and covering floors with carpet or tiles. To avoid extra large rooms, any space that exceeds a
predetermined maximum room size, is split into smaller rooms.
After the layout is created and the rooms are defined, I automatically populate each room with new office assets. Currently I'm doing this by creating different possible blocks with a unique design and interactable objects. Each block has an associated theme and will only spawn if the theme matches that of the room. In addition to room interiors, the program also adds windows, blinds, ceiling lights, etc, all at runtime. I am currently working on automating this process even more but for now it's producing really exciting results.