(hide navigation)
  • Swedish content
Fund my projects
Patreon
Steady
Don't miss
Page thumbnail
Getting numeric input (TI-83 assembly programming)
Forum
Register
Log in
Latest comments
Syndication
RSS feed
Feedback

Post Scriptum

The Impossible Bottle

Note: This is a rather lengthy author's note for The Impossible Bottle. There are spoilers, so please play the game first.

Wow! Tied 1st place! I certainly wasn't prepared for that. When the reviews started appearing, I was happy to see an overall positive vibe, but there were of course also negative comments. And there were lots of other entries that would have been worthy winners.

I admit, though, that I had set out to make a game that would place well in the competition—more so than last year, when I went in a more experimental direction. The Impossible Bottle checks a number of boxes that you often associate with top-ranking IFComp entries (lighthearted, whimsical, big, parser-based, mostly traditional but with a new twist).

I had also decided from the beginning that I would listen carefully to my beta testers and give more weight to their opinions than my own. That was maybe a little wide-eyed, and in practice there were cases where I stuck to my vision, but only after careful consideration. On the whole, the testers had a huge influence on how this game turned out. So thank you once again: Mathbrush, Mike Carletta, fos1, Hanon Ondricek, Mike Russo, Christopher Merriner, Arthur DiBianca, and my dearest Gabriella!

This year, I approached my testers serially: Each person would see a new version of the game, and thus be able to stand on the shoulders of their predecessors and spot increasingly obscure bugs. Occasionally, this had amusing consequences: One tester suggested a change that I dutifully and painstakingly implemented only to have the next tester suggest that I change it to the way it had been before.

The game is available in a web version, with clickable links. But at its heart, it is a regular parser game, and the earliest versions were compiled for the Z-machine. The first few testers only got to play it in that form; I wanted to ensure that it worked in a plaintext environment so it would be playable with a screen reader. Once I added hyperlinks, I started playing the game in a web browser; and as a side-effect of switching to a different presentation model, I was able to look at the work with fresh eyes.

Spoilers follow! Please play the game before reading any further.

For the last three years, I've been putting the finishing touches on my IFComp entries during late summer nights, in a caravan, while the kids are sleeping. This year, due to covid-19, we could only travel a short distance from home, but this gave us an opportunity to explore some of the local attractions. One of them was a zoo, and I was delighted to get an unexpected opportunity—in between those nocturnal sessions of hacking on The Impossible Bottle—to see these particular critters in real life:

Capybaras.
Capybaras in Ystad Djurpark, southern Sweden.

The central gimmick

The development of The Impossible Bottle was mainly driven by the idea of the central puzzle mechanic, the dollhouse. But it wasn't obvious from the start exactly how that mechanic would work.

It all began with a vague idea about a story set on a map with a cycle in it, and if you went around in one direction you'd gradually become larger, and if you went in the other direction you'd gradually become smaller. That would imply that you had a relative size compared to objects strewn about in the environment, and you'd be able to move things around to change their sizes with respect to each other. Then I reckoned it would be a lot easier if there was a sharp boundary at one point of the cycle, such that if you climbed through a hole you'd find yourself back where you started, but everything would be bigger (or smaller). Then I tweaked that notion into some kind of open window providing access to a miniature world on the other side. And finally, at some point, I realized that it would be like playing with a scale model, such as a dollhouse.

That's when I started coding. The underlying technique is actually very simple: Every item in the game world is implemented by a set of objects, described at different sizes relative to the observer (tiny, small, large, huge...), that are taken in and out of play as necessary.

I knew early on that I had to place the dollhouse in a back room, to prevent the player from putting things inside the room they were currently in. That would have involved a huge hand appearing through the fourth wall and putting stuff on the floor, or even picking up the player character itself. So I settled on the arrangement with four front rooms with painted doorways on the back. That also created a clean boundary where the necessary sleight-of-hand could be carried out: When Emma enters her room, every object in each of the four front rooms—if it has a smaller counterpart—is removed from play, while the smaller version is inserted into the appropriate dollhouse compartment. Then the same is done recursively for all of their descendants in the object tree. And when Emma leaves her room, every object in the dollhouse—if it has a larger counterpart—is removed from play, while the larger version is placed in the corresponding room, and so on for their descendants in the object tree.

There is a second boundary, when Emma climbs up or down the ladder, that works according to the same principle, but it got implemented much later.

