The Z-Machine Standard 1.2 (draft)

I would love to see an updated, unified standard instead of separate documents that correct each other.

Another defect in 1.0 that comes to mind: section 6.4.1 says V4 has a maximum of 3 routine arguments, but V4 defines @call_vs2 which allows 7 arguments.

That would be wonderful, but who knows enough of the edge cases to do so?

This might be a bit of jumping the gun to comment on this as my first post, but I have something I want to bring up. I’m currently about 80% done implementing a Z-machine, which is about the extent of my background.

Over all the idea of this seems pretty sound, but I think that the use of a number to ID the different extension to the interpreter has the potential for trouble.

One thing I’ve seen in the world is that this sort of thing can cause problems really quickly, especially if they catch on. Not only do you need to officiate the ‘official’ selector codes you have to worry about unofficial ones. While the spec does allow for a range of private codes the odds are pretty good that any private extension will have a 50/50 chance of using $F000 instead of a random number. Collisions in this space can and will cause a problems.

So, if I might make a different suggestion. Why not try using a string. It’s not much harder to do then anything numbers, it could eithor follow the same embedding rules as @print and @print_ret with the optional argument before the embedded string or be a paddr to the string. The upshot of this is you can use something like mime types or URIs to ID the extensions, which can be be descriptive and lower the chance of collisions (I would also suggest lower case string comparisons).

For example you could have things like:
Standard Version: “Standard-Version” “uri://curiousdannii.github.com/if/zspec12.html”
Transcript: “Transcript-Protocol” “uri://curiousdannii.github.com/if/transcripts.html”
Zoom: “Zoom-Profiling” “uri://www.logicalshift.co.uk/unix/zoom/Profiling”
Zoom: “Zoom-StackDump” “uri://www.logicalshift.co.uk/unix/zoom/StackDump”
Private: “X-Whatever” “url://whatever.com/”

I have some other thoughts on the interpreter number, but as that’s not part of your proposal I’ll wait on that.

Thanks for your comments. While we could use strings instead, I don’t think the overhead would be worth it. For both the Z-Machine and Glulx there have been so few extensions made that I wouldn’t expect this to be a common problem - I don’t really expect it to catch on. The age of javascript interpreters may change that, but we would also expect custom interpreters to be locked to playing only certain files.

Does anyone else have any comments? Is it time to publish this properly?

Can we add a clarification about @set_font 0?

Hmm. I’d rather not really. If it’s not something that requires the version to be set to 1.2 it shouldn’t be there.

There is probably a need for a document listing futher classifications than what 1.1 provided. Perhaps a page on the IF wiki?

We could also have a selector to explain what an interpreter would do for @set_font 0, but I doubt that’d really be very useful.

Having the whole specification in a Wiki would be a step forward: that might allow more effective updating. Note that I’m not volunteeing to do this, though…

It should be in some version of the specification. If we’re not going to change the old versions retroactively, then it should be in the new version.

Has consensus even been reached on @set_font?

Nope. :smiley:

vaporware’s Infocom documentation explains where the “previous font” wording came from, and zarf’s proposed behavior makes the most logical sense.

If I were updating Glk Frotz today, I would change @set_font 0 to do nothing and return the current font. Fortunately I have the luxury of time and can wait to see what ends up in the spec.

I’ve updated the draft with my position on this issue, which is effectively that the 1.2 standard is orthogonal to any clarifications of the 1.0/1.1 specs. It would be wonderful to have them, but I don’t think this spec is the appropriate place for them (as they won’t depend on @gestalt) and I’m not up to writing those clarifications either.

curiousdannii.github.com/if/zspec12.html

If the 1.2 spec isn’t the appropriate place to revise the 1.1 spec, then what is? It seems quite strange to me to propose that 1.0/1.1 be revised independently of 1.2, and that those revisions be announced through some means other than the version number.

You have a proposal for one new feature here, but labeling that as a new version of the Z-Machine Standard seems premature.

It’s one feature as well as an incrementing of the standard revision header. I honestly don’t really care what this spec is called, but having it match the revision header makes the most sense to me. Further clarifications could be made by a 1.1.1 spec, or even a 1.3 spec (whether or not that would entail incrementing the revision header again.)

How strongly do people feel the need for a further set of clarifications? It might be helpful to collect a list of issues, even if there isn’t consensus on all of them, I’d even be willing to help with this.

What I don’t want is to tie them all to my spec. I’d like to be able to introduce some function acceleration to Parchment in time for the next I7 release and would prefer the spec to be finalised by then.

Well, that header field is there to indicate which version of the Z-Machine Standard the interpreter implements, so if you increment that number, you’re making a new revision of that standard. My objection is not that this proposal is called “The Z-Machine Standard 1.2” – that’s what it should be called – but that it isn’t addressing the things that a standard revision ought to address.

(I’m also not sure what the purpose of selector $01 is, since the standard revision number is already stored in the header, and any game that uses @gestalt will have read it from there.)

It would have to be 1.3, since the header field only has room to store two parts of the version number.

Have you had any luck with pattern matching?

I think the revision header is like an API version: it describes what functionality is available. The description of that API can be updated without updating the API itself though. Similarly the 1.0 standard had a few revisions, and the 1.1 standard had clarifications for 1.0 that should be implemented by all 1.0 terps, even if they didn’t implement the 1.1 “API”. So there’s no reason another document couldn’t do the same, and if it only had clarifications it wouldn’t need to increment the revision header.

Now maybe instead of having multiple documents we should instead work on a new unified 1.0-1.1 standard. This is like the HTML5 standard, which instead of just describing the additions it makes, redescribes the entire language. Perhaps we could do the same. I could edit it if others would help with the technical minutiae.

Both options are possible, and they wouldn’t need to stop this 1.2 spec from being finalised either.

As to pattern matching, the Gnusto architecture doesn’t lend itself well to that. I’ve started rewriting Gnusto from scratch so I could add pattern matching later. Having an acceleration opcode though would be possible with the current architecture, and feasible to implement in time for the next I7 release.

I disagree: the standard revision number doesn’t only describe the set of opcodes that are available, but also the behavior of those opcodes. The game has to assume that an interpreter claiming to support 1.0 only supports 1.0 as it was first published, because there’s no way for it to know whether or not the interpreter incorporates clarifications that weren’t published until years after the original 1.0 spec.

Again, I think attempting to change the old specs retroactively is a mistake. Games can’t distinguish between “old 1.0” and “new 1.0”.

What do you suggest I do? Has consensus been reached on some issues which need specifying? Even if there has been no consensus we could still add a selector for each issue to show which reading of the standard a terp has taken, so that at least games could then detect and account for different implementations. That’s the approach I’d like to take… so if you can identify which issues need specifying I’ll add them in.

Well, from this thread we have:

  • @set_font 0
  • output streams 3 and 4 available in V3/V4
  • maximum of 7 routine arguments in V4

The first may require some more discussion – is there consensus on what @set_font 0 should do? – but the latter two are contradictions in the current specs and just need to be re-specified.

I’ve updated the spec again. I’ve added selectors which allow for those issues to be identified, but which don’t dictate which is the correct interpretation. Comments?