Next Technological Steps?

Hi, I enjoy writing stories and programming systems. Naturally I’ve found that IF really interests me :nerd:.

After watching Get Lamp by Jason Scott and a lot of it’s extended footage I’ve spent a long time
pondering how the current systems could be expanded upon. One of the main questions being, what is the
next technological step?

In visual games it’s all about more polygons, more light calculations, higher resolutions. What about IF?
Where are there opportunities to provide more?

The areas I’ve identified that I think could see improvement are:

  1. More intelligent parsers
  2. Less guesswork
  3. Smarter information hiding / less verbosity
  4. Greater responsiveness
  5. More complex personalities & relationships
  6. Possibly more real time events, more flow, more of a world in motion
  7. Easier navigation
  8. Drop in - drop out multiplayer

Thanks for any feedback :smiley:

More people maintaining what we already have :wink:

Yeah! Better interpreter support and better standardization of what already exists seems more important than anything else, mostly because a lot of what you say can be - and usually is - down to authorial preferences.

It must be frustrating to a lot of people that, in technological terms, IF got pretty much perfect after Infocom and Level 9 perfected their parsers and their features like UNDO. We keep using the same stuff because it really is the best. The only significant point of contention that usually comes up is the compass, and people have been trying to replace it for a while (relative movement, and landmark-oriented movement), but it’s stuck so long because it works so well.

I’m sure there are amazing things that can be done to IF still, and Vorple is a good example. The paradigm does not need to remain, for instance, “what’s printed on the screen is immutable”. Off the top of my head, this is the one venue where IF could experiment - Twine does it to great effect. And I remember a Vorple demo, a recent one, which had to do with a time loop and which did crazy cool things with the text on screen.

But on the whole, the basics are rock-solid. Amazingly so. The things that people get excited about - the things you yourself pointed out - are more to do with the author than anything else, and indeed an author can implement them.

Well, except for the multiplayer thing. But a multiplayer IF game would need a different design than a singleplayer one, so it’s still an authorial preference.

Hi! I have to run off to a thing so I don’t have time for a full reply this morning. However, I want to quickly say:

The responses in this thread, and the responses you are likely to see in this IF group, are going to look really conservative. This is not your imagination.

I don’t think that IF was perfected in 1984. Rather, there’s a combination of several things going on.

  • A lot of us spent many years developing our skills at writing and playing 1984-style IF. It’s hard to move outside the conventions of that design, because those are the conventions that the players understand! Any incremental change makes the experience worse. (The “nobody wants to add adverb parsing” problem. Also the “compass directions really are popular, it turns out” problem.)

  • As Dannii said, we spend a lot of effort running-in-place to keep existing features working. Bit rot is real as consumer OSes and hardware update. (Not much year-over-year, but it adds up over a decade.)

  • When someone does build a new feature, it doesn’t get much play. Many of the features on your original list already exist in an experimental way. This leads to a “We tried that / nobody wants that” response.

  • Related: there are a lot of possible “next steps”, some radical changes. Some very successful games have been built around new IF ideas. However, most of them haven’t led to new movements; they wind up being successful one-offs. The one that have become new IF subgenres (Twine, Choice of Games house style) wound up creating new IF communities – which leaves this community as the conservative one, the group that didn’t change much.

I don’t mean that we all hate new ideas. I have lots of new IF ideas and I’ve built some of them. Plenty of us split our time between this IF group and others. But this group as a group is characteristically… well… conservative about IF.

This reminds me that I need to get back to that “issues I’ve had with the parser” post I have in draft. Maybe some quick things:
-understanding multiple things before the comma
-getting disambiguation to behave nicely
-interpreting ambiguous commands as referring multiply (so if the player types “x handle” in the presence of two handles they would examine both–all this would take is the ability to intercept a disambiguation request and automatically feed “all” to it)
-having disambiguation requests respond to the names of objects even when those names contain verbs (I almost got this to work with Ron Newcomb’s I7 version of the older parser, but I don’t have the I6 skills to do it for real)
-seriously, disambiguation is very hard to deal with and modify

Some non-parser issues:
-trying to get “a/an” to behave appropriately in front of any arbitrary string rather than be bound to the object itself. It’s sometimes hard to notice how many different IF locutions arise from working around the situations where English things get modified contextually–“a bag (empty)” rather than “an empty bag,” “You can also see a knife and a fork here” rather than “A knife and a fork are here also.” In the latter case, the capitalization and pluralization are pretty easy to take care of, but they sure weren’t solved by Infocom and Level 7! (Well, I guess they didn’t even have to worry about capitalization originally.)
-grouping issues; if anyone knows how to write the code for the printed name of a slice of bread so that it’s possible for Inform to print “You have two slices of bread and two slices of toast,” let me know.

