ZZT file format

From Wiki of ZZT
Revision as of 00:12, 6 December 2021 by Quantum (talk | contribs) (→‎Credits: I messaged Saxxon over Discord and got explicit okay to license their edits to the ModdingWiki article under CC BY-SA 4.0.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

General Info

All 8-bit (byte) values are unsigned. All 16-bit (short) values are signed. Boolean values (such as a player's keys) are represented with 0 for false and 1 for true.

World Name is used by the game both on the title screen to display the game name as well as determine which file to load after the player quits and restarts the game. Therefore if a world contains a world name that is actually the filename of another world, after the player quits and restarts the game, the world with the matching filename will be loaded.

There are some unused bytes after the world information that are ignored by the game. While it is safe to put any data whatsoever into this unused space, it is not saved back to disk by the ZZT and will be converted to empty padding.

World Header

This header is found at the head of all ZZT files. After this information, storage of the boards starts at byte offset 512 (hex 0x200).

Unused values are preserved. Data not listed here is overwritten with zeroes when saving worlds.

Offset Hex Data type Description
0 0x000 INT16LE WorldType
Used to identify the world's format. ZZT uses -1 (FF FF).
2 0x002 INT16LE NumBoards
Number of boards in the world, not including the title screen. Increment by 1 for the real number of stored boards. A value of 0 means only the title screen exists.
4 0x004 INT16LE PlayerAmmo
Player's ammunition.
6 0x006 INT16LE PlayerGems
Player's gems.
8 0x008 char[7] PlayerKeys
Player's keys. A nonzero value means the player has the specified key. The keys are in this order: Blue, Green, Cyan, Red, Purple, Yellow, White.
15 0x00F INT16LE PlayerHealth
Player's health.
17 0x011 INT16LE PlayerBoard
In a world file, this will be the starting board for the player (the title screen, board 0, is always shown first). In a saved game, this will be the board that the player is currently on.
Offset Hex Data type Description
19 0x013 INT16LE PlayerTorches
Player's torches.
21 0x015 INT16LE TorchCycles
Game cycles left for a torch to remain lit.
23 0x017 INT16LE EnergyCycles
Game cycles left for an energizer to be effective.
25 0x019 INT16LE (unused)
27 0x01B INT16LE PlayerScore
Player's score.
29 0x01D UINT8 WorldNameLength
Length of the internal name of the world.
30 0x01E char[20] WorldName
Internal name of the world.
50 0x032 UINT8 Flag0Length
Length of the name of Flag 0.
51 0x033 char[20] Flag0
Name of Flag 0.
71 0x047 UINT8 Flag1Length
Length of the name of Flag 1.
72 0x048 char[20] Flag1
Name of Flag 1.
92 0x05C UINT8 Flag2Length
Length of the name of Flag 2.
93 0x05D char[20] Flag2
Name of Flag 2.
113 0x071 UINT8 Flag3Length
Length of the name of Flag 3.
114 0x072 char[20] Flag3
Name of Flag 3.
134 0x086 UINT8 Flag4Length
Length of the name of Flag 4.
135 0x087 char[20] Flag4
Name of Flag 4.
155 0x09B UINT8 Flag5Length
Length of the name of Flag 5.
156 0x09C char[20] Flag5
Name of Flag 5.
176 0x0B0 UINT8 Flag6Length
Length of the name of Flag 6.
177 0x0B1 char[20] Flag6
Name of Flag 6.
197 0x0C5 UINT8 Flag7Length
Length of the name of Flag 7.
198 0x0C6 char[20] Flag7
Name of Flag 7.
218 0x0DA UINT8 Flag8Length
Length of the name of Flag 8.
219 0x0DB char[20] Flag8
Name of Flag 8.
239 0x0EF UINT8 Flag9Length
Length of the name of Flag 9.
240 0x0F0 char[20] Flag9
Name of Flag 9.
260 0x104 INT16LE TimePassed
Amount of time in seconds that has passed on the current board. Only applicable if the board the player is on has a time limit.
262 0x106 INT16LE TimePassedTicks
This contains information about sub-seconds on time limited boards.
264 0x108 UINT8 Locked
A nonzero value indicates the world is actually a saved game. Additionally, worlds with a nonzero Locked byte can't be edited using the built-in editor.
265 0x109 UINT8[14] (unused)

After this follows the boards. Boards consist of 4 parts: Board Header, RLE Tiles, Board Properties, and Status Element Properties. Status Elements are elements on the board that the game actively processes - these include the player, enemies, any animating blocks, and Scrolls and Objects which can contain ZZT-OOP code.

Board header

ZZT boards are 60x25 tiles.

Offset Hex Data type Description
0 0x000 INT16LE BoardSize
Size of the board, in bytes (excluding the two bytes from this value). Even if the board was corrupted by the built-in editor (which happens sometimes) this value will be correct; the rest of the boards remain intact and in place.
2 0x002 UINT8 BoardNameLength
Length of the board's name.
3 0x003 char[50] BoardName
Board's name.
53 0x035 ZZT_RLE Tiles
Start of the RLE tile data.

Run-length encoded tile data

Tile data is represented as sets of 3 bytes. These sets are repeated until the board is completely filled. For ZZT, this will be 60*25=1500 tiles. The tiles are unpacked from left to right, top to bottom.

Data type Description
UINT8 Count
Number of tiles.
UINT8 Element
Element of the tiles.
UINT8 Color
Color of the tiles.

A small quirk of this RLE format is when the number of tiles is set to zero. Due to the way the decoder is set up, a Count of 0 means there are actually 256 tiles encoded. The built-in editor does not encode tiles using this value despite being decoded correctly in the game, and it will probably crash some older external editors.

Board properties

This information follows directly after the tile RLE data.

Offset Hex Data type Description
0 0x000 UINT8 MaxPlayerShots
Maximum number of player-owned projectiles allowed at once.
1 0x001 UINT8 IsDark
When set to 1, the board is covered in darkness which can only be revealed by using a torch.
2 0x002 UINT8 ExitNorth
Board # that is traveled to when moving off the North side of the board.
3 0x003 UINT8 ExitSouth
Board # that is traveled to when moving off the South side of the board.
4 0x004 UINT8 ExitWest
Board # that is traveled to when moving off the West side of the board.
5 0x005 UINT8 ExitEast
Board # that is traveled to when moving off the East side of the board.
6 0x006 UINT8 RestartOnZap
When set to 1, the player will teleport to the location where they entered the board whenever they are hurt.
7 0x007 UINT8 MessageLength
Length of the on-screen message.
8 0x008 char[58] Message
On-screen message. This is used internally and is not loaded by the game.
66 0x042 UINT8 PlayerEnterX
X-coordinate of the tile where the player entered the board.
67 0x043 UINT8 PlayerEnterY
Y-coordinate of the tile where the player entered the board.
68 0x044 INT16LE TimeLimit
Time limit of the board, in seconds. The player is hurt when time runs out.
70 0x046 UINT8[16] (unused)
86 0x056 INT16LE StatElementCount
Number of Status Elements on the board, not including the player. Increment by 1 to get the real stored number of status elements.

Status Elements

This follows directly after board properties. It is repeated for each Status Element. The first element stored is always the player-controlled element. This element may contain strange values for Step, Leader, Follower, and Parameter information, especially in older worlds / the commercial+shareware worlds.

Offset Hex Data type Description
0 0x000 UINT8 LocationX
X-coordinate. Location coordinates are 1-based, unlike any other coordinates in the file.
1 0x001 UINT8 LocationY
Y-coordinate.
2 0x002 INT16LE StepX
X-step value. This pair of values represents a vector that typically points in one of the four cardinal directions. Its use differs for each type of element.
4 0x004 INT16LE StepY
Y-step value.
6 0x006 INT16LE Cycle
Cycle. This represents the frequency, in ticks, at which the game will process this status element.
8 0x008 UINT8 P1
Parameter 1. Its use will differ depending on the type of element.
9 0x009 UINT8 P2
Parameter 2. Its use will differ depending on the type of element.
10 0x00A UINT8 P3
Parameter 3. Its use will differ depending on the type of element.
11 0x00B INT16LE Follower
Follower status element. Its value determines if another status element is linked behind this one. Used for linking centipedes.
13 0x00D INT16LE Leader
Leader status element. Its value determines if another status element is linked in front of this one. Used for linking centipedes.
15 0x00F UINT8 UnderID
Element of the tile under this status element.
16 0x010 UINT8 UnderColor
Color of the tile under this status element.
17 0x011 INT32LE Pointer
Stores the location in memory of the code that this status element is using. Status elements typically point to their own code until they #BIND the code of another - in which case this memory location value is replaced with the new one. ZZT does not use this value when loading worlds, and always sets it to 0 when saving worlds.
21 0x015 INT16LE CurrentInstruction
The offset in bytes of the code block to execute ZZT-OOP from. Only Objects and Scrolls can execute ZZT-OOP.
23 0x017 INT16LE Length
There are two uses for this value: If this value is positive, it represents the number of bytes that are in the code block. If this value is negative, the absolute value of this value represents the Status Element number to copy code from. This saves space by removing redundant code duplication. Since code is shared in this way, all modifications to code will affect any other Status Elements using it.

After this follows 8 bytes of padding (2 unused pointers). If "Length" is positive, the code is stored after the padding.

Element properties

These are all possible internal properties for each element. They are initialized on startup and used both in-game and in the editor.

Property Description
Id Id number of the element
Hex Hexidecimal representation of the Id number
Name Known name of the element, which may not be present internally
Character ASCII character for the default draw code, which may be ignored if special draw code is enabled
Color Default color. If the color is 0xFE, then new tiles will be created with the primary color as the background and a white foreground. If the color is >= 0xF0, any primary color is allowed, but in the editor you can't choose the color unless the default color is 0xFF
Destructible Element can be destroyed by bullets and by being crushed by puzzle pieces
Pushable Element can be pushed. The NS/EW sliders are a special case in the code, so they will not be marked with this flag
Editor Floor When using the editor, actors such as enemies can be placed on top of elements marked with this flag. Has no effect during gameplay.
Floor Elements with this flag can freely be moved upon by actors
Shown ZZT only. Elements marked with this flag will always be shown, even on dark boards
Special Draw If this flag is set, the default draw code is bypassed with different draw code
Draw Code Offset of the routine that performs the drawing, if Special Draw is set
Cycle Default cycle. If this is -1, the element is not generated as an actor. Creatures will have cycles above zero
Act Code Offset of the routine that performs standard behavior. For example: creature movement, bomb countdown
Interact Code Offset of the routine that handles when a player touches the element. For example: item pickups, entering a passage
Menu# Number of the editor menu where this element can be found
Key Key press which is mapped to this element in the editor
Internal Name Name of the element used in the editor. It is also used by OOP- the parser will remove all symbols and spaces and compare that
Category When it comes time to display this element in the editor, if present, the category will be drawn in yellow first.
Edit P1 Text to show when editing the P1 of an actor that uses this element
Edit P2 Text to show when editing the P2 of an actor that uses this element
Edit P3 Text to show when editing the P3 of an actor that uses this element
Edit Board Text to show when selecting the target board
Edit Step Text to show when selecting the target direction
Edit Code Text to show when editing an actor's code (scroll or object OOP)
Points When an actor using this element is killed by the player, it's worth this much score

ZZT elements

Id Hex Name Character Color Destructible Pushable Editor Floor Floor Shown Special Draw Draw Code Cycle Act Code Interact Code Menu# Key Internal Name Category Edit P1 Edit P2 Edit P3 Edit Board Edit Step Edit Code Points
0 0x00 Empty 0x20 0x70 Yes Yes 0x0020 -1 0x0000 0x0010 0 Empty 0
1 0x01 Board Edge 0x20 Any (0xFF) 0x0020 -1 0x0000 0x3973 0 0
2 0x02 Messenger 0x20 Any (0xFF) 0x0020 -1 0x0039 0x0010 0 0
3 0x03 Monitor 0x20 0x07 0x0020 1 0x4481 0x0010 0 Monitor 0
4 0x04 Player 0x02 0x1F Yes Yes Yes 0x0020 1 0x3E2F 0x0010 1 Z Player Items: 0
5 0x05 Ammo 0x84 0x03 Yes 0x0020 -1 0x0000 0x3289 1 A Ammo 0
6 0x06 Torch 0x9D 0x06 Yes 0x0020 -1 0x0000 0x37B6 1 T Torch 0
7 0x07 Gem 0x04 Any (0xFF) Yes Yes 0x0020 -1 0x0000 0x3306 1 G Gem 0
8 0x08 Key 0x0C Any (0xFF) Yes 0x0020 -1 0x0000 0x3169 1 K Key 0
9 0x09 Door 0x0A Any BG (0xFE) 0x0020 -1 0x0000 0x33DA 1 D Door 0
10 0x0A Scroll 0xE8 0x0F Yes 0x0020 1 0x2F9F 0x308B 1 S Scroll Edit text of scroll 0
11 0x0B Passage 0xF0 Any BG (0xFE) Yes 0x0020 0 0x0000 0x3372 1 P Passage Room thru passage? 0
12 0x0C Duplicator 0xFA 0x0F Yes 0x2A15 2 0x2BFF 0x0010 1 U Duplicator Duplication rate?;SF Source direction? 0
13 0x0D Bomb 0x0B Any (0xFF) Yes Yes 0x1872 6 0x18DA 0x19F3 1 B Bomb 0
14 0x0E Energizer 0x7F 0x05 0x0020 -1 0x0000 0x2034 1 E Energizer 0
15 0x0F Star 0x53 0x0F Yes 0x1D5D 1 0x1DE9 0x00F5 0 Star 0
16 0x10 Clockwise 0x2F Any (0xFF) Yes 0x171C 3 0x176C 0x0010 1 1 Clockwise Conveyors: 0
17 0x11 Counter 0x5C Any (0xFF) Yes 0x17C7 2 0x1817 0x0010 1 2 Counter 0
18 0x12 Bullet 0xF8 0x0F Yes 0x0020 1 0x0F65 0x00F5 0 Bullet 0
19 0x13 Water 0xB0 0xF9 Yes 0x0020 -1 0x0000 0x3B03 3 W Water Terrains: 0
20 0x14 Forest 0xB0 0x20 0x0020 -1 0x0000 0x38D0 3 F Forest 0
21 0x15 Solid 0xDB Any (0xFF) 0x0020 -1 0x0000 0x0010 3 S Solid Walls: 0
22 0x16 Normal 0xB2 Any (0xFF) 0x0020 -1 0x0000 0x0010 3 N Normal 0
23 0x17 Breakable 0xB1 Any (0xFF) 0x0020 -1 0x0000 0x0010 3 B Breakable 0
24 0x18 Boulder 0xFE Any (0xFF) Yes 0x0020 -1 0x0000 0x34E3 3 O Boulder 0
25 0x19 Slider (NS) 0x12 Any (0xFF) 0x0020 -1 0x0000 0x34E3 3 1 Slider (NS) 0
26 0x1A Slider (EW) 0x1D Any (0xFF) 0x0020 -1 0x0000 0x34E3 3 2 Slider (EW) 0
27 0x1B Fake 0xB2 Any (0xFF) Yes Yes 0x0020 -1 0x0000 0x3949 3 A Fake 0
28 0x1C Invisible 0xB0 Any (0xFF) 0x0020 -1 0x0000 0x3848 3 I Invisible 0
29 0x1D Blink wall 0xCE Any (0xFF) Yes 0x242E 1 0x2445 0x0010 3 L Blink wall Starting time Period Wall direction 0
30 0x1E Transporter 0xC5 Any (0xFF) Yes 0x1CC5 2 0x1C85 0x1C41 3 T Transporter Direction? 0
31 0x1F Line 0xCE Any (0xFF) Yes 0x122A -1 0x0000 0x0010 0 Line 0
32 0x20 Ricochet 0x2A 0x0A 0x0020 -1 0x0000 0x0010 3 R Ricochet 0
33 0x21 Blink Ray (Horizontal) 0xCD Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
34 0x22 Bear 0x99 0x06 Yes Yes 0x0020 3 0x054F 0x00F5 2 B Bear Creatures: Sensitivity? 1
35 0x23 Ruffian 0x05 0x0D Yes Yes 0x0020 1 0x0351 0x00F5 2 R Ruffian Intelligence? Resting time? 2
36 0x24 Object 0x02 Any (0xFF) Yes 0x2B85 3 0x2AA5 0x2BB7 2 O Object Character? Edit Program 0
37 0x25 Slime 0x2A Any (0xFF) 0x0020 3 0x20AE 0x2295 2 V Slime Movement speed?;FS 0
38 0x26 Shark 0x5E 0x07 0x0020 3 0x2321 0x0010 2 Y Shark Intelligence? 0
39 0x27 Spinning gun 0x18 Any (0xFF) Yes 0x11D0 2 0x12A7 0x0010 2 G Spinning gun Intelligence? Firing rate? Firing type? 0
40 0x28 Pusher 0x10 Any (0xFF) Yes 0x3517 4 0x358A 0x0010 2 P Pusher Push direction? 0
41 0x29 Lion 0xEA 0x0C Yes Yes 0x0020 2 0x0113 0x00F5 2 L Lion Beasts: Intelligence? 1
42 0x2A Tiger 0xE3 0x0B Yes Yes 0x0020 2 0x022D 0x00F5 2 T Tiger Intelligence? Firing rate? Firing type? 2
43 0x2B Blink Ray (Vertical) 0xBA Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
44 0x2C Head 0xE9 Any (0xFF) Yes 0x0020 2 0x06BF 0x00F5 2 H Head Centipedes Intelligence? Deviance? 1
45 0x2D Segment 0x4F Any (0xFF) Yes 0x0020 2 0x0EED 0x00F5 2 S Segment 3
46 0x2E 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
47 0x2F Text (Blue) 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
48 0x30 Text (Green) 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
49 0x31 Text (Cyan) 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
50 0x32 Text (Red) 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
51 0x33 Text (Purple) 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
52 0x34 Text (Brown) 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0
53 0x35 Text (Black) 0x20 Any (0xFF) 0x0020 -1 0x0000 0x0010 0 0

Credits

The ZZT file format was reverse engineered by SaxxonPike, Kev Vance and David Hammond.

This article is based on content written by SaxxonPike as part of a corresponding article on the ModdingWiki. Saxxon has given permission to license their edits to that article under CC BY-SA 4.0.