Z-Machine 1.0 Update

Ah, when I say ‘interpreter version’ I’m talking about the data stored at byte $1F in the header. Modern interpreters tend to store a letter related to the name of the interpreter there (I think Frotz is ‘F’ and Nitfol is ‘N’).

I know Frotz lets you change that value to experiment with old Infocom games.

I ran a quick test in Infocom’s DOS interpreter for Zork Zero, and when the width field is zero, it justifies the text as if it were in window 0, which seems like the sensible behaviour (and I believe is what the recently altered code for Frotz does, as well).

I think the Standard is in error, so I’ll just remove the offending text (unless anyone thinks I’ve missed something).

The 1.1 specification document had a section about this, which I added to the remarks at the bottom of section 8.

That should cover it, I think.

I have absolutely no idea what to do about this. Does the text of the standard need changing? Notes added?

Does not properly supported buffering (or non-buffering) actually affect any games anywhere?

I don’t know what to do about the buffering question either.

It occasionally comes up in discussion of really weird corner cases. Like, I think I remember a discussion of what happens if the interpreter crashes. Should recent output be guaranteed to be displayed if buffering is off, but perhaps lost if buffering is on? (Spoiler: I do not think this is what buffering mode is for. Please. No.)

Does anybody have a suggestion about what buffering mode should do, in (say) Gargoyle? If there is none, I’d just tack a qualifier onto 7.2: “…if the interpreter is able to control this.”

If I remember correctly the buffering opcode is also used in Inform’s box code, which could be used for heuristics there.

Hey, so it is. (I haven’t looked at this code in…)

And the behavior is… it calls @buffer_mode 1 after printing the box text to the status window, just before switching back to the story window and shrinking the status line.

Nope, no clue what that’s there for. Buffering is on by default (this code is V4/5/8 only) so the opcode will have no effect in most games.

The immediately following code calls @output_stream -1 and re-prints the box text. I presume this is intended to flow to the transcript (if active) while being suppressed from the screen. So perhaps this feature would be messed up if the game left buffering off? But I can’t see how.

EDIT: Correction – the veneer code for the box statement runs in V6 also. But the spec has already given up on saying what @buffer_mode does in V6.

Well, if nobody has any better ideas, I’ll go with that.

After a fair amount of investigation and confusion, I have substantially rewritten section 6.3.3, on the stack size. I submit the following for comment and (hopefully) approval, after which I hope to never think about the Z-Machine’s stack ever again.

6.3.3

The absolute minimum standard for stack size is:
let the ‘usage’ of a routine call be 4 plus the number of local
variables it has. During a game the total of the usages for each
routine in the recursive chain of routines being called, plus the
game’s own stack usage, can be assumed to never reach 1024.

However, more recent games have required a much larger stack
size than this allows for. It is advised that allow for these games
by having a larger stack size if at all possible.

Two examples of modern interpreters with increased stack size are
Windows Frotz, with 32768, and nfrotz with 61440.

Seems good.

I kind of want to go on a stack-use-measuring field trip with a hacked interpreter… but, um, I have a lot of other stuff to get done today. This week. This month. :confused:

The document at frobnitz.co.uk/zmachine/1.0/ should now be updated with corrections on all the issues brought up here and a few I found elsewhere, and I’m doing a final check to make sure it all makes sense and I haven’t missed anything, before deleting all the insert and deletion markup and handing it over to be uploaded to the Inform website.

If you want to look it over and comment on anything, now’s the time.

Shouldn’t the page be labeled as “1.1” or “1.2” given what Danni(?) has said?

No, this is still the 1.0 Standard. It’s not an update to the design of the Z-Machine, merely correcting errors, clearing up some vague areas, and updating some out-of-date assumptions (like the stack size).

No new features have been added (although one or two previously undocumented features have been noted), and it will take very little effort to alter an interpreter that currently claims 1.0 support to match this new revision of the document.

It would be good to record in the spec when and where unit tests exist for each feature.

Implementation tips could be good to add too, though that would be subjective depending on who is writing them.

Hi,

regarding 1.1.4: Beyond Zork (serial 870917, release 49) doesn’t seem to strictly adhere to the story file limit. Although it only breaks the limit by a mere 0.54kB I still disabled this file size check in fizmo to make this story work.

7.1.2.3: In case we’re saying that delays etc. should be recorded it would be nice if we could also suggest a parseable way of doing this, so interpreters have a chance to read command files written by other implementations. Example from fizmo/borderzone:

(Waited for 7400 ms)
examine camera
(Waited for 8600 ms)
e

The Remarks at the bottom of section 7 gives an example of one way to record this sort of thing. Probably worth putting a note in 7.1.2.3 to refer people to the example in the Remarks.

    take lamp              an ordinary command
    turn it on.[154]       command, full stop, then keypad 9
                           (which might abbreviate for NE)
    look unde[0]           timed out input
    look under the rock    the same input continuing
    [254][10][6]           mouse-click at (10,6)

Now, this doesn’t indicate how long it waited. I suppose that information would be useful in games that are doing things while the player is thinking/typing. Perhaps a minor modification to this?

I’ll have to think about it a bit more.

I see. What I’m concerned about is the preservation of what we understood the standard to be then and what we’ve worked out to really be true. Given this, we should have a revision number.

I thought about it a bit more.

The transcript does not need to state how long we waited, because nothing happens while we’re waiting until the set amount of time passes, and the interrupt routine is called. All the transcript needs to state, essentially, is ‘wait until the interrupt routine is called’, and the method suggested in the Standard already does this.

This update is more about what we’ve always understood the standard to be, but recorded wrongly or unclearly. So it is a revision of the document but not the spec. (A distinction which is almost silly, but not quite.)

I am going to preserve what is now inform-fiction.org/zmachine/stan … int0-1997/ . So we will have that comparison. We can refer to this revision as “1.0 (2014)”, I suppose, if the question comes up.