Updated Beta Release

An updated beta is now ready, and baring any bug reports will be upgraded to a formal release. This release is mostly backwards compatible, with the exception of midriff being renamed to abdomen. The major changes are:

  • A new extension to support posturing has been added.
  • Midriff renamed to abdomen.
  • Support for secret doors in Directionality.
  • Improved functionality for clearing conversation cues and dialogue entries.
  • Updated documentation.
  • Some minor bugfixes.

The release is available on GitHub and as a direct download. To install, download the file(s) (unzipping as necessary) and follow the instructions in the enclosed readme file.

Example Game: The Photo Shoot by Mister Flibble

Mister Flibble, who has previously written the Magician’s Nephew, just released a new game that uses the previous incarnation of this AIF Framework. To quote the man himself, I wrote this to try out some new libraries and different ways of doing conversation and it grew into something actually worth releasing. He has graciously released it along with the sourcecode, allowing us to see the inner workings. (You will have some problems compiling it though, as it relies on some custom extensions as well as the deprecated version of this framework, which is still available.)

The game and sourcecode can be downloaded here (v1.0).

Tutorial (5): Storycrafting

Section 7.5 – Storycrafting

This tutorial has so far been mostly focused on the technical aspects of how to implement a story in Inform through locations with inventory. This will continue in the next installment which will deal with how Inform uses rules to implement logic programming. First we’ll take a look at how to get started with writing the actual story. There are some questions you should ask yourself when starting out:

  • What is your setting, and what mood and level of detail fits?
  • How should the player’s interest and focus be maintained during the story?
  • How should I start writing the story?

Let’s start with the last question first, as it’s perhaps the easiest to understand and it lays the foundation for your workflow. Every author has their own workflow so you need to find what works for you, but there are some general approaches. Implementation is the process of converting your ideas into code, and Emily Short has written a good article covering some strategies for implementing interactive fiction. I recommend you take the time to read the article, as although this text is inspired by it we’re not going to cover it in detail.

The most basic strategy (which Emily calls ‘Implement first! Design later!’) is just to start at the beginning, implementing the ideas as they come to you. This can be a great process for learning how to work with your tools, but as a storycrafting workflow it has some issues. Maintaining forward momentum in the story is hard without a properly defined flow to the story, and it’s easy to get lost in all the alternative story branches you can see. The easy fix is to decide on the ending and start working backwards, but it can still be challenging to make it back to the start. Another issue that’s common to both all linear workflows regardless of direction is that the first parts written usually have greater descriptive detail but less mechanical detail, while the opposite is true for the latter stages. This is a result of your skills improving with experience, leading to more satisfying mechanics. At the same time your focus shifts to ‘what else can I add’ to ‘getting it done’. It’s therefore important to return to the early parts later on to ensure some consistency in details across the story.

At the other end is writing out the entire transcript for your story; what should the player type to progress and what are the responses? The major benefit of this approach is that you always have a clear idea of what the player *should* be doing to progress at any stage, but it’s easy to overlook what the player *could* be doing. The downside is that you’re basically writing the entire story before you know what mechanics you’re capable of implementing.

In practice your process would probably lie somewhere in between these two extremes, but some form of planning is essential. Personally I prefer to start by writing the walkthrough for the game, InvisiClues-style (*). This helps me focus on the player’s experience; what are the obstacles to overcome and how should the solution be hinted at, while still leaving room for misdirects and optional sub-plots. It also naturally breaks down the story into manageable chunks and puts some distance between your intentions and the implementing mechanics. This last point is important as you’re not wasting energy writing descriptions for actions you’re unable to implement or change your mind about.

(*) A form of walkthrough focused on giving hints instead of a step-by-step solution. Some examples.

If you’ve come this far into the tutorial you most likely have some ideas about the story you want to write. Before starting implementation it’s important to know what you want to achieve and what’s fitting for the story. This could be either specific characters (real or fictional) or entire settings (fan-fiction or your own), or even more abstract concepts you want to explore.

The mood of the story is one of the easier considerations which has far reaching consequences. A realistic story has to employ different techniques and effects to appear serious than a comedic story which can afford to be more loose. Regardless of the mood it’s still important for the logic to stay consistent within the context of the story. Related to this is finding the correct level of detail for your story. There are no simple and correct answers to what is correct, both in regards to rooms and contents.

