A Postmortem for “Monkeys and Car Keys”

First: The final, post-comp cut of “Monkeys and Car Keys” should be available in the next week or so. When it is, you should be able to find it here.

Now the postmortem: The following isn’t at all what I expected to write, my preconceptions for “postmortems” having been shaped by Agile SDLC practices. Instead, this is a collection of observations I took away from the experience, a bit of a thought dump really, but it seems to align with other postmortems I’ve found in these forums.

Full disclosure: I’m writing this in early September 2025, while the charged experience of readying my game for release is still fresh. I’ve seen a small handful of transcripts already, but the reflections here aren’t biased by reviews, rankings, or forum discussions. My perspectives as I write this might be different than when I post it; however, I intend to post it as-is, mid-October, untainted by subsequent influences.

About me

For a postmortem about a game, I hesitate to focus too much on myself: Showcase the experience, not the author. But I also think the author’s history and mindset effect how the game is expressed. For the experience of writing “Monkeys and Car Keys” this is especially relevant, so I’ll include some “about me” history, distilled down to just what sets the stage for this post:

  • My introduction to text adventures was pre-Infocom, in elementary school, with “Haunted House” (1979). By today’s standards it wasn’t good, but it inspired me to learn programing at an early age and, in doing so, influenced the trajectory of my life. Years later, I uploaded my first completed game, an .EXE compiled for MS-DOS, to a local dial-up BBS on April 25th, 1993.

  • In 2000, I ran across my game on GMD, found the rec.arts.int-fiction Usenet group, and discovered Inform. For the next few years, I was moderately active in the community. I contributed a few essays, a handful of games, and a library of Inform extensions. Then life got busy, and I stepped away for a bit.

Now, a couple of decades later, I find myself poking around IF again, looking under rocks and seeing what’s changed. And a lot has. Some of the items below reflect on changes as I see them. To most of you, these will be revelations akin to “the sky is blue,” but to me these differences are surprisingly nuanced and important to understand for any author returning after an extended hiatus.

Player preferences have shifted

The “Interaction vs. Fiction” dichotomy is a familiar topic. I like to think of it as “If vs. iF”, but other labels serve equally as well: “Game vs. Story” and “Puzzle vs. Narrative” come to mind. There have always been players who prefer light-puzzles-and-heavy-story to the opposite, and vice versa; but it appears to me the distribution of the player pool has changed. When I left, puzzles were king; on my return, stories with simplified interaction are more prevalent and better received than they once were.

I suspect this change is a response to Twine, which I’ve not used but understand makes choice-based works more approachable for authors. Certainly, the prevalence of such entries has ticked up. I also recognize I’m likely conflating cause-and-effect here. Arguably, Twine came about because of player preferences; however, I still think that segment of the player pool has grown as a result. So perhaps there’s a feedback principal in play and the demand inspired the tool, which grew the demand. Regardless, the existence of Twine is clearly a good thing for the community, even if it isn’t my jam.

The influence on my approach to MaCK? As I often do, I railed against this and doubled down, tossing aside the principle of “write for your audience”: MaCK is more puzzle-centric, and less story-driven, than any of my previous works. It contains enough narrative to tie puzzles together cohesively, but the story is just a veneer over the puzzle hardwood. It is “If” rather than “iF”. I did this because I wanted to create what I like to play, and I enjoy parser-based puzzles. I also suspect this will downwardly skew voting results. I’m at peace with this.

Inform 7 has supplanted Inform 6 (duh.)

I was fortunate enough to test alpha versions of Inform 7 before it was made publicly available. It’s matured a lot since that preview, but my initial impressions remain: I think the rulebook concept is inspired, but the natural language aspect is not quite up my alley. My affinities appear to be in the minority though, as a cursory review suggests I7 entries are substantially more common than I6.

I confess to wondering how much of this is due to a misleading numbering scheme. After all, what aspiring IF developer would evaluate version 6 of a language when version 7 is available? At first glance, it isn’t obvious that I7 is not simply an update to the language (as I6 was to I5, which updated I4, etc…). But I am sidetracked by the psychology of first impressions here and may just be making excuses to defend my comfort zone.

