-----------------------------------------------------------------------------
Informal Z-machine newsletter #1 10th December 1995
(circulated by Graham Nelson)
-----------------------------------------------------------------------------
I'm trying to email this to everyone I know of who's working on or
interested in the Z-machine: however boring this "news" may be, at least it
isn't a secret, so I'm also posting a note to rec.arts.int-fiction and
uploading this text to ftp.gmd.de. (Please would anybody who would like to
join the circulation list, or get off it again, email me.) I hope this
addresses the concern expressed on r.a.i-f that a private mailing list,
as proposed by Marnix Klooster, might exclude people who use Inform and want
to keep an eye on what's going on.
It's likely to appear irregularly and vary in length, turning up as and when
there's anything to say. I certainly plan another issue before standard 1.0
is published, so that 1.0 doesn't come as a nasty surprise to anyone.
I feel it would be helpful for us to keep in touch more than we're doing at
the moment. It would be especially good to hear of current projects under
way and of progress with the various interpreters and ports; perhaps the
circulation list below might become a directory of who's working on what.
Contents: Miscellaneous news; mistakes in standard 0.2; use of read_char
return values in Infocom story files; producing accented characters in
Inform; the Inform linker; circulation list.
Miscellaneous news
==================
Progress on the interpreter front has been rapid. Kevin Bracey's Archimedes
interpreter ("Zip2000", a derivative of Zip) is playing V6 games reasonably
well, and Stefan Jokisch's "Frotz" (with a new interpreter core) is already
up to V5 in implementing standard 0.2. (An MS-DOS release of this state is
planned.) Bryan Scattergood's hugely enhanced ITF interpreter (for the
Psion and Archimedes) has been souped up to V8 to play "Jigsaw".
Stefan Jokisch has produced a draft list of "all known bugs in Zip", which
can be found at ftp.gmd.de.
People are actually using the accented characters in standard 0.2. In
particular, Profesor Jose Luis Diaz de Arriba (
[email protected])
from Asturias, Spain, is trying to write an Inform game in Spanish (which
involves interesting exercise in parsing, actually, as pronouns like "it"
are simply glued onto the end of words: e.g. "cogela" means "take it",
"coge" meaning "take"). He particularly asks if JZIP produces accents
according to the standard?
Small triumph for text-only games: there's somebody working through "Jigsaw"
who is both blind and deaf, and playing by braille.
The FAQ for rec.arts.int-fiction is keen to include a brief section on the
current state of the Z-machine interpreters generally available. Please
contact Jools Arnold at the email address below (not at his personal email
address).
Mistakes in Standard 0.2
========================
This note summarises the corrections to the current Z-machine standard which
have been pointed out so far: they're provisional and not yet acted upon.
It would be very helpful if you could spare a moment to see if (a) you
agree, (b) you think I've missed anything!
The next proper release of the standard will, I hope, at last be 1.0 (some
time in early January), but I'm keen to get as much as possible right before
then.
EXTENSIONS:
1. New accented characters needed: the ligatures oe and OE (e.g. in French
word "coeur" or "Oeuvres"); upside-down Spanish exclamation and
question-marks. I propose to add the following to the list in 3.4.4:
Code name plain text form
220: oe-ligature oe
221: OE-ligature OE
222: upside-down ! !
223: upside-down ? ?
(Spanish quotation marks can be used <<like so>>, so no new characters
are needed there. Profesor de Arriba did ask about ordinal o and a
(raised and underscored letters) but said they weren't very necessary,
and since they won't be in many fonts I've left them out.)
2. I hope to briefly specify the file format for Version 6 graphics files.
I know too little about this at the moment. P. Dave D. votes for
specifying the Amiga files since they're the prettiest. So we should
add a brief description of the Amiga format. If anyone would like
to write one and send it to me...
3. Remarks to sections 7 and 10: I remarked that it would be good to
write time-out information and unusual character terminations to
command script files, to allow for really thorough testing, but that
this was "formidably" difficult. Perhaps it's not so bad. Stefan J.
suggests the following style:
take lamp 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)
with accented characters also appearing like [220]. So I propose to
specify that command script files do encode timeouts and terminating
characters after all. Any objections?
COMMENTS:
It's been suggested that non-breaking space and breaking-hyphen be
added to the standard output codes. I'm not really convinced this is
worth the effort involved: any other views?
Stefan J. has an interesting conjecture to account for the presence
of both a new font and a text style for fixed-pitch text (which on the
face of it is redundant). He suggests that fixed-pitch style should
use the ordinary font's letters, but simply pitch them a fixed distance
apart (I suppose it would have to be an Em-width), as Infocom's V6
interpreters do; whereas font 4 should genuinely be a Courier-type font.
I don't want to specify this behaviour, but I suppose it might make a
nice option on an interpreter.
I will slightly clarify the definition of "standard" -- somebody asked
me if standard meant that source code had to be available for users to
make extensions to (for example) the ASCII set; the answer is "no".
Providing such a facility in some way (not necessarily by making the
source available) is only suggested, not required.
It's been pointed out that Border Zone has a rather strangely striped
upper window when a hint answer is being displayed. I think this is a
"feature" of BZ, though, not the result of a mistake in the standard.
Infocom's own interpreters are not compliant with 0.2. Partly this
is because they obviously miss off recent changes to the Z-machine,
partly because Inform 5.5 does not get all the header bits correct
according to a strict reading of the Infocom story file design.
(For instance, I5.5 doesn't set the "I want to use UNDO" bit, even
though it does want this; likewise for the "colours" bit in Flags 2.
This means Infocom's own interpreters won't allow "undo" when playing
an Inform game, and won't display the Jigsaw jigsaw in colour.)
Inform 6 will get the header bits right (no, really) but the
standard is written so as to make Inform 5.5 games playable.
CORRECTIONS:
1.1.4: The maximum size of a V6 file is 512K, not 576K (though only because
of the "length" field in the header).
1.2.3: The V6 packed address translation formula is disastrously wrong.
(Inform 5.5 is wrong about this too and generates inaccurate files
as a result. Inform 6 will be better!) The formula should be
$$ B = \cases { 2P & Versions 1, 2 and 3\cr
4P & Versions 4 and 5\cr
4P + 8R_O & Versions 6 and 7, for routine calls\cr
4P + 8S_O & Versions 6 and 7, for {\tt print\_paddr}\cr
8P & Version 8\cr
} $$
(rather than 4P+4R_0 and 4P+4S_O respectively for versions 6 and 7).
(Thus I am also respecifying Version 7 in line with this: I don't
think this will cause trouble since nobody is actually using V7
at present anyway.)
3.4.4: The << and >> are the wrong way round. Code 162 should mean >> and
code 163 should mean <<.
6.1.3: Insert "and the stack is emptied". (Properly speaking, the stack isn't
restored from the initial state of the story file because it doesn't
live in the story file.)
7.1.2.2.1: Reword this, replacing "Any character 10 codes printed should
be converted to 13." with "(A game may |print_char| 13 but should never
|print_char| 10; in any case, it could more sensibly use
|new_line|. So there is no need to convert code 10 to 13.)"
7.2.2: Claimed that text buffering in V3-5 was only active on the lower
window. This is true in V3 and V5, but not V4. (As 8.7.2.5, indeed,
said all along.)
8.1.3.1: Perhaps I am pushing my luck asking for font changes to be possible
mid-word (Infocom's own games change font at word breaks but not inside
them): however, I want this feature to make it possible for authors
to hack up new accented characters or symbols. So I'm proposing to
keep this clause.
8.3.1: For "the colour under the mouse arrow", read "the colour under the
cursor".
8.6.1.1.1, dictionary: In Version 3, you can't turn off text buffering for
the upper window, as this seems to imply; and selecting the upper
window automatically clears it (this is the only way of clearing the
upper window).
8.7.2, 8.8.3.2, dictionary: reading the cursor position cannot be expected
to produce an accurate answer when there is text buffered up which may
become a long wrappable word. What should we do about this? Should
we (a) specify that the answer is undefined, or (b) specify that the
act of reading the cursor position ought to flush any buffered text onto
the screen and then give the accurate answer?
8.8.3.2, 8.8.3.2.6: Zork Zero's demonstration mode sets the line count to
-999 to stop [MORE] from ever appearing, which would prevent it from
timing out and restarting the demo if it feels it has been abandoned
by a shopper who has passed on. I propose to specify this as legal,
which means rewording 8.8.3.2 as well.
8.8.3.2.2.1: insert such a clause to explain when adjusting the margins takes
effect during a call to a newline interrupt routine. If such a routine
alters the left margin, no effect takes place until the succeeding
line, while altering the right margin takes effect on this line.
That is, the interpreter does the following on a new-line:
move to the new line and put the cursor at the current margin;
call the interrupt routine, if necessary, but take no further action.
8.8.3.3: Window 0 should default to have attributes 2, 3 and 4 on (scrolling,
copy to printer transcript, buffering).
8.8.4.1: Reword this to remove ambiguity: some people think this means that
window 1 is fitted into the present window 0, but actually it's meant
to mean that windows 0 and 1 are tiled onto the whole physical screen.
8.8.5.3.2: To clarify: erase_window -2 clears the entire screen to the current
background colour (rather than performing an erase_window for all 8
windows in turn).
Section 9: This section needs rewording to make clear that bleeps are treated
differently from other sound effects. Many games (e.g. Beyond Zork)
bleep but don't have a sound effects file; and:
games not setting the sound bit can still bleep;
bleeps can't be prepared, stopped or finished with;
bleeps can only be played at one volume;
bleeps don't need to run as a background task;
bleeps don't stop other sound effects which are playing in the
background.
Remarks to section 9: Unfortunately "The Lurking Horror" uses sound_effect
in slightly more complicated ways, thanks in part to sloppy coding.
In particular
sound_effect 4 8
sound_effect 4095 2 15
can both occur but both are thought to be bugs.
sound_effect n 3
sound_effect 0 3
are each used to stop the current sound effect (n being its number).
More unhappily, TLH also assumes that the interpreter is as slow
as the old Amiga one was: it fires off several sound effects in one
game round, assuming there will be time for it to play most of each
while it goes through its machinations. To simulate this,
sound_effect must be rewritten to pause sometimes:
if a new sound effect is begun while there is still one
playing which was started since the last keyboard input,
then wait until that earlier one finishes one cycle before
replacing it with the new sound effect.
10.7: In the light of the read_char research detailed below, the new
definition of the input character set is:
\nsp{7} For input purposes the character set is as follows:
\orm\beginstt
0-12 ----
13 New-line (ends input of a command)
14-26 ----
27 Escape key code
28-31 ----
32-126 Standard ASCII (see 3.4.3)
127 Delete key code
128 ----
129-154 Function key codes (see below)
155-251 Accented letter codes (see below)
252-254 Function key codes (see below)
255- ----
\endtt\frm
The codes marked |----| should never be passed to the game. Note that an
interpreter should return 13 and not 10 as ``new-line'' (contrary to the
advice in Standard 0.2). (10 would work on every known game except
`Bureaucracy', which would be unplayable; this also requires 127 to be
typeable.)
11.1: The header entry for "interpreter version" says that an ASCII
character is expected (conventionally an upper case letter). In V6,
the version code is just a number and has no ASCII significance.
13.6.3: |sread| should be |read| (only a typo).
14.1: The save opcode had the wrong syntax for Version 4. Standard 0.2 says
| * 0OP:181 5 1 save <label>|
| 5 [illegal]|
with EXT:256 taking over in V5:
| * EXT:256 0 5 save table bytes name <result>|
However, Version 4 uses a cross between the two forms, so the 0OP:181
entry should read:
| * 0OP:181 5 1 save <label>|
| 4 save <result>|
| 5 [illegal]|
where "result" means what it means in V5. Likewise, 0OP:182 should read
| * 0OP:182 6 1 restore <label>|
| 4 restore <result>|
| 5 [illegal]|
14.1: The |scan_table| opcode had the incomplete grammar line
| * * VAR:247 17 4 scan_table x table len|
which should read
| * * VAR:247 17 4 scan_table x table len form <result>|
(likewise in the dictionary entry).
14.1: I'd like to finally add details of which opcodes are used in V6. My
present belief is that EXT:261 to EXT:264 and EXT:272 to EXT:284 are
all used by existing Infocom files (though "print_form" only by Arthur,
"read_mouse" only by Journey, "make_menu" only by Journey and then only
if the machine number is 3). The following, I believe, are never used:
catch / throw
nop
piracy
Are the following used?
pull stack <result>
erase_line pixels
set_cursor l c w
get_cursor table
output_stream n t w (i.e., in its full form)
not
art_shift
I'd be grateful if V6 hackers out there could let me know.
15.3: The remarks this makes about interpreter error-checking belong in
Appendix A.
dictionary: |erase_line| should ignore its one operand in versions 4 and 5.
(The opcode is never used in any V4 or V5 game, we aren't sure what
the operand was meant to be, and I can't think of anything very useful
to do with it: so here's the least effort solution.)
dictionary: does anyone know if |get_cursor| should write its data to
words 1 and 2 of a "table" array where word 0 is the extent of the
array (presumably 2), or if it writes to words 0 and 1 of the "table"?
I would guess the former and there may be no evidence either way,
but any information would be welcomed.
dictionary: |picture_data|: to "Otherwise, if the picture number is zero,
the interpreter writes the highest legal picture number into the first
word of the table" add "and the release number of the picture file
into the second word". (Zork Zero expects this.)
dictionary: Kevin B. reports that implementing "picture_table" in the way
suggested in 0.2 as "only a conjecture" seems to work well. He suggests
that if one has to decompress pictures and then plot them, then it's
good enough to cache decompressed images only for pictures listed in
the last call to picture_table. (I.e., with other pictures it's
acceptable to decompress all over again each time they are printed.)
At any rate, I'm going to remove the "only a conjecture" caveat, as
experience seems to have confirmed it.
dictionary: the enormous |read| entry needs a short extension to make clear
where the cursor ends up: a new-line is printed if input was terminated
by ENTER, whereas the cursor stays at the end of the text entered so far
if input was terminated by anything else.
dictionary: similarly, to make clear that |read| can take place in any window.
dictionary: the |save| entry missed some of the syntax lines out. (Typo.)
App A: It's not a trivial issue to check non-existent locals, so I'll reword
this.
App F: Needs correction in line with 1.2.3.
Use of read_char return values in Infocom story files
=====================================================
This note details all uses except: (i) press-any-key-to-continue, and (ii)
press-y-or-n. With minor variations there is a common "hints" routine to
the Version 5 re-releases and releases; and also in the V4 Nord'n'Bert.
Version 4
=========
Trinity None.
-------
Bureaucracy
-----------
The form-reading code (200e4):
(i) must have 13 (not 10) for RETURN;
(ii) accepts either ^ (94) or 14 (old ASCII for cursor-up) to go back;
(iii) accepts either 127 or 8 (delete or backspace) as delete.
Otherwise it uses plain ASCII.
A joke at 30095 asks for input apparently normally but accepts only one
character before interrupting the reader. The input code is echoed to
screen with print_char.
Nord 'n' Bert
-------------
The action routine for "garble" (bff4) reads in a line of text, garbling E
into C and N into P: text can be terminated by a 10 or a 13.
Interestingly, while garbling it seems to think it might get codes with top
bit set (i.e., codes plus $80), which it treats identically.
Hints routine: expects return codes N, n, Q, q, P, p; 10 or 13 for return;
but now top bit set codes are not recognised.
A Mind Forever Voyaging
-----------------------
Is similarly written to possibly expect codes with top bit set; there is a
yes-no routine at 12ad0 and routine 2b6bc (for opening and closing "files")
expects E, C, N, O, P, R, e, c, n, o, p or r.
Version 5
=========
Beyond Zork
-----------
The routine at 11198 reads a character using read_char, converting \ to
"cursor up" (129) and / to "cursor down" (130). It's used in four places.
In each case, there is a limited set of values which the game will allow
the player to type, and the game will beep and retry if a different value
is given.
(i) At 18a68: legal values 10 or 13 for RETURN, 129 or 130.
(ii) At 18db2: as (i), except that (redundantly) the ASCII / and \
are also recognised as 129 and 130.
(iii) At 18ee6: as (i), except that cursor left and right (131 and 132)
are also legal.
(iv) At 3ae3d: as (i).
The attribute-choosing routine at 3b4cc reads 10 or 13 for return, 32 for
space.
Border Zone
-----------
Hints routine at 35bc, as for Nord'n'Bert above.
The chapter-choosing routine at 21da4 reads for 1, 2, 3, R or r.
Sherlock
--------
Hints routine at ccc0, as for Nord'n'Bert above (except for some quite funny
jokes).
At end of play (11348), a menu for Quit/Restart/Restore/Hints/Undo is
offered: using read_char and expecting only codes 1 to 5.
German Zork I
-------------
Only uses the standard hints routine, but a print_ret has been inserted into
the code to say no hints are available (in English). (Conjecturally, the
hints had not been translated yet.)
Version 5 re-releases Seem to use only the standard hints routine.
---------------------
Version 6 Based on a quick survey by Stefan, the V6 games seem to present
========= no further difficulties: i.e., behave much as the Standard says.
Conclusions:
1. Every Infocom file in V4 and 5 allows 10 or 13 as equivalent codes for
RETURN, except for Bureaucracy, which only allows 13. Therefore 13 should
be the standard.
2. Bureaucracy also needs either 127 or 8 to be "delete". I propose 127 as
the standard (since 8 is properly "backspace").
3. Otherwise no existing file needs any other "control characters" in the
range 1 to 31, so Standard 0.2 is otherwise accurate.
Producing accented characters in Inform
=======================================
This note, which I posted to rec.arts.int-fiction a while back, describes
a small patch to Inform allowing accented characters to be conveniently
compiled in text. It will end up as a feature of Inform 6, but since the
release of I6 is not imminent (see below) here is a standby measure.
They are produced by an @ string escape. Most accents are written as
@, followed by an accent marker, then the letter on which the accent appears:
@^ put a circumflex on the next letter: a,e,i,o,u,A,E,I,O or U
@' put an acute on the next letter: a,e,i,o,u,y,A,E,I,O,U or Y
@` put a grave on the next letter: a,e,i,o,u,A,E,I,O or U
@: put an umlaut on the next letter: a,e,i,o,u,A,E,I,O or U
@c put a cedilla on the next letter: c or C
@~ put a tilde on the next letter: a,n,o,A,N or O
@\ put a slash on the next letter: o or O
@o put a ring on the next letter: a or A
There are then a few others:
@ss German sz
@<< quote marks
@>>
@ae ligatures
@AE
@th, @et, @Th, @Et Icelandic accents
@LL pound sign
For instance,
print "@AEsop en fran@ccais, mon @'el@`eve: @`a votre sant@'e.";
print "Na@:ive readers of the New Yorker will re@:elect Mr Clinton.";
print "K@:arl Gau@ss first proved the Fundamental Theorem of Algebra.";
(This syntax is similar to that used by TeX.)
-------------------------------------
The patch is to zcode.c. Add the following declaration before the
translate_text routine:
static char *accents =
":a:o:u:A:O:Uss<<>>:e:i:y:E:I'a'e'i'o'u'y'A'E'I'O'U'Y`a`e`i`o`u`A`E`I`O`U\
^a^e^i^o^u^A^E^I^O^UoaoA/o/O~a~n~o~A~N~OaeAEcccCthetThEtLL";
(to follow Standard 0.2), or, better,
static char *accents =
":a:o:u:A:O:Uss>><<:e:i:y:E:I'a'e'i'o'u'y'A'E'I'O'U'Y`a`e`i`o`u`A`E`I`O`U\
^a^e^i^o^u^A^E^I^O^UoaoA/o/O~a~n~o~A~N~OaeAEcccCthetThEtLLoeOE!!??";
(correcting the <<,>> mistake in 0.2, and adding the new accents proposed
above)
And, after the block
...
if ((value!=-1)&&(value2!=-1))
{ i++; i++;
write_z_char(1); write_z_char(value*10+value2);
}
}
in translate_text, append
else
{ value=0;
for (j=0;accents[j]!=0;j=j+2)
{ if ((accents[j]==text[i+1])&&(accents[j+1]==text[i+2]))
value = j/2 + 155;
}
if (value==0)
{ char uac[4];
uac[0]='@'; uac[1]=text[i+1]; uac[2]=text[i+2]; uac[3]=0;
error_named("Unknown accented character", uac);
}
i+=2;
write_z_char(5); write_z_char(6);
write_z_char(value/32); write_z_char(value%32);
}
(Please also increment the Inform version number if you are making this
patch.)
The Inform linker
=================
Inform 6 is progressing in that its new feature, a linker, is working well
enough for everyday use (though there are still bugs to remove and a few
annoying restrictions). It works as follows: games compiled -M are compiled
as "modules", which can be embedded into any Inform game using a new "Link"
directive (exactly as if they were source code files being inserted using
"Include"). The format of a "module" file is very similar to that of a
story file. In the header, though, we have the following differences:
Byte Contents
0 64 + V (where V is the version number)
6,7 scaled address of "link data" table
56,57 the number of objects
58,59 byte address of object table
60,61 byte address of properties table
62,63 scaled address of static strings
(A module can't exceed 64K in length.) The link data table is a morass of
detail, but the rest could be readable by Txd, Infodump, etc., very easily.
-----------------------------------------------------------------------------
Circulation list
================
[email protected] Adam Thornton historian
[email protected] Bob Newell avuncle, PC Informer
[email protected] Bryan Scattergood author of
Psion and Arch ITF-based int
[email protected] Torbj|rn Andersson
[email protected] David Kinder interested in V6
[email protected] David Rose maintainer of Zip
[email protected] (David Rose)
[email protected] (David Rose)
[email protected] Andrew Plotkin author of Freefall
[email protected] (Andrew Plotkin)
[email protected] Bjorn Gustavsson author of
Scott Adams-to-Inform converter
[email protected] Gareth Rees Inform home page
[email protected] Mark Howell author of Zip, Txd
[email protected] Paul David Doherty (Dave) guru,
collector of story files,
author of Infocom fact sheet
[email protected] John Holder author of JZIP
[email protected] Stefan Jokisch author of Frotz,
maintainer of Txd and Infodump,
author of Zip bug list
[email protected] Kevin Bracey author of Zip2000
[email protected] Marnix Klooster author of
another exposition of ZM
[email protected] Bob Manson working on V6 Zip
[email protected] Matt Ackeret Apple II hacker
[email protected] Martin Frost working on
faster Amiga interpreter
[email protected] Graham Nelson author of Inform
[email protected] Robert Pelak Macintosh Informer
[email protected] Julian Arnold (Jools) FAQ-keeper
[email protected] Sverker Wiberg TeX hacker
[email protected] Ronald Tjoelker working on
V6 Mac interpreter
-----------------------------------------------------------------------------