This is a draft! Things are still subject to change.
Over the past thirty years, many ideas have been theorized and approaches tried with regards to extending and tweaking the behaviour and capabilities of the ZZT and Super ZZT game engines. With the release of the Reconstruction of ZZT greatly lowering the bar for creating such modified engine versions, the complexity and amount of forks, as well as interest in them, has begun to grow significantly. As such, in order to preserve to the extent possible the interoperability ZZT's ecosystem is known for, a standardized way to declare worlds which use or depend on extensions to the original ZZT and Super ZZT game engines is necessary.
A common format for declaring extensions will allow:
The game world types that the ZXT format considers are as follows:
These definitions may be used freely in extension standards without re-introduction.
The extension data can be provided in one of two ways:
cat TOWN.ZAX TOWN.ZZT > TOWN.ZXTis a valid operation).
This is done because neither solution is strictly superior:
The extension header's format is as follows:
|0||u16||magic||0xF227 for ZZT-style worlds, 0xF527 for Super ZZT-style worlds|
|2||u32||block_count||The number of extension blocks which immediately follow.|
After the header follow
block_count extension blocks, in sequence:
|0||u16||flags||Extension flags; defined below.|
|2||u32||owner_id||Extension owner ID|
|6||u16||selector_id||Extension selector ID|
|9||u16||field_length||Field length. Can be between 0 and 65534; if set to 65535, an u32 containing the 32-bit field length follows.|
|11||u8[field_length]||field_data||Field data. Extension-defined.|
An extension being “understood” is defined as one for whose ID pair the engine provides an implementation compliant with its standard.
The extension flags are as follows:
|0||parsing_must||Required for parsing.||If set, an implementation which does not understand this extension MUST NOT continue parsing of the extension block.||Generally, this one will be set to 0.|
|1||reading_must||Required for reading.||If set, an implementation which does not understand this extension MUST NOT read the world file, but may continue parsing the extension block.||If you're changing the world format in a breaking way, set this to 1.|
|2||writing_must||Required for writing.||If set, an implementation which does not understand this extension MUST NOT try to write the world file.||If you're changing the world format in a partially-breaking way, set this to 1. (For instance, Variety redefines the flag section of a .ZZT file in a way which breaks reading only if at least two flags are set; however, a written world could have modified these flags, so we must prevent that. Another example would be re-using the padding fields.)|
|3||playing_should||Recommended for playing.||If set, an implementation which does not understand this extension SHOULD signal this to the end user if an attempt at playing the world is made.||Non-strictly-breaking gameplay changes. For example, modified messages or sound effects. Sometimes, modified charsets or palettes.|
|4||playing_must||Required for playing.||If set, an implementation which does not understand this extension MUST signal this to the end user and prevent an attempt at playing the world.||Breaking gameplay changes. New OOP commands if required, new element IDs, etc.|
|5||editing_should||Recommended for editing.||If set, an implementation which does not understand this extension SHOULD signal this to the end user if an attempt at editing the world is made. An engine does not have to make any effort to support such a world further.||Non-format-breaking (format-breaking go into writing_must, reading_must or both) editor-side changes. Unknown element IDs count, for example.|
|6||preserve_should||Recommended to preserve on resave.||If set, an implementation SHOULD preserve the extension unchanged upon resave; if cleared, an implementation MUST NOT do so, and MUST discard the extension.||Generally, you want this set to 1 - unless the field data relies on other board, world or extension data outside itself. Meant in particular for metadata.|
|7 .. 15||reserved||Reserved.||If set, an implementation MUST NOT continue parsing of the extension block.|
It is important to note that the flags can be distinct from the ID pair; for instance, the same ZZT-OOP extension can be defined as “recommended for playing” if optional for gameplay, but “mandatory for playing” if required for gameplay. However, an extension standard may require you to set or clear certain bits.
Any interactions not listed above are undefined behaviour and MUST NOT be relied upon. For example:
000000FFis reserved for standard extensions - expansions to this standard, as well as potential “obvious” changes everyone agrees upon.
FFFFFFFFis reserved for private extensions - usage when a standard for a given extension is not yet defined, or for internal/private experiments. Publicly released worlds SHOULD NOT use this range.