Note: In no way am I disparaging the substantial, revolutionary work which has gone into I7. I’m just a simple puzzle piece describing what fits me.

The influence? Again, I doubled down.

I wrote MaCK in I6 because it aligns with my background. I prefer to express logic in procedural syntaxes rather than mostly declarative ones. Also, I have a lot of I6 under my belt. I love I6, and I’d like to think it loves me back.

Viewing the IF-Comp as a public beta

As I write this, the initial transcripts have started rolling in and I’ve had an epiphany of self-awareness: I don’t view the competition as the finish line. I used to. Once a competition closed, my work on the entry was also complete, but no longer. Maybe it’s the knowledge of a game’s longevity, that my earliest IF creation still sits in the archive after more than thirty years, but the lens I see these transcripts through has changed. I find I’m still thinking about ways to improve the game before I consider it “done.” To put this another way: I now liken the competition to a public beta, helping to ready a game for its final release. The comp is not the destination.

Of course, none of that means I don’t care if MaCK does well when the results are tallied; this is a competition after all. It’s just an additional perspective I didn’t have before.

Beta testers are more important than you think

My career in and around software development spans more than half my life, so the value of beta testing is well known to me. Even so, I thought my initial beta of MaCK was solid. Sure, it needed a few scenery objects, and maybe some additional synonyms, but my regression scripts ran the game all the way through to the end, so it had to be close, right? It wasn’t. Not even a little.

The game came out of the closed beta cycle significantly more mature than it went in. My testers were more helpful than I expected anyone could be and, as a corollary thought:

I think we should consider a sub-contest for authors to nominate, and vote on, the most effective beta testers.

Thoughts on quantifying difficulty

I also found it hard to objectively judge MaCK’s difficulty through my beta testers’ eyes. Testers are, of course, just players with varying levels of experience, and my cohort disagreed significantly on their assessments. I had beta testers who said the puzzles were far too difficult to enjoy while others zipped past the most complex ones with little more than a shrug.

I ended up branding the game as an “intermediate puzzler”, a warning to players of the CYOA ilk, but it left me wondering: How can I objectively determine puzzle difficulty for the average player? When and where should I hint-out puzzles without giving away the farm? Are the sorts of puzzles which elicit a flush of dopamine when the pieces fall into place really suitable for a 2-hour play window?

I’ve mulled this over and have some ideas around establishing a framework for pseudo-empirical quantification. I won’t detail my thoughts here, maybe it’s a topic worthy of another thread, but I suspect measuring difficulty starts by analyzing the puzzle dependency map. I usually make these when designing a game, regardless of the medium it lands on. For the curious, here’s a version of the one I made for MaCK (the proposed “dif”-ficulty values are not populated):

Origin of the game

The bigger concept, which I finally whittled down to MaCK, came to me before my break from IF. I scribbled the details into an idea journal, in an entry which is now old enough to drink, and ran across it recently enough that it was still in my head when I contemplated entering this competition. The story was too complex for a two-hour play window (consisting of multiple incarnations of a narcoleptic player character living across time) and generally had a deeper vein of mysticism running through it. The statues and the canopy monkeys were the only parts of that concept which made it into MaCK.

Tools I used

I made the cover art for MaCK using Procreate, on my iPad with my trusty Apple Pencil. The final compositing steps, I did in Affinity Designer on my Mac mini. For the game itself, in addition to the Inform 6 compiler and the most recent standard library, I used VS Code. A few plugins smoothed the experience out for me, such as an inline spell checker and two of Natrium729’s extensions named “Inform 6” and “IF Player.” I did additional testing using Gargoyle, Spatterlight, and Parchment.

The orLibrary 2.0b

I also used a beta version of the orLibrary, my collection of reusable bits of code which I package together to share with others. This latest refactoring (2.0) is a significant overhaul of the previous iteration (1.3) and I confess: maturing some of these revised extensions added to my motivation for entering the IF-Comp. The update needs additional eyes on it before I consider it ready to share broadly, but I mention it because @otistdog encouraged me to discuss which extensions I used (and why), should I choose to write up a post-mortem. I am, so I am.

