A few general questions regarding IF

Hello everybody

I am exploring IF in more depth to determine how this medium has been used and how i could make use of it in the near future.

While reading about IF and the various implementations in general, i noted down the following questions that i would appreciate the advice of the community on:

  1. Why does IF needs a Virtual Machine?
    I gravitated towards TADS because it looks more like a programming language. However, i have also seen Inform and Zorb and noticed a consistent approach in establishing a VM. So, the questions that naturally occur in my mind are: Why have such a low level VM which generates the need to also build a compiler for it? How do these VMs communicate with their environment? Why not have a simpler interperter that parses the language and interpert transactions on a set of objects directly?

  2. My understanding is that TADS and Inform have an inherent need for a set of standard objects and functionality. For example: Room, Door, Action, Region, Actor, etc. Instead of offering these through an API and making the creation of IF a software development task, both environments also offer domain specific languages with a set of desirable characteristics (for example, object orientation, abstraction, inheritance, scripting capabilities and others).

Having said this (and assuming it’s correct :slight_smile: ), where can i find:
a) A BNF expression of the TADS language (or Inform’s (?))
b) Something like a UML class diagram showing the standard objects and their relationships?

I think that these would help immensely to quickly grasp the bigger picture of TADS. I will end up creating such things anyway as i read about TADS but i am just wondering if something like this already exists.

Looking forward to hearing from you

Your questions cross through a few different issues.

IF originally went for virtual machines because that made it easy to port a game to many computer systems (Apple, Commodore, DOS, etc). In the early days, also, you couldn’t assume that everybody had access to native developer tools. So it made sense to offer an IF compiler as a standalone tool.

The list of desirable platforms has changed over time but the VM system has made it easy to keep old games playable. A modern Z-machine or TADS interpreter will continue to play community games from the early 90s. If we’d all been releasing DOS binaries back then, the IF scene would be a lot uglier and less backwards-compatible.

General programming languages don’t handle IF programming well. In theory you can design an API for anything in any language, but in practice it’s nice to use an IF-specific language. (For example, in most OO languages you have to define a class and then declare a singleton instance of it. In IF, if you use an OO model, you find that most objects are singletons.)

The combination of the VM and a IF-specific language also really simplifies the problem of saving state.

The question of why a low-level (byte-oriented) VM rather than high-level is mostly historic. Infocom designed a low-level Z-machine because anything fancier would have been too heavyweight for the 16-bit computers of the time. Inform (through Inform 6) was designed to compile to the Z-machine. Glulx is a Z-machine replacement but it was designed to support Inform 6 so it has the same basic architecture. (TADS doesn’t have this design history, so TADS 3 is higher-level; it’s object-based rather than byte-based.)

Even though the history is mostly an accident, it has advantages. We’ve been able to radically change the structure of the Inform language with almost no changes to the VM, because the VM has no notion of the high-level language structures.

I don’t think anybody’s written out a BNF for Inform 6 but the language’s syntax is summarized at inform-fiction.org/manual/html/tables.html. For Inform 7, see the documents at the top of this thread: https://intfiction.org/t/the-list-of-inform-7-documentation-as-of-19-dec-2011/3311/1

For another approach to IF using an off-the-shelf language (Ruby), you could have a look at gamefic. It also defines some basic types of things, but not many.

Just to add to zarf’s explanation re portability, having VMs is why you’ll find a fully working ZMachine interpreter for so many platforms - from iOS and Android to GBA and, in one memorable instance, a calculator.

There’s a BNF for one (rather small) part of Inform 7 in example 383 of the documentation.

Hello everyone

Many thanks for your responses. Please see below:

“General programming languages don’t handle IF programming well.”
This is very interesting. Do you mean that there is a lot of ‘scaffolding’ to be put in place before one can start building the game itself or is it something to do with patterns that are specific to IF so much so that you need a language that is adapted to them? It would be interesting to see patterns that are unique to IF.

Regarding the VM: I understand. Discovering the VM aspect was a surprise to me. I would not know where to start with the design of a VM and a VM adapted to a particular purpose. At the end of the day, machines only compute and shift memory around and that’s a long way off from something resembling an object oriented paradigm or, Inform’s paradigm which is almost like reading a piece of text. I suspect that there is a lot of juggling going on in the background, transforming objects (collections of variables) down to memory places, de-referencing them when they have to be sent as parameters to functions, managing the returned values…Or i am too faint hearted :smiley:

