Saturday, February 23, 2019

Enumerated Values

So here is a very simple story that I'm going to use for now, but over time I'll make refinements to it as I post more.

Concealment is a kind of value. 
Concealment are none, fairly, mostly, and completely.
Concealment is usually none.
A person has a concealment.

When play begins:
    Cover is blown in eight turns from now;
    Now concealment of the player is none.

[ROOMS]

The Employee Break Area is a room. "A break room that is clearly for employees of some company.  The walls are littered with information about minimum wage, HR regulations, and so on.[if unvisited]  You aren't exactly sure how you have come to get here, but you hear voices...  Not good voices, coming from the distance and growing closer.[otherwise]  Those voices continue to get closer.[end if]  To the east and west you see a door."

The Employee Closet is a room. "You enter the closet.  It's small and dusty, but you feel that you might be able to hide in here.  You notice the floor is somewhat uneven as you back up slowly into the closet and close the door."

The Employee Bathroom is a room. "You enter the bathroom.  It's quite roomy and you can see a lock on the door.  Clearly you could hide out in here, but for how long?  You feel a breeze coming from a half a foot high vent that is at floor level."

The Hiding Area is a room. "You creep down into the floor and into the open area underneath the closet.[if unvisited]  You feel around and feel small bars of metal, but are unable to properly identify what the metal is.  You attempt to pick up one of the small bars and notice that it has immense weight.[end if]  You slide the boarding back over the hole."

The Vent Shaft is a room.  "You crawl into the venting area.  The pipe narrows too much to go any further than maybe eight feet.  However, you turn around crawl backwards into the venting and pull the grate back over the vent."

[DIRECTIONS]

The Employee Closet is west of The Employee Break Area.

The Employee Bathroom is east of The Employee Break Area.

The Hiding Area is below the Employee Closet.

The Vent Shaft is east of The Employee Bathroom.

[CONCEALMENT]
After going to The Employee Break Area:
    Now concealment of the player is none;
    Continue the action.
    
After going to The Employee Closet:
    Now concealment of the player is fairly;
    Continue the action.
    
After going to the Employee Bathroom:
    Now concealment of the player is mostly;
    Continue the action.
    
After going to the Hiding Area:
    Now concealment of the player is mostly;
    Continue the action.
    
After going to the Vent Shaft:
    Now concealment of the player is completely;
    Continue the action.

[EVENTS]
At the time when cover is blown:
    If concealment of the player is none:
        End the story saying "No effort was made to hide from the voices.  Instead you thought you might be able to fight them off.  Turns out you were wrong.";
    If concealment of the player is fairly:
        End the story saying "You at least tried...  However, now you realize you could have done way better.";
    If concealment of the player is mostly:
        If the player is in The Hiding Area:
            End the story saying "Foolish, you hid yourself in the same place they we're hiding their gold.";
        Otherwise:
            End the story saying "A good effort to hide from the voices, but in the end it was not enough.";
    If concealment of the player is completely:
        End the story finally saying "Great job you hid form them!!".
        
    
Test me with "e/e/z/z/z/z/z/z/z".

If you've ever heard of the programming term enumerations then you'll already be familiar with the concept that I'm going to be covering here. Let's take a look at the first four lines of this story. We are defining a new kind of value called concealment on the first line. The next line indicates that there are only four valid values for concealment. None, fairly, mostly, and completely. The third line indicates a default value that will be automatically assigned. The default value is none, which makes sense, by default you aren't hiding from someone. However, the default is important here because of the fourth and final line I'll be covering. We are taking the built in kind called person and adding the ability to define a concealment to it. That means every single person by default in your story will have a concealment value. Now you might not test that value against every single person in your story, but what happens when you create a person that ultimately will have that value tested? Here is where the default value is the saving grace for us from potential future mistakes. By default concealment will be none and we will have to explicitly set the concealment on our people.

These kinds of enumerated values like concealment are great for implementing all kinds of distinct but somewhat related kinds. You might have food that can either be good, bad, spoiled, or poisoned. Or you might have a powder that can exploded, puff of smoke, or do nothing. Or you might have a guard that has not noticed you, is somewhat alert, on guard, or fully aware of your presence. There's also ways to "increment" that value upwards or downwards, but I'll have to circle back on that in my next post.