Lastly we’ll try to answer the important but difficult question of how to maintain the player’s interest. Unfortunately there is no single answer as every player is different, but it’s still very important to keep the player’s motivation in mind. While some freeform exploration can be interesting, the player should always have an idea of what they are trying to achieve as well as what’s keeping that from happening. Searching for the solution to puzzles can be frustrating enough without first having to find out what the puzzle is. A good approach is to consider both what is a good puzzle with a solution that makes sense in the context of the story, as well as how the player should be clued in to discovering the solution.

Tutorial (4): Assorted Things

In the previous discussion on geography we briefly talked about the items that populate a story world. It’s possible to broadly divide these in two main categories: things that exist to describe the story world and things that exist as part of puzzles for the player to solve. Hopefully the distinction between these categories should not always be apparent for the player, who would use ‘ordinary world’ items to solve the challenges presented by the story. While it’s easy to determine how many puzzle items to include (answer: whatever you feel is necessary), it’s much harder to settle on a correct amount of ‘normal world’ items. We briefly covered this when speaking about rooms, but it’s important enough to bear repeating.
My personal preference is that every item that’s notable enough to get mentioned in the room description should have a corresponding item. The detail level in that item’s description should be tailored to how important and relevant it is; it’s even ok to have a bland ‘That’s not very important’ description for items that are obvious fluff.

Another consideration is the players behavior: It’s hard to anticipate all the crazy stuff your players will try, which is why feedback from testers is very important. At the bare minimum you should consider that most players will pick up anything that isn’t nailed down, and some will actively try to pry out the nails. In other words, make sure that you either account for the player moving stuff around or ensure there is a reason why they can’t move it. Adult stories have some extra considerations here, namely clothing and body parts. Most of the intricacies here are handled by using this extension, and a later chapter dealing with actors will go into more detail on how to implement them. For now you should focus mainly on which body parts and garments you want included and how to describe them.

The rest of this tutorial installment goes into rather deep technical detail for Inform 7. Most of the subjects brought up here will make more sense later on, but it’s still important to be introduced to them in order to recognize the concepts later on. Not every thing in a story should be treated the same, and the primary form of differentiation is ‘kinds’ which closely resemble classes of other languages. Besides rooms, the most important kind in Inform is ‘thing’, and most everything you use will be a kind of thing (with the notable expection of rooms and directions). Inform has a concept of the following default kinds:

  • persons – including the player
  • containers – can contain other things inside
  • supporters – can support other things on top
  • devices – has a state that can be switched on/off
  • doors – room connector that can impede travel
  • backdrop – distant things that shouldn’t be interacted with

These kinds have various properties assigned to them to suit their purpose. Not all properties are available for all kinds though, the ‘openable’ and ‘open/closed’ properties for instance are only available for containers and doors (by default). The following is a short overview of the most important properties and what they apply to, focusing on the properties available in standard Inform7. For a full overview of properties you should look at the ‘kinds’ part of the Index tab.

  • Edible: Defined for all things and governs if the thing can be eaten, implemented by the ‘eat’ action (removing it from play).
  • Portable/fixed in place: Defined for all things and governs if the player can carry the thing in question, as implemented by the ‘take’ action. Defaults to portable except for doors, scenery, supports and people.
  • Scenery: Defined for all things to mark that which the player is not likely to interact directly with.
  • Wearable: Defined for all things and governs if the thing can be worn, as implemented by the ‘wear’ and ‘take off’ actions.
  • Transparent/Opaque: Defined for containers and governs whether the contents of the container is visible even when closed. Also used by this extension to govern if a garment blocks vision to underlying garments.
  • Enterable: Defined for containers and supporters and governs whether a person can use the ‘enter’ action to be inside of them.
  • Openable: Defined for doors and containers and governs whether the item is a valid target for the ‘open’ and ‘close’ actions. Doors default to openable while contains do not, unless it defined as open.
  • Open/closed: A state variable related to ‘openable’.
  • Lockable: Defined for doors and containers and governs whether the item is a valid target for the ‘lock’ and ‘unlock with’ actions. Defaults to lockable if the item is locked.
  • Locked/unlocked: A state variable related top ‘lockable’.
  • Matching Key: A reference to the item which acts as a key and can be used to unlock.