Since I’m still fighting the losing battle of keeping this post-mortem “less long”, I’ll not discuss these deeply. I just counted and there is a total of 56 orLibrary extensions compiled into the game (most are dependencies automatically included by more functional modules), but the following eight are the ones I found most useful for this game, in alphabetical order:

orAdjective, because it makes disambiguation easier. In this game, there’s a lot of opportunity for confusing the parser. There’s a monkey army, monkey eyes, monkey mouths, monkey ears, monkey paws, a baby monkey, a yellow monkey, a blind mama monkey, three monkey statues, and other monkey stuff. At some points in the game there are six or more of these monkey-named things in scope at once. This extension, combined with a couple of others, makes managing all that just a bit easier. It took some doing, but most of the time the parser correctly infers what the player means by the word “monkey” rather than listing all possibilities for the player to clarify.

orBackdrop, because this extension makes adding scenery easier, without the need to create actual game objects.

orDialogue, because ASK/TELL/SAY is a central mechanic in MaCK, and this is a rich implementation of that paradigm.

orFirstImpressions, because I like giving initial descriptions which only make sense the first time you examine something. This extension simplifies that.

orImplicitCommands, because I like the concept of implicit actions taking game time and wanted this experimental extension to get a bit of play.

orPlayerCommandQueue, because queuing up player commands for subsequent turns has proven unexpectedly versatile, especially when generating commands referencing “fake” objects which don’t actually exist in the game world (see orBackdrops above).

orPrint, because this:

orPrint("I examined $the:noun. $i;What is this?$n I thought."); 

Is more concise than this:

print "I examined ",(the) noun,". "; 
style underline;  
print "What is this? ";  
style roman;  
print "I thought."; 

Both produce the same output:

I examined the banana. What is this? I thought.

orUtilLoopArray, because it trivializes iterating through property elements across several turns. I used this in a few places to vary responses to player actions and to make background messaging feel more random. In past efforts, I’ve considered doing this sort of thing a lot. The code to implement it each time isn’t at all difficult; however, it’s just a little too much hassle. I usually end up moving on to focus on less subtle things. This extension takes all that friction away.

The above list won’t be of much use to anyone at the moment, since orLib 2.0 isn’t broadly available, but this post will still be discoverable when it is, so I don’t consider it a waste to describe it here.

Note: I released MaCK as a Z5 file, but the orLibrary also compiles to GLULX. I had a .gblorb version which I kept in my back pocket should the work exceed Z-Machine constraints, but it didn’t at all.

Thanks

So that concludes what I have to say in this post-mortem. Overall, participating in the IF-Comp has been an enjoyable experience, and I may participate in it again when a right-sized idea pops into my head. Before I close, I want to again recognize my beta testers, beyond the in-game “credits” blurb, and further trumpet my appreciation for their help. These include, by username, @AERobert, @mathbrush, @amruf, @dsherwood, @Jade, and Sterling Fisher (who is not a member of this forum so does not have a username, but I still want to call him out for reasons which I’m sure can be guessed).

For the rest of you, thanks for reading this (and playing MaCK, if you did). If you have questions, feel free to reach out, either in this post or by DMing me.

Jim

23 Likes

Just wanted to say that I would read this thread and probably click the Like button on several of its posts.

Thanks for the thoughtful postmortem, and for a fun game!

3 Likes

I’m definitely eager to learn more about the 2.0 version of the OnyxRing library. I’ve been duly impressed both by the thinking that went into earlier versions and my encounter with a game that made use of it.

3 Likes

I’m tentatively targeting end of year for a public beta of the “orLibrary for I6 2.0”. I’d be happy to share it sooner, privately, with those who are interested, with the hope that there will be feedback to help mature it. There’s a lot of new, experimental stuff in this version which needs to be vetted and honestly, ensuring the documentation has remained accurate as the codebase has advanced has been more difficult that I assumed it would be.

@otisdog, if you are interested to see it sooner rather than later, and anyone else really, please DM me. I can probably get it ready to preview by the end of the month.

But don’t feel obligated in the slightest.

2 Likes