Z-Machine 1.2 Proposal (again)

Now that activity on the Z-Machine Standard on Github has slowed (but not quite stopped), I thought I’d bring this back up. It’s been 5 years since I last posted about my Z-Machine 1.2 proposal, so I’ve made a new thread.

I’ve put together another draft of my proposal at http://www.frobnitz.co.uk/zmachine/1.2/draft7.html

Changes to the previous draft are:

  • removed @font_size for being too awkward
  • Allow print_unicode and check_unicode to access all Unicode characters.
  • Define font 2 (the picture font) in line with Infocom’s original idea for it.

In addition to what’s in the draft, I’m planning to add notes on the differences between the Z-Machine described by the Standard and the one described by Infocom specification documents.

I’m also thinking about adding the ZIL opcode names to the standard, for easy reference, although the standard opcode names will remain the main ones.

Feedback would be greatly appreciated.


Haven’t gone through the whole thing, but have a few quick comments/questions:

  1. There are two sections with id="check_unicode" in the html - the link at the top should be going to the second, which BTW describes the old form of the instruction.
  2. How are the second arguments for @print_unicode and @check_unicode handled? Are they UTF-16 surrogate pairs or just high/low part? Shouldn’t there be a gestalt id reserved for this?
  3. What about making 1.1 standard compliance optional with appropriate gestalt ids defined?

I’ve merged the second check_unicode section with the first.

UTF-16 (if I understand it correctly) is the idea. I’ll reword it a bit to be clearer as soon as I can. Yes, there should be a gestalt for this.

Gestalt ids for 1.1 features seems like a good idea, yes.

1 Like

Do pictures in the picture font correspond to ZSCII characters, or Z-characters? In other words, if I want to display picture number 1, do I have to output ZSCII 1, or Z-character 1?

If the former, how does that interact with some ZSCII codes being undefined for output? If the latter, how does that interact with different alphabets?

Pictures in the picture font correspond to ZSCII characters 32 and above, if defined for output. Basically it’s a way to print fancy letters from picture files, not really a way to print pictures using text, if that makes sense. I’ll try to make it a little clearer in the proposal.

This means you can’t use it to display picture number 1.

Some other interesting things in the XZip specification I’ve resisted the urge to add:

  • Picture opcodes draw_picture, erase_picture and picture_data
  • Margins for the lower window
  • Newline interrupts

Ah, okay. Maybe mention that restriction specifically, that it can only print pictures whose numbers correspond to legal output Z-characters? (Since the picture numbers are basically arbitrary that’s not really a restriction, except that some blorb tools might need an update.)

Yeah, when I wrote the text describing font 2 I was mostly just trying really hard not to copy everything from the XZip spec. It definitely needs a bit more explanation.

I think it’s worth reflecting on the fact the Z-Machine 1.1 spec discussions were about 20 years ago now, and since then there’s been exactly zero enthusiasm from anyone to actually use any of those features.

The lesson I would draw from that is that making changes to the spec in isolation from game authors and especially game system developers is pointless. The number of game authors prepared to futz around with header flags and opcodes and other random bits is, to a first approximation, zero. So either any changes come with changes to relevant game development systems to use those changes, or no-one will use it.

The Z-Machine is basically dead from Inform 7’s perspective. So that leaves Inform 6 (very few games released in recent years) and Dialog (interesting, but too new for much to have been done with it). That’s where I would start if I wanted to extend the Z-Machine further. I do rather like the classic Z-Machine screen model (i.e. not V6, which is a mess), but if it were me I’d use Glulx as the VM format, with a non-Glk I/O system to replicate the Z-Machine screen model.

1 Like

I’m not even sure what you’re suggesting I do that I’m not doing. I figure this forum is about the most relevant, open, available to game designers and game system designers place I could possibly have chosen to discuss extensions to the Z-Machine.

As far as whether it’ll be used or not… well, there’s plenty of people have put effort into plenty of IF-related systems that have gone nowhere. That’s not what I want, obviously, but I’m not sure why the Z-Machine in particular attracts this apparently discouraging attitude towards efforts to improve it.

Interpreters exist which already use my version 1.2 proposal:

