Z-Machine 1.0 Update

Over the past couple of days, I’ve take the ‘UPDATES/CLARIFICATIONS’ section of the Z-Machine 1.1 Standard, and applied them to the Z-Machine 1.0 Standard where appropriate.

The current version can be found at frobnitz.co.uk/zmachine/1.0/

The 1.1 spec document can be found at ifarchive.org/if-archive/inf … Spec11.txt

Changes should be easy enough to spot, with deletions in red and additions in bright green.

I’d be happy to hear any comments, and especially any other corrections that were not in the 1.1 spec that should be added.

Zarf kindly took a look at it already, and I’ve incorporated some of his notes. We did have a bit of a discussion about how complex Unicode formatting should be handled, and I’m still not sure about the outcome.

He also noted:

  • 6.3.3
    […recommended stack size…]
    I’ve overrun 1024 when writing an I7 game. I think modern interpreters go with 64k. (Ask around about this.)

So I’m asking around about it.

To be clear, this is about correcting errors in the 1.0 document.

When this is stabilized, I intend to install the updated files in inform-fiction.org/zmachine/standards/z1point0/ .

Hopefully this will proceed to building up a full-fledged 1.1 spec, so we can stop relying on the “1.1 differences from 1.0” document Marvin linked above.

With the stack-size thing, it was when I was writing Heliopause, which has a lot of “Instead of X: try Y” invocations. (Compiles as nested function calls.) This blew out the small stack (1024 words) in the original Frotz source. In the nfrotz fork, the default stack size is 61440, which was sufficient.

I think it would be more useful to have a single spec and mark which sections are required for 1.1 compliance.

Vaporware has some spec bugs which should be fixed.

I was wanting to do this sometime, so thanks! I even made a repository in the Friends of Inform 7 Github group, which you could use if you like.

This would be the 1.1 spec! We’d keep the 1.0 around for historical reasons, but it’s worth correcting its errors even so.

Well, if someone could point me at that list, or knows any other problems with the spec, I’ll happily add those corrections to the standard.

1.1 incorrectly states that output streams 3 and 4 are in V5+ only. For example, Nord and Bert 19-870722 (V4) makes use of output stream 3, and Ballyhoo 97-851218 (V3) makes use of output stream 4. Section 7.1.2 of the updated standard now contains the erroneous correction from 1.1. In addition, section 15 has always shown “output_stream number table” as being a V5 feature, but V4 clearly can accept that, too.

I’ll look through the source of my interpreter to search for any other notes I’ve made regarding problematic standard text.

Hey, great. It looks good at first glance.

In case it’s of interest to anyone else, I’ve just pushed the history of the ZSpec11.txt up to github: https://github.com/jpenney/ZSpec11/. It might be helpful in figuring out where some of the stuff came from by seeing when it was added and checking against an archive of the z-machine mailing list.

Speaking of output stream, the standard currently says:

In Version 6, a width field may optionally be given: if this is non-zero, text will then be justified as if it were in the window with that number (if width is positive)

The ‘if this is non-zero’ section would mean that window 0 can never be selected here. Is that accurate? It doesn’t seem useful.

The current language of the Standard on @set_font 0 is vague and unhelpful, and there seems to be no consensus on what it means. A brief examination of the behaviour of Infocom’s interpreters did not help.

Therefore, unless there are any objections, I’m going to change the language so that @set_font 0 will return the value of the currently selected font, without changing which font is currently selected.

6.4.1 is incorrect for V4, which has @call_vs2.

Marvin, are you aware of my version 1.2 draft? curiousdannii.github.io/if/zspec12.html

A few other thoughts:

  • Maybe a note could be made that some interpreters don’t support saving tables?
  • Not setting an interpreter number/versions should be allowed and maybe encouraged
  • Non-buffered output isn’t supported by all terps
  • Not all streams may be supported
  • It should be clarified that a fixed width font will be used if any of the three ways to turn it on are on.
  • It would be good to clarify how to handle box quotations with a terp that puts the upper window in a stretchy window so that the quote remains visible even though Inform shrinks the upper window immediately - though I haven’t perfected it yet myself so I wouldn’t know what to say!
  • should be altered to say that setting the cursor outside the window will instead expand the window to fit, and testing for negative values may be needed. (Parchment has a note saying Lost Pig does this, but I can’t remember how exactly it goes outside the window.)
  • @read: Is it really only versions 1-4 that convert input to lower case? Most terps convert it for 5 as well I think?

I’ve gotten this to work. I should write down some pseudocode.


I would have said “Buffered output isn’t supported by all terps” – i.e., Floyd – but this only goes to show that the concept of “buffered output” just isn’t that meaningful to interpreters. If you’re not talking directly to curses.h, it’s likely that word-wrap is happening at a level not accessible to the interpreter code.

How’s this sound?

Interpreters are allowed to not support access to external files, or to only support some methods of access. This is discouraged, but in some environments such access is not feasible.

An attempt by the game to use save or restore in a manner not supported by the interpreter should simply return 0 as with any failure, and the game should notice and take appropriate actions.

An attempt by the game to use streams to access external files which is not supported by the interpreter should ideally print a warning to the user that the functionality is not available, and otherwise do nothing.

No, z5 games completely fail to understand input if not converted to lower case. I just tested Beyond Zork. This is just some vague wording in the Standard which I will fix.


A very old bug in the Frotz core was uncovered last week that seemed to be caused by a misreading of the spec. See github.com/DavidGriffith/frotz/issues/1.

Modern games shouldn’t rely on an interpreter code, and while old ones might, the interpreter differences aren’t specified enough. If you could specify what the Infocom games think about the different interpreters then terps could choose appropriate codes for each game.

As far as I’m aware, the interpreter codes don’t make much difference in the behaviour of Infocom’s games, beyond colour and font usage. I was going to say I don’t know of any more recent games that do anything weird with it, but I think I found one.

I don’t think setting the values to 0 is going to stop game writers from trying to use the information, but I don’t think many game writers are using that information anyway.

Maybe just a note that using that interpreter number or version to change game behaviour is strongly discouraged?

How would one account for the differences between V6 and the other version?