Saturday, February 16, 2019

Using a variable with future events

So I had mentioned variables before in this post. So here is a quick example of using a variable, it will also show off the every turn rule.

The moment it gets hot is a time that varies.
The moment it gets hot is initially 7:35 PM.

The Empty Art Gallery is a room. "It looks like someone took all of the art in here."
The parking lot is a room. "This is a very empty parking lot several blocks form the art gallery."

The parking lot is west of the empty art gallery.

When play begins:
    Now the time of day is 7:31 PM;
    The heat cranks in three turns from now.

Every turn:
    If the time of day is before the moment it gets hot:
        say "Such a nice day.";
    otherwise:
        say "The heat is unbearable.".
        
At the time when the heat cranks:
    Say "I think the heat is cranking up.";
    Increase the moment it gets hot by 3 minutes.
    
Test me with "z/z/z/z/z/z/z/z".

Now if you want to play around with it, you can compare how long you have to wait before the moment it gets hot to this.

The moment it gets hot is a time that varies.
The moment it gets hot is initially 7:35 PM.

The Empty Art Gallery is a room. "It looks like someone took all of the art in here."
The parking lot is a room. "This is a very empty parking lot several blocks form the art gallery."

The parking lot is west of the empty art gallery.

When play begins:
    Now the time of day is 7:31 PM.
    [The heat cranks in three turns from now.]

Every turn:
    If the time of day is before the moment it gets hot:
        say "Such a nice day.";
    otherwise:
        say "The heat is unbearable.".
        
[At the time when the heat cranks:
    Say "I think the heat is cranking up.";
    Increase the moment it gets hot by 3 minutes.]
    
Test me with "z/z/z/z/z/z/z/z".

As you can see I commented out the the heat cranks scheduled event. So the time variable that holds when the moment it gets hot never increases by three minutes.

Now you'll notice that I'm using minutes and setting explictly the time here. This is Inform time and pretty much every action, even just standing there, costs one minute. However, you can create rules that alter the default cost of time per move. You can even create rules that have some actions cost no time what-so-ever. You can see an example of this from the Recipie Book in Chapter 4 with Timeless.

Saturday, February 9, 2019

Future Events in Inform 7

One of the neat things I like to do is a puzzle that requires the solution in a certian number of turns. The way I do this is by using future events. This is covered in The Inform Book in chapter nine.

The typical syntax for an event in the future is Amazing thing happens in five turns from now. This sets the event to happen, however, you also have to describe what happens when that event actually happens. This is done with the At the time when Amazing thing happens: syntax. Here's a sample of that for a very simple task.

The Empty Art Gallery is a room. "It looks like someone took all of the art in here."

When play begins:
    Amazing thing happens in four turns from now.

At the time when amazing thing happens:
    say "All of the art suddenly appeared!".
    
Test me with "wait/wait/wait/wait/wait".

However, there's only one room here, let's see what happens when I add another room that doesn't have anything to do with the art reappearing.

The Empty Art Gallery is a room. "It looks like someone took all of the art in here."
The parking lot is a room. "This is a very empty parking lot several blocks form the art gallery."

The parking lot is west of the empty art gallery.

When play begins:
    Amazing thing happens in four turns from now.

At the time when amazing thing happens:
    say "All of the art suddenly appeared!".
    
Test me with "wait/west/wait/wait/wait".

Test it out with Test me and you will see that you're standing in the parking lot and the art appeared! Now there's several ways to solve this, the best one is to create an object called Art and then place it in the room after so many turns. Then on the first time you see it, be surprised. However, I'm not going to get that involved right now. Instead I'll just do a simple if statement.

The Empty Art Gallery is a room. "It looks like someone took all of the art in here."
The parking lot is a room. "This is a very empty parking lot several blocks form the art gallery."

The parking lot is west of the empty art gallery.

When play begins:
    Amazing thing happens in four turns from now.

At the time when amazing thing happens:
    if the player is in The Empty Art Gallery:
        say "All of the art suddenly appeared!";
    otherwise:
        say "For some reason you thought about all of the art.".
    
