#7DRL 2019, NiceRL

7DRL Challenge is a game jam with the goal of making a roguelike in seven days. Last year, I made Obliteration, which is fan-fiction for the movie Annihilation.

This year’s entry, NiceRL, has several goals.

  • Save a lot of work and get more practice with Python by using the libtcod library.
  • Flip the dungeon crawler on its head. Use the items in the dungeon to help its inhabitants, instead of killing them and haording their wealth.

I used a helpful tutorial from rogueliketutorials.com.  The code is available on GitHub, but I typed it most of it in myself, because that forced me to understand it. Do I use an underscore or a dot here? Does this function return a list or a dictionary? Those distinctions are easy to miss when copying-and-pasting, but when I type them in myself and have to solve the resulting syntax errors and crashes, I’m training myself to have good habits.

My goal of a helpful player improving the dungeon as he goes through it is inspired by Max Kreminski‘s Gardening Games Zine.  I don’t hit all the points in that zine. The player is still central because creatures can’t solve their problems alone. The space gets less interesting as t he player acts on it because once a creature is happy, there’s no more interaction available. Mechanically, using cookies to reduce a creature’s hunger to zero is identical to using arrows to reduce a monster’s HP to zero. Is changing the theme without changing the mechanics enough?

Once I had the tutorial code up and running, I started modifying it to fit my specific game. I built one emotion and one item that relieved it, then duplicated that code for two more emotions. After all that was working, I realized it was a bad idea. All the emotions behaved similarly. I collapsed them into one and added an enum to specify the emotion. A creature with with 15 units of sadness, who can be cheered by a toy is similar to a creature with 6 unit of anger, who can be soothed by a stress ball. Just make sure the type of the item matches the type of the creature. Any time I copy and paste a significant chunk of code, I have to stop and question it, because I’m probably making a mistake.

I think that systems are hard and content is easy. A flexible expressive system can handle any content one cares to throw at it, but a restrictive, clunky system will need constant tweaks and work-arounds as content exceeds its limitations. I’ve built several systems like this before, but in each case, I had a vast pool of existing content to pull in. For example, costumes at Dragon Con, or photo galleries from conventions.  Once I built the system for helping creatures with their emotional needs, I realized I needed to name all those items and all those creatures. I needed adjectives that showed escalating intensity of various emotions, and items that similarly escalated. It was much harder than I anticipated.

My content-generation worksheet

I had ideas for other kinds of improvements the player could make to the dungeon, but they were cut for time.  As you can see on the worksheet, I thought of lighting candles, arranging furniture, or repairing broken items. I actually wrote an AI for a table that looked to see if chairs were properly arranged around it. When the last chair was placed, the table became happy and threw food on the floor for the player to retrieve. Obviously not how dinner tables behave in real life, but it felt right to me. When the table is prepared, you can eat, not before.

Conveying information to the player is always vital, but especially when the game is doing something unexpected. In a standard dungeon crawler, a player may see something labeled “goblin” and know, from decades of games and novels and movies, that a goblin is hostile yet weak. But how should I deal with “peckish Sam” or “fuming Jaunita”?  Does a toy make someone less scared or less sad? A big part of roguelike tradition is not knowing how things work and learning by (painful or fatal) experimentation. I decided to err on the side of clarity. Not only will a person who is searching for a lost item will tell you what they are searching for, but if you find that item before meeting the person, the item itself will tell you who it belongs to.

A screenshot of NiceRL

Here’s what the final game looks like. Most of the screen shows an overhead view of the space. Below that, a scrolling message log details each thing that happens. On the right are stats about the player, the item the player is holding, and whatever the player hovers over with the mouse. You can see what each item does. I also have a README file listing all the inputs and explaining what each character on the map means.

So seven days after starting this project, I have a complete, playable game. It saves, loads, exits, ends when you are exhausted or when you finish all the levels. But you can’t play it. I mean, I can play it. It works, But you can’t, because you don’t have access to it. Despite all that I learned about Python and the libtcod library, I neglected to learn how to publish a Python program. The goal of 7DRL is to create and release a playable game in seven days, and I completely failed the “release” part. I forgot to even try.

So, was my 7DRL a success? Hard to say. I made a game, and it’s mostly the game I wanted to make. I learned more about Python and project management. But the game isn’t really fun to play. It’s not much to look at. It’s not challenging or deep. My verdict: the process was valuable, but the artifact is not. It’s good practice, like pages of an artist’s sketchbook that will never see the light of day. Not everything has to be glorious, and not everything has to have an audience. The important thing about this jam, to me, is that I keep working, keep trying, and keep improving.