Conveniences and conclusions. Ending the story. More abbreviations and substitutions.
last time, on let’s make IF.
Last week, I shared methods for including prefatory text, controlling when the banner text prints, and using an extension. Hopefully you found it useful! As always, new source code was made available. You can get caught up here:
authorial conveniences: formatting substitutions
As we’ve seen, we can make minor formatting adjustments to text by using built-in substitutions. For instance, including “[italic type]” in a text will cause the output that follows to print in italics. Likewise, “[roman type]” will cause output to revert to unformatted text.
How many times to we want to type that, though? Text substitutions can make our lives easier (and our fingers happier).
to say it:
say italic type.
to say rt:
say roman type.
In practice, our code would look like this:
instead of jumping:
say "It's [it]undignified[rt], jumping like that."
“[it]” and “[rt]” are my choices, you can call them whatever you want. I’ve added some others to the project, you can check the source (shared below) for more examples. As a reminder, Inform reads these “to say” substitutions in a rather strict way. They are case sensitive, so “[IT]” and “[it]” are understood as different things.
If you find yourself typing the same thing over and over again, consider making a substitution as a time saver.
player conveniences: abbreviated commands
The primary mechanic of our project is picking cards. Here’s are the relevant declarations and rules:
card-picking is an action applying to one thing.
understand "pick [something]" as card-picking.
check card-picking (this is the must pick a tarot rule):
if the noun is not a tarot:
say "That's not a card, silly!" instead.
carry out card-picking (this is the basic card-picking rule):
say "[a default fortune]";
increment the clicker of the noun;
increment the magic number;
now cnoun is the noun.
The player is not going to want to type “pick blue” again and again, let alone “pick blue card.” Let’s work up some abbreviations. There are a lot of ways to approach this, but I’m going to handle this with individual rules for each card. By now, this should be familiar territory.
choosing a red card is an action applying to nothing.
understand "r" as choosing a red card.
understand "red" as choosing a red card.
instead of choosing a red card:
try card-picking an redc.
There isn’t much to the action. It just allows us to add some abbreviated commands (“red” and “r”) for the player.
There are a couple of hitches, though. Whenever making one-letter abbreviations, double-check to make sure they aren’t already used for something else. In our case, “o” (for orange) is already an abbreviation for “oops.” The “oops” command has mostly fallen out of practice for modern interpreters, since the arrow keys can be used to cycle through and edit previous commands. I’m comfortable remapping “o” for our own usage. There’s not a lot to that. Before creating our own action, we just need to code to remove the current mapping:
understand the command "o" as something new.
With that, we can do what we want. That’s not all, though. “g” on the other hand, is used often, so we should leave it alone.
With that being so, I will change my “green card” (greenc) to a “yellow card” (yellowc), updating my code and tables to reflect this. You may have noticed that even “y” is a built-in abbreviation for “yes,” but by default that is blocked in the standard rules. It should be safe for us to remap.
Important: be sure to think things through before changing commonly used commands. A lot of parser gameplay is based on conventions, and players may resent changes. As always, playtesting is the best way to confirm your decisions.
player conveniences: choosing a random card.
As a last way to abbreviate input, let’s add support for choosing a card at random. We can make another action easily, but how is the card randomized. The beginning is easy enough, and using a local variable is the best way to get started. Since we have a kind (“tarot”) that characterizes our cards, we can say things like
let rc be a random tarot in the location.
There’s a problem, though. “In the location” means a very specific thing: something on the floor, basically. The tarot can’t be held by the player, for instance, or in a container. In our project, the cards are on a table, which means they aren’t technically in the location, even though the table is. There are two routes we can take. One is all encompassing, meaning that the card can be in the room, or in something else in the room, or in something that is in the room (inside a bag held by the player, for instance). The magic word is “enclosed.”
let rc be a random tarot enclosed by the location.
We may wish to be more specific.
let rc be a random tarot on the table.
Sometimes these distinctions are meaningful. Keep an eye on them, as they can afford a comfortable home for bugs! Here, we are relatively safe because we will prevent players from taking cards in code, and there is only one location in our project. INSTEAD rules are perfect for this kind of thing, since we are, quite literally, instructing Inform to do one thing instead of another.
The whole construction looks like this:
r-picking is an action applying to nothing.
understand "pick card" as r-picking.
instead of r-picking:
let rt be a random tarot on the table;
say "[the random remark]";
try card-picking rt.
to say the random remark:
say "a placeholder for randomness."
This will print some text, “[the random remark]”, before choosing a card. I’m using substitutions whenever possible for output, because we may well want something complex or variable in our final project.
Let’s say we want to go further. What if we want our program to interpret a blank line (simply pressing the Enter key) as picking a random card? We’ll need another extension for that, “Undo Output Control” by Nathanael Nerode (with some help from others). We’ll have to download it first. Currently, the best place to find extensions for Inform 10 (the current version) is the “Friends of Inform” repository (https://github.com/i7/extensions). These are organized by name, so we can find it by scrolling down to the author’s name. If you aren’t familiar with github: you want to download the extension rather than opening it, since opening it will present a version for reading (i.e., non-working).
After downloading it, you can install it. Within the programming environment (IDE), simply select “install extension” from the “file” dropdown menu at top left.
The extension does a lot (as always, you can scroll to the bottom to read the documentation), but right now all we want to do is set up our project to redirect a blank to command to the “pick card” command:
include undo output control by nathanael nerode.
rule for repairing an empty command:
change the text of the player's command to "pick card".
There. That’s it! That’s the last of our conveniences for today.
ending things.
As we discussed last time, we need to end our story after the player has chosen eight cards. Since our counter (the magic number) increments after the card is drawn, that would mean that the magic number would be nine. Right now, all of our tables are numbered one through eight. Would it be confusing to handle a nine in our code? This will ultimately be a straightforward work, so probably not. We have other options, though. We could increase the magic number with an every turn rule, for instance, since those occur at the very end of action processing.
Let’s keep all of that in mind, while sticking to the most straightforward path. I think an AFTER or REPORT rule would make the most sense. Let’s go with AFTER for now, since by default it will shut down any loose REPORT rules floating around.
after card-picking when the magic number is 9:
end the story finally saying "[the final blurb]"
to say the final blurb:
say "A Placeholder"
As always, I am using substitutions to leave room for future variations. A story can be ended, or it can be ended “finally”. Some post-game options are only available to players when a story ends “finally”. For us, it won’t matter, as there is only a final ending, but sometimes a person beating a game ought to have more options than someone dying in the middle would.
That’s not all. Just as we can say “WHEN PLAY BEGINS,” so can we say “WHEN PLAY ENDS.” Such rules are processed immediately before the story-ending blurb and menu print.
when play ends:
say the epitaph.
to say the epitaph:
say "Wow! You got the [italic type]xxx[roman type] ending!"
Out game isn’t yet saying a lot, but it is filled with potential for saying things. I’ll do a quick playthrough using only the ENTER key (sorry I can’t collapse this, plugins are a paid feature–“business-tier”–on WordPress).
Portrait With Wolf ^_^
A fun activity by Drew Cook
Release 0 / Serial number 240930 / Inform 7 v10.1.2 / D
A Brightly Lit Room!
A bare place. A bright light emerges from an unknown source above.
A small metal table stands under the light. It is covered in gray, chipped paint. The following items rest atop it:
a red card
a blue card
a yellow card
an orange card
>
a placeholder for randomness.
green.
>
a placeholder for randomness.
blue.
>
a placeholder for randomness.
red 3.
>
a placeholder for randomness.
orange.
>
a placeholder for randomness.
green.
>
a placeholder for randomness.
green.
>
a placeholder for randomness.
blue.
>
a placeholder for randomness.
orange.
Wow! You got the xxx ending!
*** A Placeholder ***
Would you like to RESTART, RESTORE a saved game, QUIT or UNDO the last command?
>
Not bad. Note that I’ve added line breaks after the color prints to preserve Inform’s standard spacing.
We aren’t done yet. In fact, there’s tons to do:
- Implementing multiple endings.
- Building out tables for everything that varies.
- Make some other things variable (card names, room description, and so forth).
- Helping the player track which cards have been chosen.
- Dealing with all of the default parser stuff (77 standard rules verbs, parser errors, handling ambiguity).
- Considering the “form” of the printed page or interface.
If you are following along, you may wish to experiment adding your own text to the fortune tables (“table of red fortunes” and the like), just to get a feel for how things will go.
next.
Card-counting, and a framework for multiple endings.
One response to “let’s write IF #9: refinements and endings”
-

[…] let’s write IF #9: refinements and endings […]
LikeLike

Leave a comment