Thanks for the pointers to the structure of the language, i will have a closer look.

Many thanks for gamefic too.

Can i ask what is the next step for Inform or TADS? Are there new things to be added to the language or the way that worlds are modeled?

All the best

Well, I7 is the next step, isn’t it?

For you to fully realise what this means, you should read some I6 source code. Here’s one:

ifarchive.org/if-archive/games/s … Advent.inf

A lot of code in a parser-based IF is just defining the list of places, and objects in the places. This is best done in a “declarative” style. Most general-purpose programming languages are imperative or functional; when you need to write something declarative, they ask you to write it in a separate “data” file, either in an object notation like JSON or a document format like HTML or XML. (Or, worse, they put the object notation in a document format, e.g. abusing XML.)

Plus, the objects are typically inert until triggered by “rules” or events. Most general-purpose languages punt problems like these to a “business rules engine” which has its own domain-specific language.

If you want to define rules and declare a lot of objects/locations in a single file, and if you don’t do it in a domain-specific language, you’re going to have a bad time.

And that’s not even touching on punctuation. “IF tends to include a lot of character dialog,” he said. Or should I say: line = ““IF tends to include a lot of character dialog,” he said.” Another sweet spot for a DSL is clearing the way for nicer punctuation.

I see. Thank you for the clarification.

Is there any sort of ontology for IF that could provide the lineage of key entities in an IF world?

I like the narrative style of I7 and how close it appears to be to natural language. Yes, compared to a I6 sample it does seem like the next leap. I am not very experienced in either but how “problematic” is I7? Are there syntax snippets that cannot be interpreted because they can have two (or more) different interpretations?

For Inform 7, you want to distinguish the natural-language syntax from the rule-based programming model. They’re really separate features; in theory you could invent a programming language that used either without the other. The rule model is intended to make the IF system more customizable and scalable. The natural-language syntax is intended to make the language more readable and to fit with the problem domain (objects and their relations).

Each feature has its own problems, although I think they’re both valuable features.

I’m not sure whether you want a detailed dissection of I7 in a “general” thread, though.

As for “key entities”, we normally talk about rooms, objects, doors, containers, supporters, characters, and the player.

But one of the lessons is that an IF system shouldn’t try to build a complete, detailed class tree that covers everything a game author might need. That takes forever and never works. You want to offer a few primitives, a working world model, and a lot of flexibility in customizing the world model.

If it weren’t for the “working world model” part, this would be a call for a general programming language. The inherent contradiction comes from the fact that a basic IF world model is very complicated! You need the “basics” of rooms, doors, containers, supporters, “take”, “put in”, and so on – with a model of synonyms and abstract actions and so on. An IF system needs all that out of the box. But if you’re not careful, you wind up with a fragile, rigid “box” of code that’s hard for the game author to tweak.

Thanks, i am going through Inform7 so that i don’t “drive from memory” assuming that it’s just a programming language, but progress is slow. That’s to do with me…and a little tiny pico bit with the way the documentation and error messages are formatted. They are written for humans, they take time. I am used to (sometimes cryptic) one line error messages, like “syntax error line 2” not “I did not expect this. You see, you are defining a room attached to a pink whale. This is not making sense, probably due to an action you have not yet defined. You could try expressing this as…”.

Although i am trying to keep an open mind, i can’t avoid mappings such as (Thing, door, room, etc) are classes, (Before, after, etc) are standard methods (like onBeginOfTurn, onEnterRoom, etc), “Instead of” is a bit like overriding default behaviour, “In 5 minutes the fireworks explode / At the time when fireworks explode…” is about producing / consuming events, etc.

This is why, i wanted a map of the already defined stuff…For example, my first attempt at a room with a switch connected to a bulb took the long way around: Switch and bulb is a Thing…Right, now i have to write about the concepts of “switchability” and connectedness…What if i want the bulb to be warming up and cooling down? Property…Probably nominal…How do i define this? Then i turned the page and read about devices (DOH!).

The point about rigid / flexible is extremely interesting.