Test first with "wait/west/wait/wait/wait".
Test second with "wait/wait/wait/wait/wait".

Now you get a different bit of text depending on your location. I know this is a very basic example, but it demostrates the basic scheduling of tasks. In this case the timer begins as soon as the game starts, but you can also schedule the event when entering or leaving a room, talking to a person, or picking up an item. That last one is always fun!

Saturday, February 2, 2019

Data Types in Inform 7

Inform 7 stories are a collection of things. Your story is basically a telling of how those things interact with the player, what the outcome of certain actions on those things are, and so on. So starting from square one it's important to understand one of the early questions that gets asked when using Inform 7 for the first time. "What kinds of things can I put in my story?"

The kinds of things that you cna put into your story are "types". I'm going to run through the list of types in Inform 7, give a very brief description of what they're there for, and an example of it. Now you can find this same information at ifwiki.

Type Description Example
number Used for a number. X is a number that varies.
time Used for a time which is based in Inform time system.1 Deadline is a time that varies.
text Used for some text. An excuse is a time that varies.
thing Used for an object. 2 My favorite toy is a thing that varies.
person Used for a person. The current manager is a person that varies.
direction Used for a direction. The ocean currents are a direciton that varies.
room Used for a room. The best spot is a room that varies.
truth state Used for a boolean value. The light switch's boolean is a truth state that varies.
table-name Used for named tables. 3 The guru's answers are a table-name that varies.

There's also four other types that are worth mentioning, but you'll uses these type a lot less than the previously mentioned types.

Type Description Example
rulebook Used for rulebooks. 4 My secret plans are a rulebook that varies.
rule Used for rules. What works last time is a rule that varies.
text Used for text parsing. 5 My regex target is some text that varies.
stored action Used for actions. 6 An abetance is a stored action that varies.

If you've ever written, even a basic story, in Inform 7, most of the ones from the first table should seem familiar. Variables in Inform 7 can also be references to other objects within your story. Take for example the room type.

The storage shed is a room.  "Just a simple wooden shed.  It looks like whatever was once here has long since been taken."
The attached garage is room.  "An empty garage barren of anything interesting."

The attached garage is west of the storage shed.

The magic spot is a room that varies.  Now the magic spot is initially the attached garage.

In this pretty short and pointless story, we created two rooms and a reference to one of them called The magic spot. At the start The magic spot refers to The attached garage. However we can change that should something happen. Additionally, since it is magic, we could just pick up the player and plop them back to wherever The magic spot refers to, which also means that we could add rules to allow some magic incatation that moves The magic spot to whatever room the player is currently in. The that varies text is what makes the variable become a reference versus an actual instance. Note how the two rooms The storage shed and The attached garage lack the varies text and thus causes them to be actual instances of rooms that you can travel to.


  1. This is opposed to something like 7:30am we'd be used to, though 7:30am is valid but has no bearing on the real world's time, but whatever the time currently is in your story. Explaining the Inform time system will just have to be a post all of its own.

  2. An object in this sense is a subset of things that are considered "objects" in the Inform sense. A thing can be a door, container, device, or supporter. But not a backdrop or person.

  3. Named tables are great tools but can sometimes be difficult to properly add to your story. I'll need to do a post that gives them some limelight.

  4. Rules and rulebooks are all covered in Chapter 19 of the the Inform book. I'll refer most people there as diving into that topic is absolutely something I'd have to commit some time to write a post or several posts, just to give it the proper treatment it deserves.

  5. This used to be two different things. Text and Indexed Text, however in 2012 it was decided to merge the two into just text and the 6L02 release of Inform 7 in 2014 gave us our first release that used this new merged text. I recommened to everyone that they go ahead and drop Indexed Text if they haven't already been using it. However, I've placed it on this table as well as from the first to stay in line with the information from IF wiki.

  6. Stored actions are pretty much taking an action that the player does and remembering it for later. So if say the play knocks out a person in your story and then later on your player runs back into that person. If they did commit the hitting action and you stored that, then you'll be able to test that using this. However, you'll find that stored actions are more useful in temporary variables that are used in carrying out an action.

Implementing Help in a Story