Z-machine Hacks

From IFWiki
Revision as of 19:37, 14 September 2013 by Zzo38 (Talk | contribs) (s/large story files/overlong story files/)

Jump to: navigation, search

Here I list a bunch of things that can be done with Z-machine, not specific to any programming language (although some may only be possible in some programming languages). Examples may sometimes be given in the Frolg assembler language, if necessary.

Alphabet table

The alphabet table can be modified so that common characters are on row 0. If there are uncommon characters but they often go together in long strings (for output only, though), you might put them on row 2; a permanent shift into row 2 can more efficiently select a single character from row 1 than the other way around. (Note: The Z-Machine Standard only allows shift locks in V1 and V2; Infocom's interpreters allowed them for later versions, but this functionality was never used. Frolg is the only compiler that will encode them in later versions, and only if it is not in COMPLIANT mode.)

See also: Fun With ZCharacter

Dynamic fwords

Reserve part of the fwords table for dynamic entries. This can be used to allow descriptions to be changed depending on circumstances. An example might be a user option to switch between British or American spelling, or if a lot of descriptions will include the player's name.

Global variables overlapping the extension table

The global variable table can overlap the extension table, so that the mouse and joystick state can be accessed directly as variables.

Global variables overlapping the object table

If the object table is placed right after the global variables table, the first object header might fit in the global variables table. If the first object is the player, then you can read their location easily as a global variable.

Level data in high memory

If the level data doesn't fit in core memory, you can store it in high memory, as a text string loaded into output stream 3.

A two-stage compression can be used, one of which is the Z-machine text packing (which can use the fwords table and other things), and then use a secondary decompression implemented in your program, which might involve run-length encoding, Huffman coding, and whatever else is necessary.

Remember that you will want to represent the most common tiles, as well as other things like run-length, in row 0 (lowercase letters).

Memory layout in version 6 and 7 story files

Version 6 uses offsets in the header which are added to the routine number and string number to calculate their address. This can be used to make overlong story files.

An example of a memory layout might look like this:

  • $00000-$0FFFF: Core
  • $10000-$1FFFF: Strings for fwords table
  • $20000-$5FFFF: Routines
  • $60000-$9FFFF: Strings

The VERIFY command won't work if you do this, so if you want to verify it, the interpreter will need to have some other way of doing so.

Overlapping text strings

Text strings can overlap, if one of them doesn't have the high bit set when it ends when it will continue with the next one. Therefore you can have one string which is short and then another one which ends with the same text as that one.

You might also need padding. How this is done depends on the current state and on the Z-machine version. You will need to change it from its current state to row 0.

Here are the possible paddings (after any one, you can place any sequence of state 0 paddings, to fill up the extra padding if required):

  • Version 1, state 0: empty, 45, 444.
  • Version 1, state 1: 5, 44.
  • Version 1, state 2: 4, 55.
  • Version 3, state 0: empty, 45, 445.
  • Version 3, state 1: 5, 45.
  • Version 3, state 2: 4, 54.

Shared property tables

You can make multiple objects sharing property tables if it would help. Such objects will then share their name and property values, although they will still have their individual locations and attributes.

It might help if the properties are read-only for those class of objects. An example might be if many rooms contain an identical magical portal all leading to the same location.

Shared text

If you have a long string with only lowercase letters and spaces (no fwords references) and you want the uppercase variant, it can be the previous text string which encodes a permanent shift into uppercase letters.

The coding is:

  • Version 1: 454.
  • Version 3: 444.
  • Version 5: 444444.

Truncated default property table

If you don't need 63 default properties, you can truncate the default property table to only the default properties you need. Number the properties that need defaults with the highest numbers, 63 and down. The header to specify where the object table is, it is then deducted the unused default properties so that the address of the default properties will be correct. (Frolg automatically does this.)

Very long object names

Object names have to be in core (which is limited to 64K) and are limited to 765 Z-characters. If you have very long names, you can make them fit by storing them in the fwords table. (The Z-machine port of Wry Humor does this.)