If IF is “special”, then it should require its own DSL which is supposed to encompass all of its special points. But if IF wants to be too general, then the constraints of the DSL might become so general that we are back to a general purpose programming language.

That was my idea initially. That TADS and Inform are providing access (very fancy access in the case of Inform7) to a set of standard related objects that can be reordered and customised to express a game. It turns out that they can do much more because they enable the definition of both the form and behaviour of new things and the redefinition of existing.

At the very least, i imagine a world composed of related objects and actions that accept the whole world as a parameter, change it and return it. Actions can be made to fire with specific pre or post conditions. An Interactive Fiction Reality CPU. But that’s already a general programming language.

Which brings me to my next question: What is the objective of IF? (and the languages of course)

Are we trying to TELL a story?
(In this case, the interaction is guided, it’s there to give prompts that will unfold the story, there are no dead-ends, if you start the story you will finish it, the game will make sure that you will finish it. It’s like reading a story in small chunks and you pass over some checkpoints).

Are we trying to let the reader DISCOVER the/a story?
(In this case, interaction is everything. I don’t want to “You find yourself in a featureless white room. The black rectangle next to the door is attracting your gaze. You wonder if it opens the door or turns on a light.”, instead i want to “He found himself in a featureless white room.”…OK, look around… “There is a black rectangle next to the door”…OK, push black rectangle…“The door opens with a metallic sound that fades to the hum of a coil”. In this case, dead-ends are allowed. The world doesn’t give you prompts. You have to think about your interactions for the story to move on.

The first mode is a bit like a guided presentation…you don’t need much programming capabilities. It could be seen as mindless traversing on a story tree if it wasn’t for the nice reading. It’s probably also easier for the reader to remember the narrative and retransmit it to friends like it’s done with classic stories.

The second mode is about world simulation and interaction with that world. In this case, everything is possible depending on context. In some earth-bound game you “Go north”, in some other world you “Fly up, land, dive, swim left” so there is a clear need for a general programming language. In this mode, there is still a story tree but now, if the simulation is just right, the tree of choices is so dense that the story might unfold differently over two play sessions. It’s probably harder for the reader to remember the narrative though…This becomes an experience. You tell your friends about the experience not the myth.

In this case, perhaps it is possible to compile Inform7 to an interpreted language such as Python. It could be possible to write some code in Python by overriding some standard classes or writing some new and then use Inform’s paradigm to express the game (the defined entities, their relationships and interactions) in a more natural form. I can’t try this at the moment, my knowledge of Inform’s language form is almost inexistent :slight_smile:

Others will be able to chime in with more detail, but broadly:

  • If you are mostly concerned with the narrative, I7 will normally be the tool for you.

  • If you are mostly concerned with creating a very detailed world model, TADS will normally be the tool for you.

  • Both systems are equally capable of doing either - TADS can be used for story-heavy games, and I7 can simulate a very detailed world model. But from what I read from users of both systems, they each have their strengths in different places.

  • You are forgetting something. :slight_smile: What about the IF that’s not entirely about the story? What about the puzzlefests (Not Just an Ordinary Ballerina) or the word games (Counterfeit Monkey, Ad Verbum)?

If the big question is “What is the objective of IF?”…

…the big answer is “whatever you want it to be”.

One small note: rulebooks are in many ways much more powerful than overloaded methods. They take some getting used to, but are really nice once you understand them.

That is a game-design question, not a technical question. The affordances of the language have some indirect bearing – if you want detailed simulation mechanics, you need a language that can implement them – but people have taken both the (roughly-described) “tell” and “discover” approaches with every sort of game-design tool. (Inform, TADS, Twine, Unity, tile-based CRPGs, …)

Just to add my two cents…

I’ve always seen the declarative definitions of IF as data and the parser/execution loop as the engine. I have posited many times that it might be a useful experiment to build an IF platform with a separate data store for the “world model”. But I’m personally not a strong enough developer (or I just don’t have the time) to try it. There’s certainly overlap between data and execution within IF that is very strange from a traditional programming perspective. But I still think there should be a way to pull them apart.

I’ve been poking around the Orleans project from Microsoft Research. It’s a cloud based system that implements the Actor pattern. They call them “grains”, but the idea is that you can implement a grain that manages its data and behavior and is always “on”. I sense something IF-like in this technology.

David C.