Course: CSCI 1400

Game Structure & Flow

The game is based on a roguelike archetype, where you have to answer PC setup related questions to move on to the next floor. Initially, I was having trouble deciding how I would integrate the PC setup aspect into the game, but I eventually decided on what I have now. I was also thinking about just making the user answer the questions, and then letting them able to play the game—but that wouldn’t make sense for the assignment, I don’t think.

I have quite a few different problems, I have them all stored in a questions.py file. For the sake of brevity, I won’t include all 300 lines (33 questions), the file is on the GitHub repository: ./src/questions.py. Each of these questions try to explore the different topics covered, with having a few different questions for each topic. For instance, the question “What is a common symptom of a memory leak? (Slow performance)”, would help users identify how to troubleshoot issues with theirs (or others) computers.

Manual

The controls can be accessed in-game through the ? key.

Movement Controls

  • W → Up
  • S → Down
  • A → Left
  • D → Right
  • Q → Up-Left
  • E → Up-Right
  • Z → Down-Left
  • C → Down-Right

Action Controls

  • G → Pickup Item
  • X → Drop Item
  • I → Inventory
  • O → Character Info
  • H → Message History
  • T → Take Stairs
  • . → Wait Turn
  • ESC → Quit Game

Reflection

I didn’t necessarily choose my theme for it to “enhance IT concepts”—since frankly, I’m not entirely sure how a theme would do that. I tried to make the game as fun as possible, that way people would want to continue to play the game (and in turn, do more of the questions and learn more). Since I’m a big fan of roguelike games, such as The Binding of Isaac I decided to base my game on that sort of style. I took a lot of inspiration from how Rogue looks, since it introduced the roguelike genre, and it was terminal-based, so I took some inspiration from it.

I encountered a few issues, especially since my game was a pretty large project (≈2900 lines 🤓). One of the main issues was just deciding on how I would actually build the project. I was initially going to use a cool such as curses, but I decided against it due to screen flickering caused by clearing the console at certain rates. Additionally, curses is pretty annoying to setup with macOS, since I would have to install the ncurses library through homebrew, and I thought that would be too much of a hassle. Also, I would have had to switch the library to windows-curses if the system was Windows, but that would be a lot of effort, especially given the screen flickering issue. (There was a work-around for screen flickering, but it would also make the user able to scroll to previous frames, which would have been even worse, arguably)

After all of that, I decided to go with the python-tcod library, which is a CFFI implementation of libtcod. This ended up being a super nice decision, especially with some of the features the library provides. For instance, the line-of-sight algorithms such as Bresenham’s Line Algorithm, which I used for determining how rooms should connect. Also, the console system included in the library made my life a lot easier. Additionally, I used numpy for the matrices within the game since they’re quicker, more memory efficient and have some extra functionality.

I learned a bit about IT support, especially when I was coming up with some of the questions. Granted, a few of the questions were generated from ChatGPT, I came up with the majority of them myself. For instance, the questions related to drivers were pretty new to me since I’ve never really had issues with drivers.

After this project, I have determined that Python has a lot of really weird decisions in their language. For example, circular imports are caused even when you’re importing a file just for their type declaration. As a result, you have to use a ridiculous combinations of imports to make it work without throwing an error:

from __future__ import annotations
from typing import TYPE_CHECKING
 
if TYPE_CHECKING:
    # now you can put your imports here...

I also learned about how Python manages virtual environments, since I had a few issues with that, specifically with the $PYTHONPATH environment variable being weird, and when I tested the game on another system, the game didn’t function properly at all, so I needed to load a different tileset depending on their resolution. Instead of specifically checking for screen resolution (since that would be kind of annoying) I just loaded a different tileset for macOS, since most macOS machines have a high enough resolution that the original (and better) tileset isn’t cut off.

xkcd 1987 - python environment