One feature of many object oriented languages is the ability to inherit properties from from multiple parents, where this ancestry would be a kind of property onto itself. Instead of allowing multiple inheritance, Inform treats properties which share the name to be the same property regardless of the kind it is defined for. This can be confusing for a programmer who is used to having a thing inherit the ‘openable’ interface to flag it for the correct actions and inherit the open/closed state. In the natural language style it’s more intuitive to state that a thing is open and then infer that it must also be able to be opened. Actions in Inform (such as ‘opening’ and ‘locking’) makes use of properties, with the effect that they work on any thing which provides the correct properties (such as doors and containers).

Inform uses references between compontents called ‘relation’ to build and maintain its world model, which a story author will mainly used for defining or checking where something is. Chapter 13 of ‘Writing with Inform’ is devoted to relations, and for the most part the names makes them easy to understand, but section 13.3 has a good overview of the most commonly used. A person can ‘have’ a thing, which is actually they union of the two relations ‘carry’ and ‘wear’. With containers and supporters things can also be in ‘in’ or ‘on’ something else, with ‘contained by’ as the combined relation that covers both. We can also have assemblies where something is ‘part of’ something else (in which case it is ‘enclosed by’ that part), of which body parts is the most pertinent example at hand. Inform will assume that you’re speaking about the player if you give no reference to which person, so the condition ‘if the hat is worn’ actually reads ‘if the hat is worn by the player’.

Beta Release

For most of the last year I’ve been working on remaking the old AIF Library into an improved extension for Erotic Storytelling. While most of it’s been available in a working state on GitHub for a while, now is finally the time for a formal beta release:

  • Erotic Storytelling: The main extension, providing:
    • System for layered clothing,with templates for garments and body parts
    • Erotic Actions are (might contain some bugs still)
    • Consent rules for actions affecting other actors, similar to how persuasion rules work
    • Optional Discrete Arousal-based Consent and Stimulation (DACS) for TADS-style arousal (Mainly untested)
    • Various out-of-world functions for testing and warning the player of the contents of the story
    • Full documentation in the IDE, including a tutorial (work in progress)
  • Template: Illustrating how a story can be organized
  • Simple Conversations: A conversation model based on ‘talk to’ actions and table-based dialogue options
  • Directionality: Automatic listing of all room exits

The release is available on GitHub and as a direct download. To install, download the file(s) (unzipping as necessary) and follow the instructions in the enclosed readme file.

Tutorial (3): Technicalities

Your regular programming will resume shortly, but first a short interlude on some of the technicalities and peculiarities of Inform 7. Inform’s IDE has some handy shortcuts (on Windows at least): F5 will compile and launch your story, while F9 will compile and replay the last game: Excellent for debugging. F7 on the other hand will just compile and rebuild the built-in index tab which is a great resource while developing. It’s a good habit to compile often as it can be daunting to debug larger code changes even if the compiler is good at pointing out what went wrong.

As we’ve seen earlier, source code in Inform is written in natural language, but that doesn’t mean it actually understands English. Just like any other programming language Inform has a rather strict syntax to follow, it’s just that Inform’s syntax is easy to read. Anything Inform should recognize as text should be written inside double-quotes, and single quotes inside a text is converted to double-quotes when bordering whitespace. Anything written inside square brackets in a text is considered to be substitutions, while square brackets elsewhere is considered to be comments.

Unlike many other programming languages (such as TADS, other C-like derivations, and even Inform 6), Inform 7 is limited to only one source file. In lieu of dividing the source into several files, I7 uses five ‘header’ types for organizing your code into modules. In decreasing order of magnitude, these headers are Volume – Book – Part – Chapter – Section, or in a easy-to-remember mnemonic: Very Bad People Choose Satan. Exactly how to divide your code with these headings is largely up to each author, but a template project setup based on my personal preferences is included herein. My personal preference is to use ‘chapter’ as the main holder of sourcecode, divided into sections as needed and using ‘volume/book/part’ for hierarchical organization.

Structuring the source code with these headers has three main effects, the first of which should be pretty obvious. By building a hierarchy of headings it’s easy to place related content near each other, using the interface’s overview to jump around. The second effect is less obvious, and related to a feature we briefly covered before: the ‘Use unabbreviated object names’ phrase. When this use option is not enabled we’re allowed to refer to objects in our source by abbreviated names, such as referencing the ‘kitchen table’ by just ‘table’. If an abbreviated name could be taken to refer to multiple objects (for instance a ‘coffee table’ as well), Inform uses the hierarchy of headings to select the closest match. My personal preference is using unabbreviated object names, which avoids mishaps when re-arranging code. Lastly, Inform also uses these header to tell you where a compile error was detected.