There’s some other more blue-sky things I’d be interested to see in parsers, but those are all coding problems that I’ve actually had, which I think count as me bumping my head against the limits of the I7 parser more than me bumping my head against the limits of my coding ability.

There’s no reason why IF can’t have more polygons and higher resolutions too. Except money :slight_smile:

An IF game that has graphics just as good as other games is what I always wished. Sadly, after Legend stopped making graphical text adventures, this was never pursued again.

Kitchen is a room.

A bread slice is a kind of edible thing. There are four bread slices. Understand "of" as a bread slice. A bread slice can be toasted or untoasted. A bread slice is usually untoasted.  Understand "toast" as a bread slice when the item described is toasted. The printed name of a bread slice is "slice of [if toasted]toast[otherwise]bread[end if]".

Understand "slices" as the plural of a bread slice. The printed plural name of a bread slice is "slices of [if the item described is toasted]toast[otherwise]bread[end if]". The description of the bread slice is "[if untoasted]A bit crumbly[otherwise]Nicely toasted[end if]."

After jumping:
	let T be a random bread slice that is nowhere;
	if T is nothing, continue the action;
	now the player carries T;
	say "You jump, and a slice of bread materializes in your inventory."
	
After waving hands:
	let T be a random bread slice that is nowhere;
	if T is nothing, continue the action;
	now T is toasted;
	now the player carries T;
	say "You wave your hands, and a slice of toast materializes in your inventory."

After eating a bread slice:
	say "[We] [eat] [the noun][if actor is player]. Not bad[end if].";
	now the noun is untoasted;

Rule for printing a number of bread slices while taking inventory:
	let B be number of untoasted bread slices carried by the player;
	let T be number of toasted bread slices carried by the player;
	if B > 0, say "[if B is 1]a slice[else][B in words] slices[end if] of bread";
	if B > 0 and T > 0, say " and ";
	if T > 0, say "[if T is 1]a slice[else][T in words] slices[end if] of toast".

Test me with "wave / i / jump / i / wave / i / jump / i".

Printing a number of! Very clever! I had forgotten that that was even a thing.

I do think that there may still be some grouping issues that pop up occasionally.

There’s an extension that prints the number for you. :slight_smile:

Come to think about it, there IS something about the parser I never fully grasped. How well do I7 and TADS cope with giving NPCs multiple commands, via “NPC, this then that then those” format?

Touche. I guess I was thinking in terms of big changes and paradigm-changing improvements (like UNDO), and didn’t look at the small fiddly little niceties we take for granted and which are a big part of the solid systems we have. Mea culpa. Those are still being perfected, even in Inform 6 from what I see in the relevant board.

But that harkens back to what Dannii said, doesn’t it? :slight_smile: Not so much “what can we do that’s new”, but “how can we perfect what’s already here”.

Then again, that’s not so different from “more polygons” and “more light levels” - that stuff is just perfecting as well.

Argh. Brain hurts. Stopping now.

EDIT 2 - Is it possible to order more than one NPC around? Like “Donna and James, go north then hug” or something? Even if it is, though, isn’t it crazy specific and unlikely to be be of practical use? Then again, isn’t that true of EVERYTHING until someone actually makes it and then all of a sudden it turns out it really WAS necessary?

I7 handles this. Here’s a snippet of transcript from Example 188 (Generation X):

I should point out that this has been a thing since Enchanter, so it’s not surprising that it works.

With much hacking–that’s Daniel Stelzer’s Multiple Actors extension. It’s what I meant by “understanding multiple things before the comma.” But, you know, it took a lot of hacking and is not entirely smooth.

You’re breaking my heart, Peter! :wink: Arno von Borries did this in Dead Man’s Hill too.

Another big non-smoothness about ordering multiple NPCs around is that, even once you get the parser to resolve “Donna and James, go north then hug,” it’s going to turn into the action of Donna going north, then the action of James going north–which is fine–then the action of Donna hugging, then the action of James hugging, which is not so fine; we want Donna and James hugging to be a collective action, and there’s no such thing in the world model. (Actually the way Multiple Actors works it comes out worse–I think it gets resolved as Donna going north-Donna hugging-James going north-James hugging, which means that when the first hugging action gets resolved they’ll be in different rooms. Dunno–in Terminator I tried to disallow these completely, but that was because they could subvert the timed element rather than because of any particular problem with Multiple Actors, except insofar as I had to do some weird stuff to get the Every Turn rules to work properly with Multiple Actors.)