Some objects have internal state. For instance, a flashlight might be on or off, and a diary might be open or closed. I used after-rules to synchronize these attributes across every version of the object whenever they changed. I could just as well have done it as part of the object-swapping process.

That's basically all there is to it. Once I had this fundamental mechanism in place—this was in late 2019—I put the project on hold for a while and worked on other stuff. But I would occasionally think of puzzles that could be solved by changing the size of something. In March I sat down and started to implement them, and the codebase slowly began to grow.

The story and characters

I came up with the opening line—“Emma, be a doll...”—quite early. It would look innocent enough the first time, without the context of the dollhouse, and had the potential to be hilarious or illuminating on a second reading. From there, it was a natural step to implement an initial conversation (which later turned into a foreshadowing extravaganza) with a parent who can supply the first immediate goal for the player. The way I saw it, starting the game by cleaning up would have two benefits: You'd be motivated to explore the map while looking for toys, and you'd eventually stumble over the dollhouse in your room. Unfortunately, it's also a rather boring premise for a story, as many reviewers have rightfully remarked.

The supporting characters, too, are perhaps a bit too bland. My best excuse is that they have to act as foil for the crazy geometry and animal-based puzzles. There is some progression: Dad gradually deteriorates from chipper and patronizing to a nervous wreck, and both Mom and Nolan have a little bit of depth to them that gets revealed towards the end. But I'll concede that the only character who is given a chance to come alive is probably Emma herself.

Some reviewers have remarked that Emma is unrealistically helpful and eager to please her parents. Now, of course I don't have the final say on how to interpret the text, but please allow me to draw attention to a couple of details: Yes, you do pick up your toys, but then you immediately proceed to make an even larger mess. You play loud, obnoxious music despite being asked to keep it down. You promise to return Dad's phone when you're done with it, but you probably don't. Depending on how the story is interpreted, you might even be running around and knocking down plants from the window sills while Dad is trying to vacuum. You steal and break your brother's precious ship, and you read his diary. You tamper with the electrical installation.

But yeah, you do it all with a smile and a ribbon in your hair.

Levels of reality

Speaking of the ribbon, there's potential nightmare fuel beneath the surface of this story if you think of Emma as some kind of creepy living doll. Adventure game players will try anything when stuck on a puzzle, so it's important to include a response for when they attempt to remove their clothes. In this case, Emma's dress and leggings are sewn together, and her ribbon “doesn't seem to come off”. And did you try licking the batteries?

It's deliberately left open how much of the story is magical realism and how much is the vivid imagination of a child. Suppose, for the sake of argument, that there really is a magical dollhouse—a small house inside the real Small House, as it were. Then it's not unthinkable that there are other magical portals. So when Nolan is in his room “exploring a secret dungeon”, why should we assume that he's only playing a video game?

The Impossible Bottle contains explicit references to the Infocom game Trinity and its famous Klein bottle puzzle. Technically, the dollhouse isn't a Klein bottle because it doesn't mess with chirality (for instance by reversing east and west, which would only have given players a headache). But it has the same “impossible” property that its inside and outside are one and the same. So who built the dollhouse? Mom wrote a book about the inhabitability of self-intersecting manifolds, so I wouldn't put it past her. Her name, Felicia Small, is of course a nod to the German mathematician in question.

The ending

For a long time, I didn't know how the story would end. In my mind the Taylors were some real people who would eventually show up, and I had nebulous ideas about puzzles where you'd have to turn them into dolls and carry them around. But I was also worried that the scope of the game was getting out of hand, so it was a great relief when I suddenly thought of turning the whole thing upside down and having the Taylors arrive in doll form for the final cutscene. And by keeping the existing parts of the story more or less intact (with only a few careful adjustments to the prose) I could present it as a plot twist, along with some comedy of subverted expectations when opening the front door.

And then, the covid-19 angle was an economical way to tie everything together, justifying the delayed birthday present as well as the isolated setting where people have to stay bottled up in their homes. I think this pandemic may become a stock historical period that writers will use as a backdrop for their chamber plays and whodunnits a hundred years from now.

The puzzles

A lot of puzzles could be derived from the central dollhouse mechanic. One of my earliest ideas was to have a fire truck with a retractable ladder that would let you climb out of the house—but I put off implementing this one (and the corresponding oversized world) until quite late in the project.

One of the first puzzles I did implement had been lingering at the back of my head for a long time, but I hadn't realized it could be used in a text adventure: I had seen my daughter, who was younger than Emma at the time, use a mobile phone as a TV in a Lego house.

