Updating the Z-Machine Standard Documents

One of the issues is titled ‘Cutthroats’ 99:99 clock thing’ because I don’t know what ‘Cutthroats’ 99:99 clock thing’ is so I couldn’t make it clearer.

In Cutthroats there are situations where it is supposed to display 99:99 for the time. It does this by putting 111 in the score/hours variable and 99 in the moves/minutes. Infocom’s interpreters subtract 12 from the hour when it is greater than 12, giving 111-12=99.
There are several ways this can go wrong in a modern interpreter - capping the hours at 23, taking the hours modulus 24, or capping the minutes at 59, etc.

3 Likes

Having not played Cutthroats, is it important that it display exactly 99? Or is it just supposed to be a general “error” display?

(For comparison, I’d say it’s not important whether the interpreter displays 14:00 vs 2:00pm; the devs might have expected the latter, but the former doesn’t significantly change the experience.)

I think anything that indicates an error would work. In my interpreter for example, I allow the minutes to be any value, not just 0-59, and hours are switchable between 12 and 24 hour clocks, but 111 is special cased to always return 99 so that it works for both.

2 Likes

The time 99:99 is displayed in Cutthroats when the player doesn’t have their watch, so they don’t know the time.

1 Like

I suppose ??:?? or the like would work as well, although that would actually require more special casing than changing 111:99 into 99:99.

The display of all other possible values for hours from 23-110 and 112-65535 is still undefined. The same for minutes 60-110 and 112-65535.

If people think it is important, one way to define those unused values that works for Cutthroats and allows potential future shenanigans:

  • Minutes are always displayed unaltered regardless of value.
  • 24 hour displays reduce any hour greater than 23 by 12.
  • 12 hour displays reduce any hour greater then 12 by 12 and special case 0 into 12, adding the AM suffix for 0-11 and PM for anything else.

While this looks fine as an approach, it seems a bit out of scope for the standard. A simple --:-- or ??:?? (as suggested earlier) after a range check would work just as well in this case.

1 Like

Or just a note like…

Infocom’s Cutthroats sets a time greater than 23:59 when the player doesn’t have their watch—specifically, it sets the hours to 111 and the minutes to 99, which displays as 99:99 on Infocom’s original interpreters. As such, modern interpreters must be able to handle values outside the normal range, but how they’re displayed is not specified, as long as it’s clearly distinct from any normal time: “99:99”, “??:??”, “111:99”, and not displaying the clock at all are acceptable, while “3:40 pm” is not.

3 Likes

I agree the standard needn’t call for any particular representation. Personally, I think --:-- is the cleanest and clearest visually, although I am partial to 99:99 because I am nostalgic for Infocom’s original experiences. Although maybe we should allow minutes to go to 60 in case proposals for future leap-minutes become reality. :wink:

As an aside, the status line (the actual pre-V4 status line, not the upper window) exists in a weird sort of limbo. Other than some common data - an object description and two numbers, the presentation is solely up to the interpreter. Where it appears and in what manner is completely outside the game’s control. Sometimes a display that works for most games is a bit odd for others, e.g. Planetfall.

1 Like

FWIW, Ozmoo allows the person bundling the game to set the border colour to:
A: Always the same as the background colour
B: Always the same as the foreground colour
C: Any specific colour

Option A is the default.

In section 1.11:

The remaining usage of @ is hacky but powerful. Suppose you are trying to implement some scenes from Infocom’s spoof of 1930s sci-fi, ‘Leather Goddesses of Phobos’, where one of the player’s companions has to be called Tiffany if the player is female, and Trent if male. The name turns up in numerous messages and it would be tiresome to keep writing

if (female_flag) print “Tiffany”; else print “Trent”;

Instead you can use one of Inform’s 32 “printing-variables” @00 to @31. When the text @14 is printed, for instance, the contents of string 14 are substituted in. The contents of string 14 can be set using the string statement, so:

if (female_flag) string 14 “Tiffany”; else string 14 “Trent”; … print “You offer the untangling cream to @14, who whistles.^”;

The value specified by a string statement has to be a literal, constant bit of text. There are really hacky ways to get around this, but if you needed to then you’d probably be better off with a different solution anyway.

5 Likes

I think it happened in the Amiga and ST terp as well when we tested it. Those game versions were z5.

1 Like

I haven’t looked at the relevant part of Infocom’s code to see how their terps actually handle it, but I can easily imagine it going something like this:

All locals for the current routine are stored in a buffer for easy access. This buffer is reused for every routine call. Calling a routine checks the new number of locals needed and copies that many of the existing locals elsewhere to be restored upon completion. Routine arguments (or defaults) then overwrite locals in the original buffer and the new routine proceeds. Upon return the number of previously saved locals are restored to the buffer, leaving any modified by extra arguments with changed values. Oops!

3 Likes

The picture_data opcode, according to the Standard:

Otherwise, if the picture number is zero, the interpreter writes the number of available pictures into word 0 of the array and the release number of the picture file into word 1, and branches if any pictures are available.

According to the Infocom spec:

Since zero is not a legal picture id, if the picture argument to PICINF is
zero, then the highest picture id in the picture library will be returned in
word 0 of the data table. This will be equivalent to the number of pictures
in the library if all ids are used, but there is no requirement that this be the
case.

That is, the Standard says that it returns the number of pictures available, whereas the Infocom spec says that it returns the ID of the highest numbered picture.These may be different values. Which do Infocom interpreters actually do? Does it make a difference to any game?

2 Likes

Amiga and Mac interpreters return the highest ID.

Edit: Actually the Mac interpreter implementation seems to return the count, but with a comment that it should be returning the highest ID. My original assessment was relying on a different comment in the source that said highest ID. :slight_smile:

Didn’t check the others. No idea if any games rely on it, but I am sceptical there is much utility in it. I also don’t see anything that looks like “release number of the picture file” in the source of the various interpreters, but my understanding of the code is limited.

Note that the definitions are equivalent in the usual case where pictures are numbered sequentially from 1. Since the Standard definition does not trip up any known Infocom games, and any subsequent games that do funky things with picture IDs would presumably be written to the Standard behavior, it seems safe to leave this as-is.

(I can’t see an obvious technical reason to prefer one over the other. The main utility of @picture_data 0 is to allow manipulating pictures without hardcoding picture IDs, e.g., iterating over all images in the game; but this can be achieved just as easily under either definition, just in slightly different ways.)

Section 8.6.3 contains the word ‘beavoided’

1 Like

8.3.6

Ah, I made a typo in a post complaining about a typo I made. Wonderful.

I’m not actually sure how ‘beavoided’ ended up there, since I copy/pasted it from the 1.1 text document which doesn’t have that mistake.

For v5+, the default Inform behaviour for turning fixed pitch on (font off) is to @set_font 4.

Should supporting font 4 be required?