Copyright 2021 Brian Davis - CC-BY-NC-SA
Wandering Whimsy was my entry into the github 2020 GameOff. When I signed up I had a notion I wanted to make a text adventure game, loosely inspired by a trip I took to Long Beach, Washington earlier that summer. It's free to play with binaries available on itch.io and the source on github.
I initially looked at using ink as suggested by the GameOff sign up page. But it seg faulted on my Linux computer, wouldn't load under wine and I just couldn't get excited about running a windows VM for what was supposed to be fun.
Time to write my own engine. I had the idea to build a very simple game loop in python and store the world state entirely in a JSON file. Then loading/saving the world would be a simple matter of reading/writing the JSON and the code would be easy to maintain and debug. I threw together the first version in a evening and it worked pretty slick. As the project went along I extended it a little to support events, end game conditions, and a minimal amount of logic built into the world file. I was suprised at how complex a game I could create with such a minimal amount of code.
I didn't end up having time to go back and clean up the engine at all. My feeling is that, small as it is, there are still some repetition that could be factored out.
I wanted a very limited menu based interface. The game would display the descriptive text of the location and any options the player had and the player would simply choose the option. A handful of commands (save, load, quit) would be recognized everywhere.
For testing I started with a basic print/input loop. Later on I wanted to add a Qt window wrapper. I flailed around a bit with how to do that with callbacks and stumbled on the idea of turning the game engine into a generator that would yield whenever it needed input from the user. I used
send() pass user commands to the engine and
next() to get the output to display. It worked pretty neat and allowed me to keep a simple print/input loop around for testing whithout breaking the Qt wrapper that went into the published version.
See QtTerm for my notes on making QTextEdit act sort of like a terminal emulator.
Mostly the world consists of nodes that each have a description to display and optionally a menu of choices for the player. Some global flags are used for the game state and conditions can be placed on nodes in the form of simple python statements that are passed to
eval along with the world as the local namespace. This turned into a very flexible system with a very minimal amount of code.
I did end up writing a validator for the world file. JSON being so flexible is an advantage during design and a liability during construction. Its so easy to make mistakes and very hard to find them.
For a fun twist there is a point in the game where the player gets cursed by a witch and after that all text is displayed backwards. I did that just by prepending the unicode
\u202e character. That didn't work in my terminal (urxvt doesn't support unicode maybe?) but worked just fine in QTextEdit.
My wife sketched a lovely cover art and the noun project provided an icon.
I use a make.py file to build an application package for Windows, Linux and Mac. That'll get a separate write up eventually.
The folks who played it seemed to enjoy my writing which was the real focus of the project for me. The tech was secondary to the prose but still provided several opportuntities to solve interesting problems. Text games didn't get a lot of love during the jam but my main goal simply to produce a complete product, not to gain wide appeal. I feel good about how Whimsy met that goal and was fun along the way.