To help debugging your story Inform supplies a variety of testing commands as well as the option of easily creating test cases and special actions that are removed from the final release. The default testing actions included in Inform is:

  • ACTIONS on/off: Toggles the printing of exactly which actions are processed, as well as printing the name of any failed rules without swamping the output.
  • RULES on/off: Toggles the printing of all rules being consulted for a very detailed and verbose feedback only recommended for ferreting out tricky bugs.
  • SHOWME object: Lists out all of the properties for the given object as they appear at the current runtime state.
  • PURLOIN object: Moves the object from anywhere in the world model into the player’s inventory.
  • GONEAR object: Moved the player as close as possible to the given object anywhere in the world model.
  • SCOPE: Lists out all of the objects that are currently in scope for the player to interact with.
  • RELATIONS: Lists out all the various kinds of relations that are in use in the game.
  • SHOW RELATION relationship: Lists out the details of a specific relations, as detailed in 13.7 of ‘Writing with Inform’.

This extension also provides a ‘debug examine’ action (shortened to ‘DEX‘) to provide detailed information on the kinds most relevant to AIF: garments, body parts and persons. It’s also possible to write both test cases and special commands only available during testing, which can be used to artificially set story progression variables. Test cases can be written by the phrase ‘TEST testname WITH “actions / separated / by / slashes”.’, allowing you to write ‘TEST testname’ during play to execute the given actions in order. To create commands only available for testing you can mark one of the source headers as ‘Not For Release’, which is described in chapter 2.9 of ‘Writing with Inform’.

It’s very important to take the time to explore your world and experience it as a player would. One of the harder parts to test is when connections between room differs from the room description. To help test this you could use the included extension ‘Directionality’ which auto-generates a description of the available exits in a room.

Before moving on to some more programming in Inform, I would recommend exploring various tabs in the IDE, especially ‘Index’ which gives a helpful overview of your story world.

Tutorial (2): Geography

Upon starting Inform for the first time, you’re prompted to create your first project by entering a title and author for your story as well as a place to store it. The title and author is used to create the title line of your new story, which is one half of Inform’s absolute minimum for a story. Every story needs somewhere to take place and a player to experience it, Inform is happy to supply you with a default player but you need to define atleast one room. Thankfully, due to Inform’s natural language syntax this is as simple as writing a declaration that something is a room, such as stating that ‘Library is a room.’ Unless informed otherwise, Inform assumes that the first room created is the starting location for the story. While this will compile (try copying the text over to your story, and press F5 to run), it makes for perhaps the most boring story ever written. The only description present is the title of the room, and while Inform has a built-in understanding of quite a few verbs, they won’t do anything interesting.

Before we start making the world more interesting, it’s time to introduce some of the basic properties in Inform. We’ve actually already seen two of them in action despite only writing the single statement ‘Library is a room.’ This statement creates the object name which we use to refer to the object in the source code, and is also used as the default value of the ‘printed name’ property which is printed to the player. By default Inform allows the author to use abbreviated object names, but can be forced to only accept fully qualified names through the ‘Use unabbreviated object names’ phrase. Going one step further, the object’s name is also what the parser tries to match the player’s input to. This can be altered in two ways; either by using the ‘understand’ phrase to assign synonyms for the player or by declaring the object to be privately-named to prevent the player from refering to it by object name. This latter purpose is an advanced effect mostly for objects that have complicated names that would otherwise confuse Inform.

There are two other properties which are similar but different, and are very important: Description and initial appearance. Initial appearance is how the item is presented to the player during the story, and for a room this is actually the description. Similarly to declaring objects properties values are set by statements that simply state what they are, like ‘The initial appearance of Library is “Seemingly endless rows of bookshelves fill the room.”‘ Writing the initial appearance of a room is such a common occurence that Inform has a special syntax for it: Text enclosed in double-quotes just after the object declaration is interpreted as the initial appearance property.

