top expert

i am my own ghost

Let’s Make IF #2: framing things in.

Some more thoughts on the project.

I’m excited to get started! Here are just a couple of more things that have occurred to me:

  • I’m no expert. I will make mistakes. I might have to rework things as we go. That’s just part of my process! This will be a “warts and all” look at my methods.
  • I may not always do things the best way. Sometimes, it just feels good to get something to compile, you know?
  • Today’s update may seem daunting. Messing with scope and relations is something that I, an inexperienced programmer, find intimidating. If you feel the same way, stick with us! We’re doing some of these tricky things up front so that we can focus on writing and building out our rooms with fewer interruptions. We’d be sorry if we saved the scope stuff for later, as it would lead to a lot of rework.

Alright. Here we go.

We need something that can compile.

As you probably noticed last time, I added a bogus room to my code. I called it “lab.” Inform 7 won’t compile without at least one location. Additionally, there’s always at least one thing–the player character–in every Inform 7 game. That’s largely what an Inform 7 game consists of: things in locations. We later construct action rules, and we may even deal with some data in tables, but it almost always comes down to things in locations. Before I can start building things out, I need a rough conception of the world. At the moment, here’s what I have in mind:

  • A small region of four rooms, meant to be a theater of some sort.
  • I would like the player to be able to look into every room in this region from every room in the region. I envision a large, open area, where people could reasonably see across locations.
  • I would like the two main characters, Marbles and D, to be able to communicate with one another as long as they are both in any room in this theater region.

I’ll start by adding the rooms, without descriptions. Here’s the plan.

A graphical representation of the rooms listed immediately below the image.
the theater is a region.

Center Stage is a room in the theater.

Among the Seats is north of Center Stage.
among the seats is in the theater.

Theater Exit is north of Among the Seats.
theater exit is in the theater.

Spotlight Booth is up from Theater Exit.
spotlight booth is in the theater.

Are these names too long? Typing “Among the Seats” repeatedly might get tiresome, but we’ll leave it for now. We can always use a shorter name while specifying a “printed name” if we decide to do so later. Meanwhile, we can take a look at the “index” tab in the IDE (integrated development environment), then choose the built-in map feature. Things are looking good! We have clickable links to each room, and they are grouped in appropriately by region.

A screenshot from Inform 7's project index. It shows the four rooms of the game as separate green squares. A header states that they are all part of the same region.

After compiling, we can walk from one end of the map to the other. It’s still not much, but we now have places for our things to go.

We need a protagonist.

Rather than a generic “player,” we need to specify our protagonist: a cat named marbles.

a cat is a kind of animal.
marbles is a female cat.
the player is marbles.
marbles is in center stage.

Naturally, we’ll need to come up with a description of Marbles. Add it to the to-do list!

We need to see into every room in the region: a relation.

This is more of a toughie! How can we accomplish this? Out of the box, Inform 7 delineates visibility on a per-room basis. Players can see the things in their current location, provided those things are not concealed or inside a closed, opaque container. There must be light in the room, too, which is the default condition for new rooms.

However, that’s the end of it. Players don’t see into other rooms by default. This makes sense most of the time, but sometimes we are in a large open area where we would expect to see as far as conditions (and our eyesight) might allow. This theater is one such place. The audience must see what’s onstage, and a spotlight operator would have to know where to point their lamp. It would be handy if we could say something simple and straightforward like “center stage is perceptible from the spotlight booth.” It couldn’t be that simple… could it?

It’s one of those things that intimidates people, including me, but we can use what are called “relations” to build conditional phrases just like that one. The chapter on relations in the documentation is large and complex. To boil things down: one purpose of relations is to define, well, relationships between things. We can then make rules, do action processing, and write conditional text with them. The important thing to remember is that we are supplying the logic. Inform 7 doesn’t know if there is a relationship between penny nails and orbital satellites. If we say there is, there is. It’s helpful to come to a problem like ours with specific sentences or phrases in mind that we’d like to use. Again, we are shooting for something like “center stage is perceptible from the spotlight booth.”

There’s a relationship there. We are stating that one room can be seen from another room. How do we convince Inform 7 to recognize a phrase like that?

limited interactivity relates rooms to each other.
the verb to be perceptible from implies the limited interactivity relation.

Some notes. There are various constructions of the first sentence. Sometimes, we might want a one-to-one relationship.

the recharging relation relates one phone to one charger.

In our case, though, we have a number of rooms that are visible to one-another. So we use a plural and “each other.”

