This is the first post in an ongoing series in which I talk about the development of “Portal Adventure”, a text-based adventure game that my 10-year-old son and I are writing in order to help him learn about programming. See other posts in this series: 2
As we worked through things, I would have to spend so much time jumping from topic to topic and explaining fundamentals that we could never focus on one area long enough for him to develop a deep understanding, and we couldn’t make enough visible progress on our idea in order to keep it exciting (for either of us). While we managed a couple of sessions, it didn’t really lead anywhere. I needed to find something a little bit simpler.
An Idea Emerges
Last week, I started playing a video game called Pillars of Eternity. Lachlan saw me playing it and asked why I enjoyed it so much, and I told him it is because I really like games that have a rich and engaging story. This got us talking about games a bit, and I recalled to him my experiences as a kid playing what is still one of my favorite computer games of all time: Zork.
As I described Zork to Lachlan, it dawned on me that creating a similar game might be a great project for us to work on together. It would have the advantage of being complex enough to provide many teaching opportunities, yet the interface to it is simple enough that he would get to see something working almost right away; no need to set up a bunch of frameworks just to get a few strings to output to the console, which is enough of a start to get the ball rolling. Plus, it’s making a game! What kid doesn’t enjoy making up games?
I proposed the idea to Lachlan, and he immediately got excited about the possibility. We kicked around a few ideas for the basics of the game and came up with a concept for the game mechanics.
Much like Zork, the player will control a character via text commands entered at a CLI prompt, and then the game will respond with the result. The game will consist of multiple locations, each with a description of the area and containing various items with which the character may interact. We may attempt to build a command-parser like the one in Zork, but we might also take the easy way out and present a list of possible actions from which the player may select. The basic options would be for moving from location to location, picking up and dropping items found throughout the game, and using items to interact with the environment.
The game will be divided into a number of levels, each of which will contain multiple locations. In order to move between levels, the player must defeat enemies and/or solve puzzles and, by doing so, unlock the portal on that level. Once a level’s portal is unlocked, the character may travel from the portal location on their current level to the portal location on any other level that has been previously unlocked. The player wins the game when they unlock the portal on the final level.
Our First Session
We had our first session of pairing on the game yesterday, and we spent around three or four hours between discussing our first steps and then getting to our first milestone. (A lot of that time, of course, was taken up with explanations about some fairly basic stuff such as “here’s how we initialize a new git repository,” and “this is the purpose of an object in object-oriented programming.”)
Starting from the outside and working our way in, we determined that our first milestone would be that we can launch the game (always as a new game at this point, we will tackle saving games down the road) and it will output a description of the starting location.
As for testing, we (well, I) decided not to try and automate any full-stack testing with something like cucumber at this point—we will perform that level of verification through hand-testing for now—and that we will do extensive unit testing with RSpec. We may try to add in full-stack acceptance testing down the road, but I wanted to make sure we had enough time to get something done-done by the end of our first session, and the milestone was simple enough to not need that level of automated verification.
While the absolute simplest/dumbest way we could meet the milestone
requirement would be to just add a
puts statement to the game
launcher, we instead took some time to think about what objects we would
need in order to implement the basic game mechanics and then implement
our first milestone in terms of (some of) those objects.
First, since we wanted to output the description of the location in which
the character starts the game, we clearly needed some type of
object with a description attribute. Easy enough.
Since we start off the game with a character in that location, we
PlayerCharacter object, and because we operate the game from
the point of view of that character, we want to get the description of
the location by having that player character inspect the location. That
last part will be important for the game mechanics, because the
description of the location that is output by the game may change
depending on certain attributes of the player character.
We would also need something to encapsulate the general state of the
game (who is the player character, what is the current location, etc.),
which we decided to call the
Universe. This object would serve as the
factory that sets up the game context and then allows us to
Finally, rather than baking into the guts of the game the assumption
that it will run in a console with access to
communication with the player, we would initialize the
Universe with a
PlayerInterface that provides a higher-order abstraction around the
player’s interaction with the game.
Next time, we will be implementing our first two commands:
quit. The former will simply display the description of the current
(and so far only) location and wait for another command, while the
latter will exit the game, returning the player to their shell prompt.
Some additional ideas that I have for the game include:
- Random Level Creation - use a database of “challenges” to randomly create each level, either at the start of the game or perhaps as each level is unlocked.
- Game DSL - rather than random level creation (or in addition to the
possibility of that?) create the game engine as something into which a
separate “game description” can be loaded, thus allowing a
content-creator to write new adventures.
- I wonder if there’s a way to use cucumber/gherkin for that? (cue evil laugh)
- Character attributes/skills - Use a D&D-like system of character
attributes and skills to influence how the player goes about solving
- Would need to be careful to ensure that it was never impossible to solve a level.
- Multi-Character Adventuring Party - Especially if using attributes/skills, we could allow the player (or perhaps players at this point) to switch between and control multiple player characters with different abilities.
Constructive Feedback Appreciated
I hope that you’ll follow along as we continue to develop Portal Adventure and eventually enjoy playing the game, too. If you have any feedback on our code or ideas about the game design, please feel free to share them as Github issues, comments on the commits, or pull requests. And although I have a pretty thick skin when it comes to…«ahem»…discussions about the best way to code things, please keep in mind that there is a 10-year-old, very green programmer working on this project and keep your feedback appropriate. :-)
Also, yes, I am aware that there are numerous libraries and frameworks out there that already allow people to create text-based adventure games; no need to point them out other than in the context of “I see you are attempting to do X. You might want to look at how something similar was done in open-source-codebase-Y.”
Remember, the main purpose of this is to help Lachlan learn about programming, not just to develop a game that we want to play.