Writing good descriptions for the locations in a story is not an easy task, even trying to define what is a good description is tricky as not every location has the same requirements. A lot can be written about descriptions, and Stephen Granade has written an excellent article on the subject. Long descriptions aren’t necessarily better than short, it’s usually better to focus on what you intend the story to tell the player and how to draw attention to the correct objects. It’s also important to keep a consistent level of detail, or atleast only deviate from the default level with a conscious decision. Another issue to consider is that while Library’s appearance implies the existence of bookshelves, the player can’t interact with them in any way because they aren’t defined in any way. Defining new things is once again as simple as stating where they are, anything that isn’t given a kind is implied to be a thing.
With this in mind we can create a slightly more interesting library (copy the text below into your story):

Library is a room. "Seemingly endless rows of bookshelves fill the room."
Some bookshelves are in Library.

Testing this short story will show that we can indeed interact with the bookshelves, but there are two problems: Firstly, the bookshelves are also listed both in the room’s appearance and indepentendly afterwards. Although we refered to the bookshelves in the appearance, we did so in a way that was only humanly readable, and Inform lists any unmentioned objects that are present in the room separately. In order to let Inform know that the object has been mentioned, we can use what’s called text substitution: By making Inform print the name of the object that object will be flagged as mentioned so there’s no need for a second mention. Text substitutions are made by writing the substitution inside square brackets inside the text string, and writing the object name will substitute in the printed name. I find it a good practice to write in these substitutions while writing the initial appearance of the room as a reminder to create the mentioned objects.

The second problem is less immediately apparant, as all things are by default portable, the player can pick up the bookshelves. This is easily remedied by setting the already mentioned ‘portable’ property and it’s opposite ‘fixed in place’, but there is another solution. For things that are intended to decorate a room, we have the aptly named ‘scenery’ which defaults to being fixed in place. More importantly though, a scenery is usually omitted from the listing of unmentioned things in a room and thus is an alternative solution to the duplicate mentions we discussed above. If we need a scenery to be in multiple places at once (such as the sky or the ground, or the vision of something far away) we can use backdrop instead of scenery.

For all of what we’ve written so far we still only have the one room, albeit with some scenery. Unsurprisingly we can add new rooms in relation to existing rooms by stating where they are in relation, and because only rooms can be related to each other by directions we don’t even have to state that they are room. By default Inform is aware of the eight cardinal directions, as well as up/down and inside/outside. Inform also assumes that directions are two-way, and automatically creates the reverse for you unless told otherwise. It’s possible to create twisting, secret or one-way passages as well, but this is an advanced topic we’re leaving for another time.

Settling on the correct amount of locations for a story is a hard challenge. When mapping out a ‘known’ location such as a house, there are certain locations the player would expect to find but that serve no real purpose. Another challenge is ‘connetion’ rooms whose main purpose is to link together the more interesting locations. By clever use of room descriptions and the ‘before’ and ‘instead’ rulebooks it’s possible to give the player the impression of a larger world than what is implemented.

Include Erotic Storytelling by Fictitious Frode.
The player is wearing an outfit called your clothes.

Living Room is a room.
"At the heart of your house is your living room, with it's large 
flatscreen TV and soft couch. Refreshments can be had in the 
kitchen to the north, and a small hallway leads east towards the 
bedroom. A small bathroom lies to the west, and the front door 
is to the south."

Before going east in Living Room, say "You pass through the 
hallway and enter your bedroom."
Instead of going west in Living Room, say "You don't have a 
pressing need to go visit the bathroom."

The front door is a closed door. It is south of Living Room.
Instead of opening front door, say "You'd rather stay home tonight."

Kitchen is north of Living Room.
"Your kitchen is small but functional, containing cupboards, an 
oven and a stocked fridge. As you consume most of your meals in the 
living room to the south, you've never seen the need for a kitchen 
table."

Bedroom is east of Living Room. The decency threshold is indecent.
"This is where you sleep, and the mess in the room makes it hard to 
do anything else in here."
Before going west in Bedroom, say "You pass through the hall on your 
way back to the living room."

This example illustrates another small complication introduced by this extension, as it contains the notion of decency. In order to stop the player from running around in an inappropriate state of dress, each room has a decency threshold which defaults to ‘casual’ but the naked player is ‘indecent’. This can make testing the game a small annoyance at first, but one that can be easily remedied by giving the player an outfit to wear.