The sequence where you are stuck inside the bottle and have to find a way out doesn't involve the dollhouse directly (because you don't have access to it), but it's thematically related: You are resized yourself, and bottled up in a scale model inside another scale model.

Structure

Here is a dependency chart of all the puzzles and major plot points in The Impossible Bottle (click for a larger version):

Puzzle chart.

Blue lines indicate that something has to be put through the dollhouse.

I used this chart as a living document while developing the game, in order to keep track of how everything fit together, and to ensure that the overall shape was reasonably wide and non-linear. The ambition was to keep as many tracks as possible open to the player at the same time. Puzzles were often moved around and adapted to fit into their new roles.

As seen in the chart, most puzzles are associated with a Dialog object (hashtag). The game uses a per-object flag to track which puzzles have been solved. This is used to compute the current progress, which is displayed at all times in the status bar (and in response to the SCORE/PROGRESS command).

There are no alternative paths through the chart. However, the dollhouse mechanic allows for multiple approaches at the individual puzzle level. For instance, some players put the handkerchief and thimble on the miniature dining table in the dollhouse, while others use the dollhouse to produce a full-size tablecloth and vase, and put those on the actual dining table. The table itself, and thus the final scene, can be moved to any room.

An inherent problem with the dollhouse mechanism is that many puzzles require the player to have a sense of the relative sizes of objects. I didn't want to clutter the text with actual measurements, preferring comparative expressions like “as long as yourself” or “about the size of a house cat”, but even that could easily be overdone. So in the end, I erred on the side of better prose, leaving many descriptions rather vague about size. Unfortunately this means that a player can be stumped on a puzzle because they're visualizing a crucial object at the wrong size.

In-game hints

Because the game keeps track of what puzzles have been solved, the HINT command can—in principle—tell the player exactly what they need to hear in order to get past the next obstacle in the game. All the puzzles are listed in the source code in order of increasing difficulty. In response to the HINT command, the game picks the first unsolved puzzle that doesn't depend on an unsolved puzzle in turn, and prints the next entry from a series of progressively more spoilery clues for that particular puzzle.

The problem with this approach is the tacit assumption that the player will type HINT only when they have explored every corner of the game and are truly stuck on every remaining puzzle. While this makes sense from the point of view of the author who is familiar with all the puzzles, it's not necessarily helpful to the player. For instance, if the player is in Nolan's room, trying to climb various objects in order to reach the bottle, and they ask for a hint, then it would come across as rather nonsequitous if the game would tell them to go and get the potted herb from the dollhouse. Yet exactly this can happen, because as we see in the chart, finding the basil for Dad is an indirect prerequisite for getting the impossible bottle off the shelf.

So for my next game, I will attempt to build a better hint system: In response to HINT, the player should be given a list of goals (same as in the GOALS command), and asked which goal they want help with. Then, if there's no immediate action that will solve the corresponding puzzle, a subgoal is revealed—not the first thing the player has to do, but the last. This new subgoal would appear in GOALS and HINT, and be selectable for further hinting.

The midgame

The stegosaurus puzzle has been fairly criticized for being too hard. Not necessarily too hard to solve, but hard enough to disrupt the flow of the narrative. Getting rid of the unruly beast involves a multi-step sequence that you have to construct gradually, through a process of trial and error, much like the infamous babelfish puzzle from The Hitchhiker's Guide to the Galaxy. And it keeps knocking things down! Actually, I had to dial down the random knocking several times while developing the game because it was too frustrating; there's code now to prevent the most infuriating combinations, like dolls getting knocked out of the dollhouse. I couldn't bear to remove the unplanned slapstick comedy of having the microphone knocked out of the mic stand, resulting in feedback noise—but it will happen at most once in a playthrough. And it's important to keep knocking those plants down, to keep Dad busy with the vacuum cleaner until it's time for the plot to advance.

Speaking of plot devices: The missing cufflink is, I think, an atypically commonsensical puzzle that also serves to provide some depth for Dad as a character. But it's not related to the dollhouse at all. Instead, its main purpose is to allow the player to discover the tiny diary key just when the plot calls for it, without having to explicitly go on a hunt for it.

Stepping outside

And then we come to what I had originally thought would be the pièce de résistance, puzzle-wise: Figuring out that it's possible to leave the house by the fourth wall and step out onto the edge of the table. It's referred to as “think outside the box” in the dependency chart. The HELP text mentions that one puzzle cannot be solved by clicking on links; this is that puzzle. I wanted the the player to experience a great epiphany and bask in their own cleverness when they realized that this was possible—that they could indeed have done it at the very beginning of the game. Obviously an explicit link would have spoiled that.