The results are instant. We can start using this qualification in our rules right away.

if center stage is perceptible from the location:

Let’s add some relation information.

seating area is perceptible from center stage.
main entrance is perceptible from center stage.
spotlight booth is perceptible from center stage.
spotlight booth is perceptible from seating area.
main entrance is perceptible from seating area.

Since these are what Inform 7 considers “reciprocal” relationships (you can tell by the each-other designation), we don’t have to state inverses. If center stage is perceptible from the spotlight booth, then the spotlight booth is perceptible from center stage.

Note that we will not really make use of the term “limited interactivity.” In our implementation, that’s just the name we give the relationship. If we want to review relations we’ve created in our source, we can type “relations” within the IDE:

>relations
limited interactivity relates rooms to each other:
  Center Stage  <=>  Among the Seats
  Main Entrance  <=>  Among the Seats
  Main Entrance  <=>  Center Stage
  Spotlight Booth  <=>  Among the Seats
  Spotlight Booth  <=>  Center Stage

The bidirectional arrows indicate reciprocity.

We need to see into every room in the region: the player’s scope.

We now have a framework for making rules based on whether a room is “perceptible” or not, but we still haven’t used that to affect what the player can see. That’s defined by the player’s scope. As I mentioned above, we don’t usually think about this. We make games where players visit rooms and interact with the things they find there. Sometimes, we need to tell Inform 7 to do something different. We start that process like so:

after deciding the scope of marbles:

The idea here is that once Inform 7 decides what is and is not accessible to the player, authors can add to or take away from that “scope.” We can modify or qualify a scope rule in ways similar to action processing rules, with the final phrase being “place [something] in scope.” For example:

after deciding the scope of marbles:
	place the frob in scope.

We have a couple of options here. We can place individual objects in each room in scope, or we can place the rooms in scope. Which to do? Placing the rooms in scope will let us “examine” each room and get a room description in return. Let’s try that first, with a note to evaluate further.

after deciding the scope of marbles:
	repeat with destination running through rooms:
		if the destination is perceptible from the location:
			place the destination in scope.

[English translation: check every room in the game. if a room is perceptible from the player's location, place it in scope.]

Some caveats to this code as-is:

  1. Actions applying to one or more “visible thing[s]” will work, while actions applying to one or more “touchable thing[s]” will not work. This is all as intended. However, the default error/response for the “can’t reach inside rooms rule” should be customized. We’ll add that to our to-do list.
  2. Players can examine other rooms, so long as they are in scope. That’s good! Examining doesn’t perform the locale description process, though, so we’ll need another way to print off any portable items that are in the remote room being examined. That goes on the pile, too.
  3. Inform 7 treats these newly in-scope rooms as touchable (verbs like touch, taste, and move don’t return parser errors), so we’ll have to shut all of that down. We could break something in the process, since it’ll take a pretty extensive “instead” rule.
  4. We could be signing up to write at least two descriptions for every room if we continue down this path: one for examining remotely, and one for looking in the location.

I’m ok with those caveats so far, but 4 in particular could get out of hand (we’ll probably need further customizations for each room based on advancing the plot). We may later find we need to make our scoping rule more complex, but let’s cross that bridge if/when we come to it.

OK! I think that’s enough for today. The goal is to keep framing things in. We’ve got rooms, we’ve got a way to see into them. Next time, we’ll figure out a way to print portable items while looking into rooms. We’ll also tie that functionality to a “look [direction]” command. We should be able to start descriptive writing at that point!

Beginners, today’s update is a little tricky, but we’re laying groundwork for more typical authorship tasks. Let’s see where this takes us!

Borogove snippets have a size limit, so I won’t be able to share the whole project for much longer. I may still share snippets sometimes to illustrate techniques and features. Just to stay on the right side of Spring Thing’s guidelines, I will probably avoid sharing compiled games. It would probably be fine up to a certain point in the process, but I don’t want to misjudge where that point is. You can always compile it yourself, and pasting the code into an IDE will make it much more readable whether you compile it or not.

Once the game is feature complete, this project will go dark for closed testing.

Here is the folder where I will archive source code.

Here is a link to the current source as of today.

Here’s a link to a snippet containing the entire project. I’ve added some junk items to the rooms to demonstrate that they can be examined but not taken. For instance, from the beginning location, try “get hat” and “examine hat.”

Next

We’ll hit Borogove’s character limit for snippets, most likely.

& other cool stuff