In this project, I worked as lead programmer with two other programmers. We broke down the game system into 3 seperate modules: player controller, enemy AI and level generator which I implemented.
Dungeon Level Generator

The level generator sequence was inspired by the one in the Spelunky games, which goes like this:
This system was suitable for the game since we wanted unique level patterns with props to hide from enemies which chase you.

To further achieve this, there are several room layouts with different arrangements of props, which is randomly rotated in 90 degrees for more variety.
I applied more downward bias to encourage more of a straight path from start to end to have similar length for each randomly generated level. The level on the right is created with the bias.


public void Generate()
{
Rooms = new List();
map = new bool[levelSizeX, levelSizeZ];
// Create entrance from top
int roomPosX = Random.Range(0, levelSizeX);
int roomPosZ = 0;
CreateRoom(roomPosX * distanceX, roomPosZ, RoomType.Entrance, roomPosX);
// Create rooms middle to exit
while (roomPosX >= 0 && roomPosX <= levelSizeX - 1 &&
roomPosZ <= 0 && roomPosZ >= -levelSizeZ + 1)
{
// Left, right or down (more downs to encorage more of a linear shape)
int randomDirIndex = Random.Range(0, directions.Length);
Vector3Int randomDir = directions[randomDirIndex];
int newPosX = roomPosX + randomDir.x;
int newPosZ = roomPosZ + randomDir.z;
// Check if we're hitting the edge of the map
if (newPosX < 0 || newPosX > levelSizeX - 1 ||
newPosZ > 0 || newPosZ < -levelSizeZ + 1)
{
// If we're not hitting bottom edge, then move down and create a new middle room
if (roomPosZ > -levelSizeZ + 1)
{
randomDir = directions[2];
roomPosX += randomDir.x;
roomPosZ += randomDir.z;
CreateMiddleRoom(roomPosX, roomPosZ, randomDir);
continue;
}
// If we are on bottom edge, then mark new room as exit and end generation
else if (roomPosZ == -levelSizeZ + 1)
{
Room exitRoom = Rooms[Rooms.Count - 1];
exitRoom.ApplyType(RoomType.Exit);
CreateHallway(exitRoom, directions[2], PassType.Exit);
CreateDoor(exitRoom, directions[2], PassType.Exit);
break;
}
}
// If chosen direction is blocked by another room, then pick another
if (map[newPosX, -newPosZ] == true)
continue;
// If we are just within the map, then create a middle room
roomPosX = newPosX;
roomPosZ = newPosZ;
CreateMiddleRoom(roomPosX, roomPosZ, randomDir);
}
// Create path nodes for enemy AI
mapHolder.CreateNodes();
}