Anyway! The other big issue here, and one that goes beyond this admittedly rather specialized application (pending the upcoming boom in textual square-dance calling games), is that the actions will get processed as they get reported, in an entirely piecemeal fashion. So if you write “Donna, James, and Allie, go north” the default will look like this:

Which is ugly. But since the actions get processed separately in that order, and get reported as they get processed, it takes some hacking to get something different. And you get the same issue when the actions are triggered by the code rather than by a command. This makes it hard to have smooth prose when there are a bunch of autonomous NPCs around. Extensions like John Clemens’s Consolidated Multiple Actions are meant to take care of at least some of this (I think that only works for actions the player takes, though), but again, they require some pretty deep hacking.

I’ll go stand quietly in the corner and brush up on my parser knowledge, shall I. :wink:

(BTW, I knew the giving-people-more-than-one-order had been a thing since Enchanter, but it always puzzled me. I could never tell whether actions were queued, or whether the actor was performing more than one action in a single turn, and wasn’t this a puzzle element in Enchanter? Anyway, brain tired, and I’ve swallowed my feet often enough for one thread!)

They’re queued.

(Technically, it’s not the actions that are queued. The parser saves the unused part of the compound command and generates actions from it on demand each time the main game loop asks for the next action, reading new player input only when it runs out. See held_back_mode and sections A and K of the parser.)

I added an every turn rule to my previous example to illustrate this:

Yeah, the Enchanter thing was a puzzle element. That’s why I didn’t mention anything beyond the name. I’d have spoiler tagged even that, but what would I say to indicate who could safely read the spoiler?

So, in your example two turns pass and the PC is unable to do anything in the meantime? What about ordering a PC to two a bunch of actions and doing something WHILE they’re doing them?

Ha ha, no foot-swallowing here–it’s an obscure corner of parser experimentation that happens to be one I’m interested in.

I don’t know about Enchanter, but in I7 asking someone to try a queue of commands gets converted into a queue of requests, which get evaluated in turn. Example:

[code]Lab is a room.

Taylor is a person in Lab.

Persuasion rule when asking Taylor to try jumping or asking Taylor to try waving hands: persuasion succeeds.

Every turn: say “One turn has elapsed. Number of turns elapsed: [turn count].”

Test me with “actions/jump then wave then kiss taylor/taylor, jump then wave then kiss me/taylor, kiss me then wave then jump”.[/code]

output:

As you can see, the requests get processed in turn, and whether persuasion succeeds with one doesn’t affect whether the next one gets tried–it’s just as though you’d entered “Taylor, jump” and then “Taylor, wave” and then “Taylor, kiss me.” Each action seems to take one turn (on preview: as Vince points out), as with multiple queued actions you perform (which I’d forgotten about–I guess I had to hack queued commands out of Terminator because I’d already done something weird to prevent the Every Turn rules from running after every robot’s action, and I had the timer tied to the Every Turn rules rather than the turn count, so queued actions would’ve messed up the timer).

(By the way, the multiple-actors thing ultimately goes to a question someone had about Suspended, but Infocom’s solution there appears to have been something of a kludge.)

Oh! I forgot to add a particular piece of trivia about collective actions that may be of interest only to me. Spoilers for the third room in Faithful Companion (that’s after you get through the three-latch door):

One of the first things I coded in Inform was something for two people to move a couch together. I think this had something to do with a very early draft of Jim Aikin’s Inform handbook where he had some code for switching the PC near the beginning. Anyway, it turned out to be non-trivial to code this, because Inform’s world model is not that big on having an object that’s carried by two people at once. Then after I had the idea for the mimicking ghost in Faithful Companion, I thought it might be cool to have a puzzle where you and the ghost work together to move a heavy coffin lid, so I dropped that in… but instead of all the tricky stuff, I just had it check whether you and the ghost were trying to lift the lid on the same turn, and if you were the game put it in the right place for you.

Also, I meant to write a 10,000-word Lukascian rant on how the impossibility of collective action and collective report in these games is a reflection of our atomized bourgeois consciousness, which presents us always as individuals interacting with others as mere machines. Watch this space! (Don’t watch this space.)

I think that was always my confusion - I never really understood why it should be that way. Imagine if you could give an NPC a string of commands and, like in Lure of the Temptress, do stuff WHILE they were doing what we told them to!

I’m sure that in I7 this is codable, using tables and other wizardry… it’s just that it always seemed natural to me, but no game actually used it. That I know of. (cue matt w linking me to games that did it)