So I made sure to put in a lot of implicit clues. For instance, there are a couple of responses suggesting that you might want to get inside the bottle. When you try, you're told that “There just might be enough room for you inside the bottle, but you are too large to squeeze through the bottleneck.” If you try again, the message is extended with: “If only you were smaller.” The HINT command was carefully prepared with clues such as “There's a place you haven't been”, “If a doll were to walk out of the dollhouse, where would it end up?”, “There's an unmentioned exit somewhere”, and eventually step-by-step instructions for getting there.

Instead, what happened to most players was that they accidentally stepped in the wrong direction while working on an unrelated puzzle. It has been quite illuminating to look at the online transcripts and see (and really notice, for once) just how much players mistype directions. Some appear to navigate by flailing around at random until they end up in the right room. But even those with a good grasp of the map do occasionally walk the wrong way—and let's not forget that even a good grasp has to be acquired, often by making mistakes and learning from them.

So in the end, the puzzle was perhaps clever on paper, but in practice most players stumbled over the solution way too early. But I tell myself that if just one single player had the intended epiphany, then it was worth the effort.

On a related note, I will never again design a game where the player gets locked into conversation every time they walk through a particular door from a central hallway.

The point-and-click interface

The Impossible Bottle is a hybrid parser/choice game. There’s a prompt where you can type commands, but there are also hyperlinks for inserting text at the prompt, and it’s possible to complete nearly all of the game using those links. Typing is generally faster, except on touch-screen devices where tapping on links is faster.

Hybrids have been attempted before, but I think my approach here is novel: Nouns can be typed on their own in order to examine them, e.g. TABLE instead of X TABLE. After the description of the table, the player is presented with a brief list of things to do with it, such as LOOK UNDER IT. These suggested actions are generally expressed with pronouns for brevity. I call them affordances: The table affords looking under it.

The game can also suggest incomplete commands like GIVE IT or PUT IT IN SOMETHING, where the indirect object is missing. Thus, if the player clicks (or types) TABLECLOTH, the game will print a description of the tablecloth and suggest (among other things) PUT IT ON SOMETHING. If the player clicks on that incomplete command, the game will ask “On what?”. Now the player can scroll to an earlier command, or all the way back to the room description, and click on TABLE—this is now interpreted as an answer to the question. So any given link always inserts the same text at the prompt, but that text is interpreted differently based on context.

A pseudo-hierarchy of actions

A good design principle for parser games in general is that it should be possible to complete them using only “natural” actions—the traditional canon of verbs that suggest themselves to any experienced parser-game player—and maybe a few special verbs that are clearly spelled out in the text. So by providing an explicit list of all the natural actions that apply, we're helping the inexperienced players on board, while not really spoiling anything for the experienced players.

If we imagine a hierarchy where the necessary actions (that are required for completing the game) are a subset of the allowed actions (that have some effect on the game world), which in turn are a subset of the understood actions (that are recognised by the parser), then the set of suggested actions would at first appear to represent an intermediate level between the necessary and the allowed actions.

But in The Impossible Bottle, the “think outside the box” puzzle would have been spoiled by an explicit link, whereas some of the suggested actions don't affect the game world, such as looking under beds; they are included only because they would suggest themselves to experienced parser-game players. Thus, the set of suggested actions can only be loosely captured by a hierarchical model, as illustrated by the dashed line in the diagram above.

The list of suggested actions can be autogenerated to a degree based on the world model, but some story-specific fine tuning is necessary. For instance, I mentioned earlier that a parser game needs to include a response for when the player attemps to remove their clothes. So, arguably, all worn items ought to afford the REMOVE IT action. But it would be unfortunate to put the player in a state of mind where undressing is a viable puzzle solution, when it's just not that kind of game. In other words, the set of afforded actions is not merely a mechanism; it also contributes to the storytelling.

Evaluation

So, if this was an experimental interface, we ought to evaluate it. Did the players prefer clicking or typing? Here is a visualization of my online transcripts for the full judging period. Each transcript documents a session (the game can be restarted several times in a single session) that begun in October or November 2020. Only transcripts with at least 20 commands are shown:

Transcript chart.

Every horizontal bar represents one transcript. Every pixel is one move. Time flows from left to right, but the pixels are stacked vertically in groups of five to keep the diagram reasonably sized. The thin grey lines indicate 500-move intervals.

If the player has managed to reach the end of the game, the entire bar is coloured khaki; otherwise it is blue.

Each command has been categorized as probably choice (light) or probably parser (dark). This classification can not be done with 100% accuracy, because the mode of input isn’t recorded in the transcript file—e.g. TAKE IT is often available as a clickable option, but it could equally well have been typed. The algorithm tends to err in favour of choice (light), which means that a speckled bar is consistent with a player who types everything in.

Note that choice-based play is expected to produce longer bars, because instead of typing e.g. PUT PILLOW ON BED you have to go through the motions of INVENTORY, PILLOW, PUT IT ON SOMETHING, BED.

Again, these are just the online transcripts. The game can also be played offline, either in a web browser or on the Z-machine (which has no hyperlinks), and I have no statistics for those use cases.

A couple of observations:

  • There’s diversity in the way players choose to interact with the game. Some stick to choice-based input, and some use typed commands throughout. Some start out clicking and switch to typing, and some go the other way. Some vacillate.
  • There is no strong correlation between preferred input mode and transcript length.
  • Nobody has completed the game with only hyperlinks, but some have done it with a large proportion of hyperlinks.
  • There’s a substantial difference in player stamina. Every blue bar represents a player giving up at some point, and there’s a huge variance in how far into the game that happens. Roughly half of all players give up after less than 250 moves.
  • Of the finished games, the shortest transcript is 624 moves, the longest is 2369 moves, and the median is 1630 moves. The length of the walkthrough is 246 moves.
  • One fighter kept going for over 4500 moves, alas without completing the game.

The game tracks progress in the status bar, but unfortunately the status bar is not preserved in the transcripts. So in the future I might implement some kind of auxiliary transcript service that logs the status bar, the input mode for each command, and perhaps timestamps—it would have been interesting to see how much wall-clock time was spent on each puzzle.

Finally, a success story: I know at least one person who came to this game with no previous parser-game experience, played it on a phone by tapping the links at first, and then gradually started to type in some of the more involved commands (like putting things on things). So at least for this player, the hybrid interface worked as a kind of tutorial introduction to parser games, even though the game itself wasn't framed as such.

A sizeable story

The Impossible Bottle is the largest Dialog game to date. The source code clocks in at over 17,000 lines (excluding the standard library), and the compiler reports that there are about 20,000 words of story text (not counting code).

On the whole, the Dialog toolchain handled the increased workload well. There was an issue with the interactive debugger eating a lot of RAM and choking on very long transcripts; this was fixed by putting a cap on the size of the undo history.

The web browser on my phone had trouble displaying large amounts of text, such as you get from a game that never clears the screen. This prompted me to add a “clear old” feature to Dialog, that lets you trim away old text but keep anything that the player hasn't had a chance to read yet.

Last, but not least, the game is too large for the Commodore 64 interpreter. I had originally hoped to be able to put a C64 game in the comp, but the storyfile outgrew a single-sided floppy disk. Hopefully I can get something to work, primarily by adding support for stories that span two disksides, but also by improving the compiler and Å-machine to reduce the size of the bytecode. The C64 is such a lovely machine to program and tinker with—in that respect it's as relevant as ever—and I can't help feeling that it ought to be capable of running the latest text adventures. Especially Dialog-based IFComp winners.

But that's a size-changing puzzle for another day.

Posted Friday 11-Dec-2020 22:59

Discuss this page

Disclaimer: I am not responsible for what people (other than myself) write in the forums. Please report any abuse, such as insults, slander, spam and illegal material, and I will take appropriate actions. Don't feed the trolls.

Jag tar inget ansvar för det som skrivs i forumet, förutom mina egna inlägg. Vänligen rapportera alla inlägg som bryter mot reglerna, så ska jag se vad jag kan göra. Som regelbrott räknas till exempel förolämpningar, förtal, spam och olagligt material. Mata inte trålarna.

Anonymous
Sat 12-Dec-2020 00:36
I love the word "nonsequitous" (:

-Pace Smith
Anonymous
Sat 20-Mar-2021 17:55
I think found a bug where I think you can get into an unwinnable state. If you drop the batteries while inside the bottle, and then try to take the batteries, you get a message about not being able to do more than one thing at once. But without the batteries you can't turn the power back on.
Anonymous
Thu 23-Sep-2021 08:48
i love reading your analyses, even if i fail to comprehend each and every point ;) you have an excellent style of prose: concise and precise, yet rich. keep on keeping on, best regards from chuinho/multistyle labs