Can we make them compatible?

That would involve:

  • Not reusing any existing gestalt selectors (already done)
  • Changing your stream 5 to stream 7

Another idea we could consider is a general Glk opcode. Cheap to specify, but for those terps using Glk gives you a lot.

I don’t see anything on Stream 5 in the page on that link, but Stream 5 as I’ve proposed it would be a generic use, so any specific use by interpreters that already exist would be compatible. That is, it’s legal for your interpreter to treat output to Stream 5 that doesn’t have an identifier in any way it likes. It should of course be highly recommended for future games to use an identifier so as to not confuse things.

I have considered adding Stream 6 as a second Standard ‘send data to the interpreter for whatever reason’ stream, in order to ensure already existing games are not actually violating the Standard.

eval() stream $30 Stream: 5 Supports the eval() stream. It behaves like the memory stream, except that when it is turned off its contents will be run through the Javascript function eval(), and what that returns will be written back to memory. If they are both enabled then the memory stream takes priority.

But my point was that I’d like to be able to implement your proposal, but there are conflicting meanings about what stream 5 means. Nobody has implemented your proposal yet. There is zero cost to change it to stream 7.

And yes, reserving stream 6 for Vorple, and including my gestalt selectors in your table would be wise. EXT:31 wasn’t ever really used, so that can be ignored.

The whole point of my design of Stream 5 was to be compatible with existing use of Stream 5, but to not have a whole Stream exclusive to web-based interpreters that want to run eval().

Sending data through Stream 5 for the interpreter to run through Javascript’s eval() is perfectly legal. The text in my proposal expands the definition of Stream 5, it does not contradict it. (I mean, it slightly contradicts it because my Stream 5 doesn’t block other Streams, but I’m willing at this point to change that).

There are 32 thousand possible streams. I don’t understand the issue with changing the number to make sure there is not even the possibility of a problem.


I don’t see a possiibilty of a problem. The way current interpreters use Stream 5 matches my proposal. I don’t want to have games using non-Standard streams when we could make them Standard. I don’t want to have a stream entirely dedicated to a feature that most interpreters can’t use (eval()). I don’t see the problem with making Stream 5 more (potentially) useful to other interpreters, while allowing it to continue doing what it already does.

I don’t understand your reluctance on this at all. Most of these are features that most interpreters won’t have, and streams are not a limited resource (unlike opcodes).

I’m not even saying that you should define stream 5 in full. Mark it down as depreciated. The different behaviour for how it interacts with other streams is significant enough to make this a new feature, currently unimplemented by anyone, so the cleanest thing is to use a new stream number.

I’d also recommend including the private-use area. I’ve had emails from people who are using it.

I guess my reluctance is down to a few things. One is that the whole point of my design for Stream 5 was to allow your use of it to continue, but make it available for other uses as well. Moving it to a new stream kinda defeats that purpose.

Secondly, honestly, I don’t want the Standard streams to be numbered 1,2,3,4,7. It’s ugly. I don’t like it.

And finally, I genuinely don’t see the point. I explicitly put together a system that had backwards compatibility with the current uses of Stream 5, so why not just use it? If I’ve messed something up and it’s incompatible, that can surely be fixed. I don’t understand why you’re so against this.

1 Like

I’m currently rewriting a lot of the output stream 5 stuff to make it a lot clearer that sending data without an identifier is legal, although discouraged. I’ll rewrite a few other bits (like the gestalt selectors ) to try to make it more compatible with Dannii’s proposal. Should have another draft up soonish, with no new features, just a few changes and clarifications.

I’ve also just noticed the suggestion for a general Glk opcode. This one I’m really very strongly against. If you want direct access to Glk features, you should be using Glulx.

Sorry I didn’t reply after your last one.

If you’d want to make it compatible, that would be good. I think having the streams interact how I specified would be best anyway. The author won’t always know when steam 3 is in use, and library functions using stream 3 won’t know which other streams are in use. Having to manually switch off all other streams is just very author unfriendly.

I’d say that sending data without an identifier is now deprecated. Same for the selectors. New implementations shouldn’t include them, and old games will only try to use them if the deprecated selectors are supported. Same for stream 6.