Nah, I’m going to do my other trick, which is to code it up quick-and-dirty. You have to catch when multiple commands are being issued in a turn, so you can execute the first one and intercept the rest for the queue, and then you have to empty the queue at the right time. Also I discovered a limitation in Inform’s model for queued commands: If your first command takes the NPC out of sight, then Inform won’t allow you to issue the second one, since it’s just as if you’d typed them one after the other.

[code]the living room is a room. the lower hallway is north of living room. the upper hallway is up from the lower hallway. the study is south of the upper hallway.

Taylor is a person in Living Room.

Taylor’s future actions is a list of stored actions that varies.
Caching action is a truth state that varies.
First action this turn is a truth state that varies.
Taylor commandable is a truth state that varies. [Tracks whether Taylor was in scope at the beginning of the queue of commands.]

After reading a command:
now first action this turn is true;
now caching action is false;
now Taylor commandable is false.

Every turn: now first action this turn is false. [This means that first action this turn will be false only when we’ve done or requested multiple actions in one turn]

Persuasion rule when first action this turn is true:
if the number of entries in Taylor’s future actions is greater than 0: [we’ve interrupted a previous sequence of commands]
say “Taylor says, ‘OK, never mind that stuff you said before.’”;
truncate Taylor’s future actions to 0 entries;
now Taylor commandable is true; [Taylor should remain commandable throughout these commands]
persuasion succeeds.

After deciding the scope of the player when Taylor commandable is true: place Taylor in scope.

Persuasion rule when first action this turn is false: [we’ve queued up multiple requests]
now caching action is true;
persuasion succeeds.

First before Taylor doing something when caching action is true: [so we are now executing one of the subsequent requested action on the turn when multiple requests were made–that means we add it to the queue and then stop it completely]
add the current action to Taylor’s future actions;
rule succeeds.

Every turn when the number of entries in Taylor’s future actions is greater than 0 and caching action is false: [if it’s true, then we added actions to Taylor’s queue this turn, and we don’t want to empty it again]
try entry 1 in Taylor’s future actions;
remove entry 1 from Taylor’s future actions.

A clock is a door. It is up from the Living Room and down from the Study.
After going when the door gone through is the clock:
say “You slip through the secret passage in the clock and go [noun] to [the room gone to].”

Last report Taylor going to the Study when the Study encloses the player and the Upper Hallway is unvisited:
say “‘Oh! I didn’t expect you here!’ [if the clock is open]Taylor looks at the open clock. ‘Ah, I see.’ [otherwise]Taylor says. [end if][paragraph break]”.

Test me with “Taylor, jump then wave then jump/z/Taylor, go north then go up then go south/open clock/up”.[/code]

Correct. The parser is set up to produce the next action (actor, action, noun, second noun) each time that the game’s main loop calls it, not to manage per-actor action queues.

Today, you would have to implement simultaneous action at the game level. For example, you could say “Professor Plum, go to the library” and have the parser produce a single action that sets some state in Plum that he’s now in the process of going to the library. Then, each turn a rule (“every turn when plum is traveling:”) would note that he’s going to the library, figure out the next step on the path, and execute a going action. Since this would be a rule-generated action (“try going east”) rather than a parser-generated action, by default it would be part of the current turn, simultaneous with the player’s action for that turn.

It’s an interesting area for experimentation. I can see a couple of approaches:

  • The parser views the entire compound command as a speech action and sends it as an order to the NPC. The burden is then on the NPC to parse it and act on it over time.
  • The parser produces a set of actions each time it’s called rather than a single action, and the game loop maintains queues for each actor. The problem here is that the parser disambiguates commands based on the current state of the world. So if we say “Bob, A. B. C.”, B and C may be interpreted differently after A has happened. I think that this is why the parser holds off on consuming input and generating actions from it until a new action is needed. Generating actions for A, B, and C immediately so that they can be shipped off to the game loop and queued would interfere with this disambiguation and possibly result in a different and less sensible set of actions (although one could argue that Bob would interpret them based on the world as it was when the command was issued).

I’ve just checked, and this is featured in Melbourne House’s classic Tolkien IF works “Lord Of the Rings” and “The Hobbit” (this last one, incidentally, launched the year before Enchanter)

In the beginning of the Hobbit you can, for example (testing it right now in a Spectrum emulator):

DROP MAP
SAY TO THORIN “GET MAP,GO EAST,DROP MAP,GO WEST”

and if Thorin agrees (beeing the hard headed guy he is, there is a high chance that he’ll refuse :laughing: ) he will use a turn for every order and you’ll be able to do any action in between.

Hey thanks everyone for the responses. Zarf I think you really summed things up perfectly :smiley: