Tomb of Khaibit

A co-op horror game where you and your friends are archaeologists trying to escape a deadly Egyptian tomb.

About

Tomb of Khaibit is a co-op dungeon crawler where you play as archaeologists exploring a newly unearthed tomb in Egypt. In the dungeon, you'll discover horrifying creatures and magic from the Egyptian gods.

The tomb is procedurally generated and the puzzles you'll need to escape are randomized, meaning each tomb will be a new experience.

This was a group senior software project as part of the team BLU3_J3LL0. For the game, I created a procedural generation algorithm to make tombs, coded a flexible UI system, and worked as a gameplay designer.

Skills

Video Game

Team: BLU3_J3LL0
2021

Development

BLU3_J3LL0 Team
The BLU3_J3LL0 Team

I developed this project for my Senior Software Project with the group known as Blu3_J3ll0. The team included Chloe Flores, Joseph Mellor, Tim Flavin, James Hale, Spencer Stith, John Dickey, Kate Kwasny, and myself.

Skills

My roles for this project are Project Manager, Programmer, and Artist. My largest task was designing and coding a Procedural Generation tool codenamed Texo that creates random dungeons. I also made the pixel art for the environment, and worked on several features such as flexible UI and inventory.

Texo-Procedural Generation

Procedural Generation was our most ambitious goal from the start, so I looked for a solution for Unity. Unfortunately, Unity didn't have any built-in Tools and the Asset Store has no free solutions for a rogue-like game. The Texo editor is my solution to this problem and is what I am most proud of developing for this game. I spent around 80 hours creating it.

Texo Algorithm and Solution Overview

If you're curious about how Texo works, read on! I'll explain in brief how the solution and algorithm works. Note: lots of this may not make sense to people unfamiliar with Unity, as it uses lots of Unity-specific terms.

  1. Level designers create Rooms in prefabs using the Tilemap system already in Unity. Rooms can be any size. They place small arrow tiles on a special "Connectors" Tilemap to indicate where the room should connect to hallways. Other GameObjects can be placed anywhere in the prefab and will be spawned in as well. Rooms are put into special RoomLists which group rooms into folders.
  2. Generate Rooms: Rooms are randomly given placements in a "PlacedGrid", which has padding and predetermined dimensions and cellSize. Rooms in the Required Room List are all placed first. Special rooms like the entrance, exit, and altar rooms go in this list. Placement continues until a target "density" of rooms is reached, for example, 55% filled.
  3. Pre-Connect: A Room is selected at random to be the "root" room. Find the closest N (typically N = 2) rooms to this room and select a random connector from each room to connect to. The selected rooms are added to the tree, and become root nodes. The algorithm continues until all rooms are in the tree, guaranteeing connectivity between all placed rooms. At the end of this step, we have a list of connections to make.
  4. Hallway Connect: Using the A* Algorithm, find the shortest path for each connection, using the cells in the PlacedGrid as units. At the end of this step, we have a bunch of lists of cells that make up a path from Room A's connector to B's connector.
  5. Hallway Post-Process: A subtle but important step. Hallways adjacent to a connector will check to see if a perpendicular hallway exists across from the connector (for example, an east connector should run into a vertical hallway). If there is not, hallways are extended in that direction.
  6. Writing: Last, Rooms and Hallways are drawn to the Grid, combining tiles from tilemaps of identical names into a singular tilemap. This flattens complexity of the level, and allows RuleTiles to connect to tiles from other rooms. GameObjects are spawned in relative to the room's position. All empty spaces in the grid are filled with "blank" tiles.

Benefits of the Texo Solution:

  • Level Designers can have nearly unlimited freedom developing rooms inside prefabs instead of editing an entire level.
  • Developers can place GameObjects inside Rooms and they will be spawned in with the room.
  • Rooms connect to each other using a spanning tree, guaranteeing connectivity between rooms.
  • Hallways between rooms take the shortest path to the other room with the A* algorithm.
  • Certain Rooms can be guaranteed to spawn, such as entrances, exits, or save rooms.

UI System

Insert image / video of journal here.

Tomb of Khaibit is very UI-heavy for a 2D game. Each player has a Journal with many pages of different information, including Inventory, Spells, a Map, and more. Players also have a HUD that shows their actively equipped items, health, mana, and joystick for movement. Of course, there are also menus, multiplayer lobbies and so much more.

With so much complexity, I wanted to create a simple solution that made creating UI elements easy and communicating between them a breeze. I also wanted to use the Observable/Observer pattern so that GameObjects would never need to know anything about the UI.

With these goals in mind, I created a flexible solution which I will outline in overview. I got inspiration for this solution from this Gamasutra article by Yanko Oliveira. He breaks UI down into elements of the following types: Layers, Panels, Dialogs, or Widgets.

Layer

A Layer is like a folder for UI. It groups a bunch of different elements together. For instance, in our project we have Mobile Ingame, Mobile Main Menu, and Journal Layers. A Layer carries the important task of turning various Screens (which are Layers, Panels, or Dialogs) on and off. Layers can also be nested, which helps with sub-management (our Journal Layer is nested inside the Mobile Ingame Layer).

Panels and Dialogs

Panels and Dialogs are functionally similar but semantically different. Dialogs are full-attention UI components, meaning that other dialogs must be hidden. Each page in the Journal, like the Inventory or Spells page is a Dialog, since only one page can be shown at a time. Panels, on the other hand, can be shown simultaneously or even on top of dialogs. An example of a panel is the Player's Equip Slots, which are shown for all pages in the Journal.

Widgets

Widgets are the smallest UI element, and are generally a self-contained singular element, like player's Health for example. These can be turned on and off using the Dialog or Panel that they are contained in.

itch.io

There is currently no playable prototype for the public, but it is being continuously developed and will eventually be posted on itch.io. Check regularly for updates!