Information Topics

General Information

ZZT World Support



ZZT Ultra Editors

There are two content editors supported in ZZT Ultra: The GUI editor and the world editor. Both of these are accessible from the top-level menu.

GUI Editor

The GUI editor is very simple. The main interface allows you to define the size, position, and other information about the GUI as a whole. The text-editing interface allows you to edit the characters and colors of the display.

The main interface has the following choices:

  • L) Load GUI: Load a ZZTGUI file.
  • S) Save GUI: Save current GUI as a ZZTGUI file.
  • P) Edit GUI properties (a JSON dictionary).
  • T) Enter text-editing interface.
  • D) Redraw the GUI.
  • F6) Cycle foreground color.
  • F7) Cycle background color.
  • F8) Cycle blink flag.

The GUI Properties

GUI properties are quite straightforward:

  • GuiLocX and GuiLocY define the 1-based column and row, respectively, where the GUI is rendered on the screen. This could be (1, 1) for a left-justified GUI, (61, 1) for a right-justified GUI, etc.

  • GuiWidth and GuiHeight define the width and height of the GUI, respectively. These must be numbers greater than or equal to 1.

  • OverallSizeX and OverallSizeY define the width and height of the entire display, respectively, which includes both the GUI and the viewport. This is (40, 25) for 40-column mode and (80, 25) for 80-column mode.

  • Use40Column is 1 for 40-column mode and 0 for 80-column mode. Generally, all GUIs in ZZT are 80-column, and all GUIs in Super ZZT are 40-column. There are a few exceptions to this rule for Super ZZT--the editor and title screens in Super ZZT are in 80-column mode.

  • Viewport is a JSON array of four numbers: the 1-based starting viewport column, the 1-based starting viewport row, the number of columns in the viewport, and the number of rows in the viewport. The viewport can be either shown to the side of the GUI (i.e. ZZT) or within the GUI as an internal frame (i.e. Super ZZT).

  • SCROLL is a JSON array of five numbers that sets where the scroll interface should be displayed relative to the GUI. The first two numbers are the 1-based center GUI column and the 1-based center GUI row. The next two numbers are the number of columns and number of rows to be shown within the scroll interface when fully opened. The final number is synonymous with Use40Column: 0 shows a scroll interface in 80-column view, while 1 shows a scroll interface in 40-column view.

    The scroll interface rarely appears as a GUI property because its default location is generally acceptable most of the time. When it does need to be changed, one should remember that the center position is relative to the GUI, not the viewport.

  • KeyInput is a JSON dictionary keyed to keyboard codes, with values representing event-handler message names that are dispatched to the main type code. If the keyboard code is a number, it is assumed to be an AS3 keyboard code. If the keyboard code is not a number (letter, punctuation, etc.), it is assumed to be the actual key itself.

  • Label is a JSON dictionary keyed to label names, with values representing label position, length, and color information. The value, which is a JSON array, is ordered as 1-based column offset, 1-based row offset, length of label (in columns), default color attribute, and an optional right-justification flag (1=right-justified; absent=left-justified).

  • MouseInput is a JSON dictionary keyed to event-handler message names, with values representing label position and selection box size. These definitions identify parts of the GUI that can act as clickable mouse buttons.

  • SCANLINES is 0, 1, or 2, and is optional. If it is present, the number of scanlines is set whenever the GUI is displayed. See #SCANLINES in the ZZT-OOP documentation for more information.

  • BIT7ATTR is 0 or 1, and is optional. If it is present, the meaning of bit 7 of the color attribute is changed to high-intensity color (0) or blink (1) whenever the GUI is displayed. See #BIT7ATTR in the ZZT-OOP documentation for more information.

  • PALETTE is an array of RGB scalar integers, and is optional. If it is present, this palette is automatically applied whenever the GUI is displayed. See #PALETTEBLOCK in the ZZT-OOP documentation for more information.

Special Labels

There are two special TOAST keys that can be set within the Label dictionary: TOAST1 and TOAST2. When a one- or two-line text message needs to be displayed, it is flashed for a moment at this location. ZZT games have only TOAST1 defined (to be shown at the bottom of the screen), while Super ZZT games have both TOAST1 and TOAST2 defined (to be shown on the two lines just below the viewport).

The FILEMESSAGE and FILEENTRY keys are also special. FILEMESSAGE identifies the label location that displays a file-load or file-save message. FILEENTRY defines the actual input location where the user types text.

The CONFMESSAGE key is also special. CONFMESSAGE displays a "Yes/No" confirmation message when prompted for save or exit.

Keyboard Key Mapping

When defining the KeyInput dictionary, one should structure the key map in an intuitive fashion. While it is not absolutely necessary to display the keyboard key availability using text within the GUI, a user will find the interface easiest to figure out if they can identify which keys are immediately available.

The key map assumes that a key, when pressed, is identified by either a character code (if printable) or an AS3 code (if unprintable) without any shift status applied. Simply specifying the code "C", for example, will mean the key is only accepted if the key is unshifted. To capture the key with the "Shift" key held down, one would use "Shift+C" instead of "C". To capture the key with the "Ctrl" key held down, one would use "Ctrl+C" instead of "C".

The following are some useful AS3 codes for unprintable keys or special punctuation:

  • Backspace: 8
  • Tab: 9
  • Enter, Numpad Enter: 13
  • Shift: 16
  • Control: 17
  • Escape: 27
  • Windows key: 91, 92
  • Context menu key: 93
  • Caps lock: 20
  • Scroll Lock: 145
  • Pause/Break: 19
  • Tilde: 192
  • Minus/underscore: 189
  • Equals/Plus: 187
  • Open bracket: 219
  • Close bracket: 221
  • Backslash: 220
  • Semicolon/colon: 186
  • Single quote/double quote: 222
  • Comma/Less than: 188
  • Period/Greater than: 190
  • Slash/Question mark: 191
  • Left: 37
  • Up: 38
  • Right: 39
  • Down: 40
  • Insert: 45
  • Delete: 46
  • Home: 36
  • End: 35
  • Page Up: 33
  • Page Down: 34
  • F1-F12: 112-123
  • Num lock: 144
  • Numpad Slash: 111
  • Numpad Asterisk: 106
  • Numpad Minus: 109
  • Numpad Plus: 107
  • Numpad Dot/Del: 110
  • Numpad 5: 12
  • Num lock-activated numpad numbers: 96-105

There are a few limitations concerning which keys can be mapped, based upon the inherent embedded-within-browser requirement of Flash applications:

  • Some of the function keys, such as F10, might be forced to escape to the browser level. Capturing function keys is not recommended.
  • The "Tab" key can be captured, but some browsers escape the key to act as a page component toggle.
  • The "Alt" key is not capturable in most browsers.
  • The "Print Screen" key is not capturable in most browsers.
  • In general, it is unwise to rely upon key codes that were not originally present in a 101/102 keyboard. There is a risk that such key codes would not be standardized across every keyboard variation or localization.

Mouse Input Definitions

The MouseInput dictionary is optional for many GUIs, because ZZT did not originally feature clickable button interfaces. However, people have come to expect that mouse functionality will be available in modern user interfaces, so it is a good idea to support MouseInput labels for many, if not all, of the mapped keyboard keys.

A clickable location on the GUI is defined by setting the key to the event-handler message name to be dispatched to the main type code. The value is a four-element JSON array, ordered as 1-based column offset, 1-based row offset, length of button (in columns), and height of button (in rows).

Mouse-over events for a clickable location will invert the coloration, indicating that the area is clickable. A left-click will dispatch the message label.

The Text-editing Interface

When in this mode, the display becomes rather sparse. The reason for the sparse layout is that it is not certain how much space the user will need when editing the GUI. The worst-case scenario requires the entire 80x25 space to be available.

The help labels on the right-hand side are not permanent if this much space is required--moving the cursor over the labels will show the actual GUI characters underneath, and the labels move to the left-hand side if you are editing on the right-hand side.

Keyboard commands are as follows:

  • Arrows: Move cursor.
  • ENTER: Pick up character under cursor.
  • Shift+ENTER: Pick up character and color under cursor.
  • SPACE: Enter picked-up character.
  • TAB: Toggle auto-drawing of picked-up character.
  • Numpad +/-: Cycle through ASCII characters.
  • F3: Add GUI label at cursor.
  • F4: Add mouse input label at cursor.
  • F6: Cycle foreground color.
  • F7: Cycle background color.
  • F8: Cycle blink flag.
  • Ctrl+K: Show color dialog.
  • Shift+Arrows: Select copying region.
  • Ctrl+C: Copy selected region.
  • Ctrl+V: Paste region at cursor.
  • Escape: Return to main interface.

Use the cursor keys to move the editing cursor. To enter text in the GUI, simply type text and the cursor will advance.

You can "pick up" the character under the cursor with ENTER. To place this last "picked up" character, press SPACE.

Often, you will want to enter GUI characters that are not accessible from the keyboard. To choose a character from the range 0-31 or 127-255 of Code Page 437, use the +/- numpad keys to cycle through the last "picked up" character.

You can quickly add a text label to the properties from the cursor location by pressing F3. The label size and color still need to be filled out.

You can quickly add a MouseInput label to the properties from the cursor location by pressing F4. The label sizes still need to be filled out.

Using a GUI in ZZT-OOP

The #USEGUI command loads a GUI. Note that the stark differences in how some GUIs are defined can make this command radically change the display in ways that might be disconcerting, such as a transition between 40-column and 80-column modes. The best gameplay experience occurs when the GUI remains on one side of the screen with minimal changes.

The #SETGUILABEL command draws label contents to one of the named labels (see the Label property). This is ideal for visually updating the player's inventory.

World Editor

The world editor in ZZT Ultra is the analog of the world editor (a.k.a. "board editor") present in the original ZZT and Super ZZT engines. When invoked, it allows users to explore, edit, and test their own content. All of the advanced features of the ZZT Ultra editor are accessible within the integrated editor.

The world editor GUI occupies the right-hand screen margin. The left-hand portion (60x25) contains the gridded data for the currently selected board within the world file. You move the editor cursor around with the arrow keys or the mouse. To place the currently selected pattern in the board, use the left mouse button or the space bar.

While the editor key commands used in the editor are visible, there is much more than what can be shown on a single page. Press the "M" key to cycle through the key mappings.

Note that you do not need to have the page currently showing the key mapping to be displayed in order for the key to work--the keys for all four of the toggled GUIs will always work while the editor is active.

ZZT Ultra is not, of course, the only ZZT-themed engine to feature an editing interface. In the interests of maintaining the capabilities and layouts of classic editors, ZZT Ultra offers parallel editor interfaces for individuals who want to work with such older interfaces, having already gotten used to them. Press the "E" key to cycle through the four interfaces. These include the default ZZT Ultra editor, KevEdit, ZZT, and Super ZZT.

Note that the key mappings will also match these classic editors; you will not be able to access all ZZT Ultra editing features from these interfaces.


There are several indicators on the right-hand side that identify mode information during editing. Although the exact display and capabilities of such indicators will vary depending on which editor interface is shown, the concept is the same across all editors.

The Cursor Coordinates, in parentheses, report the current cursor location. This can be useful when constructing coordinate pairs in ZZT-OOP. Also, it serves as a measuring queue for large boards, such as those in Super ZZT. Large boards cannot be contained within the 60x25 display; moving the cursor to the edges of the display will cause the board viewport to scroll.

The Status Element Object Count reports the number of independently tracked status element object instances that exist within the board. The first number is the count, while the second number is the theoretical maximum. ZZT Ultra does not have an inherent maximum, so 9999 is set as a practical number. For ZZT and Super ZZT, on the other hand, the maximum is much lower, to the tune of 152 or 130. You should be mindful of this limit when saving content in legacy ZZT or Super ZZT formats.

The Pattern Indicator shows the currently selected pattern, which will be placed with the space bar and other editing commands. Press "P" to cycle through the individual patterns.

This pattern indicator is actually composed of two different sections: the built-in patterns and the back-buffer patterns. Built-in patterns are always available. Back-buffer patterns are filled as various types are selected and acquired, with a record of patterns accumulating as you edit a board.

The Color Palette shows the currently selected colors, which will be placed with the space bar and other editing commands. Press "C" to cycle through the foreground colors, and "Shift+C" to cycle through the background colors.

Pattern Placement

Use "P" to move the pattern cursor forward, and "Shift+P" to move the pattern cursor backward. To select an EMPTY type, press the "0" key. To select one of the first nine back-buffer slots, press a number key from "1" to "9".

To place the currently selected pattern at the cursor location, use left mouse button or the space bar. You can also toggle the "drawing mode" by pressing the TAB key, which draws the selected pattern where the cursor is moved. A variation on drawing mode is "cycled drawing mode," activated by Shift+TAB. Cycled drawing mode advances the pattern cursor by one (either forward or backward) through the built-in patterns or back-buffer patterns, whichever section is selected.

The color of the placed type depends on whether the pattern cursor is selecting a built-in type (SOLID, NORMAL, BREAKABLE, WATER, EMPTY, or LINE), or a back-buffer type. For a built-in type, the color is always created from the foreground color, background color, and blink flag. For a back-buffer type, the color from the back-buffer is used, unless the default color mode flag is unset (use "D" to toggle). The default color mode flag controls whether the selected color overrides the color that would be placed from the back-buffer.

CRT colors allow for as many as 256 color combinations per square: 16 foreground colors, 8 background colors, and a blink flag. The color, as it is represented numerically, always equals (foreground color) + (background color * 16) + (blinkFlag * 128). The "V" key toggles the blink flag.

It is possible to change the blink bit to act as a high-intensity background color. Press "Shift+K" to toggle between blink and high-intensity background. This setting is retained when a world file is saved as the BIT7ATTR world property.

Type Selection

The built-in patterns only cover basic wall types. The full range of types become available by invoking one of the type-selection pages. "F1" selects non-blocking (or "floor") types, "F2" selects blocking types, and "F3" selects types represented by status elements.

To select a type, highlight the type with the arrows and press "ENTER". The new type will be added to the back-buffer and placed at the cursor location. Note that ZZT Ultra lets you edit and add your own types from this page. This capability is discussed below.

Once a type has been placed in the board, it can be edited (if it is a status element) using "ENTER". The type can also be removed (and replaced by EMPTY) with the "Delete" key.

Text Entry

The "F4" key toggles text-editing mode. Most keystrokes in this mode write text characters of the currently selected color to the board. Text acts as a solid wall in the game.

ZZT Ultra supports hexadecimal ASCII code entry for those Code Page 437 characters that would not be selectable from the keyboard. To write such a character, press "F7", then press a number or letter (A-F) twice to enter a hexadecimal code from 00 to FF.

Color and Character Dialogs

The typing of characters and selection of colors can be somewhat slow if a specific combination is desired. ZZT Ultra offers an alternate way to select characters and colors: quick dialogs with all selections readily available.

Press "K" to open the color selection dialog, which provides all foreground and background colors (press "ENTER" to choose). The right-hand side will provide either blinking colors or high-intensity background colors based on the BIT7ATTR world property ("Shift+K" toggles this).

Press "Ctrl+A" to open the character selection dialog, which provides all characters in Code Page 437 that can be entered as text. Note that you do not need to be in text-editing mode to invoke the character selection dialog.

Back-buffer Manipulation

Types automatically forward-feed the back-buffer when selected. Whether the type is placed using "F1", "F2", or "F3", or copied directly using "ENTER" (with status element editing) or "Insert" (without status element editing), the result is always that the copy is placed at position 1 in the back-buffer, with previous position 1 moving to position 2, 2 moving to 3, etc. with the last entry in the back-buffer being discarded.

If such automatic advancement is not desired, one can temporarily "lock" the back-buffer using the "/" key. When the back-buffer is locked, types can still be placed, but the buffer will never change.

One can also change the size of the back-buffer using the ">" and "<" keys. It is possible to have a back-buffer larger than what the editor interface would show (more than 10) if a back buffer this large is desired.

There is another way to fill the back buffer: "acquire mode." Press the "A" key to toggle this mode. When the editor is in acquire mode, the back buffer is filled with the type under the cursor wherever it moves. It is possible to copy an entire long sequence of types into the buffer, instead of individually copying them at each spot. This mode is helpful if you wish to use cycled drawing mode or gradient fill with the acquired types.

Copying and Pasting

Editing is not limited to just single squares at once. You can pick up entire sections of a board and paste them anywhere you want, including other boards. To select a box, hold the "Shift" key down and move the arrow keys. This draws a "selection box" that can be copied or acted upon in other ways. You can cancel a selection with the "Escape" key.

To copy the box, press "Ctrl+C". To paste the box, press "Ctrl+V". You will get an opportunity to select the exact new location in the board before the section is finalized.

You can also "cut" a box using "Ctrl+X". The only difference from "Ctrl+C" is that the currently selected pattern is left behind in the cut section.

ZZT Ultra is not limited to selecting only rectangular sections. Multiple rectangular selections are possible by moving the cursor with the Shift key depressed, then without it depressed, then with it depressed. One can also perform a "flood-fill selection" using "X", or a "type/color picker selection" using "Shift+X".

Fill Operations

One can "flood-fill" the currently selected pattern at the cursor location by using the "F" key. Both the type and the color must match, and be adjacent using the four-neighbors fill algorithm, for a square to be filled. No fill operation will happen if the type and color are the same as the selected pattern, or if a BOARDEDGE type is the target.

There is also a "random flood-fill" action. To randomly fill the contents of the area with the built-in patterns (or back-buffer contents, whichever is selected), press "Shift+F". Be careful about this action--it is not easy to undo a random fill.

Finally, there is a "gradient fill" action. Gradient fill lets you write a complex, striped pattern of types to a target. The downside of gradient fill is that it requires a learning curve before it can be used effectively.

Press "G" to invoke gradient fill. If there is no selected section, you will be prompted to select one. The main gradient interface allows you to set the two foci, the general shape pattern, and the extent of dither.

The focus points, or "foci," serve as boundary points for drawing imaginary lines through which the gradient shape is connected. Press the "TAB" key to switch between points. Use the arrows to move the active focus point. As you move the foci, the gradient preview is drawn in the selected area.

There are three shape patterns: linear, bilinear, and radial. A linear shape ranges between the type extents in a min->max pattern. A bilinear shape ranges in a min->max->min pattern. A radial shape is similar to linear, but it ignores the line angle and instead looks at only the first focus point and the distance between the foci.

The "dither" factor is the extent of randomness injected into the gradient pattern. By default, there is no dithering; use +/- to change it.

The types chosen for the pattern itself depend on whether the built-in types or back-buffer types are selected in the pattern interface. The built-in types range from SOLID to EMPTY, but they do not include the type LINE. The back-buffer types range over the entirety of the buffer size. This is one way that size customization of the back buffer can be quite useful: you can select as many types for gradient fill as desired.

When you are satisfied with the pattern, press "ENTER" to write the gradient shape permanently.

Region Editing

Rectangular regions are a new feature of ZZT Ultra. You can store as many regions in a board as desired. Regions can be used in ZZT-OOP to quickly locate target areas by name.

To create a region in a board, select the region using "Shift" and arrow keys, then press "Ctrl+R". You will be prompted to enter the name for the region, which is then stored in the board.

If you want to show which regions are already defined in the board, press "Ctrl+R" without selecting anything. This highlights all regions on the board.

To modify an existing region, place the cursor within the region, then press "Ctrl+R". From the text entry box, you can change the region's name. You can also remove the region from the board by clearing the name out completely, setting the name to nothing.

Regions are not storable in legacy world files; they can only be stored in WAD files.

World Editor: Detailed Editing

The most important parts of any game are the fine details. ZZT Ultra provides many types of of interfaces and dialogs for editing these details.

Because ZZT Ultra attempts to move beyond the concept of fixed-length storage formats, many of the containers used for detailed content are dictionaries. A dictionary is a set of key-value pairings, as opposed to a fixed-length list indexed by number.

For this reason, there are several locations within the world editor where there are text boxes for entering JSON content. When presented with a JSON text box, the user can type, copy, and paste text freely between the editor and any other text file. The fact that JSON is a common and human-readable standard makes its usage relatively straightforward.

Status Element Editing

A status element is edited by selecting its square with the cursor within the board, and pressing the "ENTER" key. This brings up a scroll with the individual fields of the object.

Some status element fields are common to all types, including CYCLE, STEPX, and STEPY. You can adjust these values using the left and right arrow keys, or enter a new value via a text box by pressing "ENTER".

Most other status element fields will vary based on the type itself. Common fields include CHAR (the shown character), ONAME (specific name given to object instance), and the legacy parameters P1, P2, and P3. These can be adjusted and edited like the common fields.

ZZT Ultra departs from other forms of ZZT in that it lets a status element contain any number of additional members, including members not defined for the type. These extra members can be edited with "ENTER" or removed with "Delete". Note that it is not possible to remove a member that is defined for the type itself; the "Delete" key will simply zeroize the member, instead of removing it.

One can also edit the whole dictionary at once using JSON. From here, a user can add or edit the fields freely.

For status elements with the HASOWNCODE property set for the type, the $CODE virtual member lets the user modify the code for the status element. This displays the code editor interface for the object's custom code portion.

Code/HLP File Editor

When the "$CODE" member of a status element is edited, or if the HLP file editor is opened using the "!" key, ZZT Ultra displays a text box for entering program code. This is similar to code editors found in other ZZT editors. This editor differs from the others in that the user can copy and paste the text freely between this text box and other applications.

ZZT-OOP code is what makes ZZT "tick" for the most part. For ZZT Ultra, the entire engine depends upon the code. Refer to the ZZT-OOP Reference for more information.

After you are finished editing the code, pressing the Escape key will perform an action based upon how the code editor was invoked. If the editor is modifying custom code for a status element object that supports custom code, the code entered in the box replaces the custom code defined for that status element. However, if the HLP editor was displayed, you are prompted to save the text to a local file. Note that if you decline to save a HLP file, you can re-open the editor and save it later.

HLP file documentation can be useful when describing details of a ZZT world in a semi-offline fashion. Of course, HLP files are somewhat of a rarity, because they were never described in the original ZZT's documentation. This means there are few ZZT adventures that support them. It is often sufficient to document a ZZT world with ordinary text files or in-game documentation.

In today's day and age, users often want a level of convenient syntax highlighting that goes beyond what an in-editor text box could offer. With this in mind, two Notepad++ language syntax UDL files are provided, one for ZZT Ultra's brand of ZZT-OOP, and one for classic ZZT-OOP.

Board Properties

Press "I" to bring up the board properties, also known as board info, for the current board. The displayed scroll shows board properties with most relevant properties listed first, followed by all other properties sorted alphabetically.

The board name, size, time limit, shot limit, and re-entry-on-zap behavior are modified by selecting the corresponding property and entering a new value into the text box. For the board edge links, a board-selection scroll is opened.

If the SIZEX or SIZEY properties are changed, the board is resized to the new dimensions. Even though there is no logical maximum for the board dimensions, it is generally a good idea to limit the boards to a reasonable size, such as the Super ZZT dimensions of 96x80. Remember that legacy formats only allow board sizes of 60x25 or 96x80--no other sizes are supported.

It is possible to edit all board regions at once using JSON. Regions are keyed by name, with each inclusive rectangular range existing as a JSON array. One can add or modify any number of regions freely.

One can edit the whole dictionary of board properties using JSON. From the JSON interface, a user can add or edit the fields freely.

Board Management

To select a different board in the world file, press "B" and pick a board from the scroll. To add a new board, select the "Add New Board" link. You can also quickly move up or down in the board storage order using the "PgUp" and "PgDn" keys.

It is also possible to delete a board from the world file using Delete. When this happens, ZZT Ultra modifies the entire world file, not just the record of boards. The reason for this is that board passage links and edge-navigation links are stored as numerical indexes, and these indexes need to be decreased as appropriate to match the new metadata configuration.

A world file is required to have at least one board (the title screen). There is no way to delete the first board in the world file.

World Properties

To open world properties, press "W". There are many different features about the ZZT world that can be configured within ZZT Ultra.

The most basic world information is listed first: the world name, the world type, and the starting board. The default world type code is -3 (representing a ZZT Ultra world). This type code is implicitly set to -1 (ZZT) or -2 (Super ZZT) when the world is saved in a legacy format. The type code should never be changed in theory, but it is present in the off-chance that it might have some future meaning.

Inventory properties control what inventory the player starts with. This is a composite of ZZT and Super ZZT inventory, so not all of these numbers will be relevant if the world file is saved in a legacy format. The individual "KEYnn" properties represent the count of a key of a particular color (see color lookups).

There is an option to edit all world properties, including the numerous properties associated with the general configuration. These properties are stored only within a WAD file--they do not have any representation in legacy formats.

Global Variables

From the world properties scroll, you can open two different interfaces for editing global variables. The "common" global variables only include those variables that do not begin with a dollar symbol ($). Variables used in the fundamental run operations of the engine itself are not deemed important to the world file, so it makes sense to screen out those variables.

If you want to view all global variables, including the variables used by the ZZT Ultra engine itself, you are presented with a JSON interface. Be careful about which variables are modified here, as the engine often depends upon them being set.

Because global variables in ZZT Ultra are a superset of the original global flag functionality, you can modify the "flag" functionality from this interface if you intend to save in a legacy world file format. However, you must remember that the classic flag limitation only permits 10 flags for ZZT and 16 for Super ZZT.

Type Customization

The custom types for a world file can be edited from the world properties scroll. Custom types represent the entire set of new types and type overrides for the world. The type selection pages let a user create or edit individual types; those actions on such pages open the custom types JSON interface.

Type definition information is described here. You must ensure that all information is correct, and code complete, before exiting the interface. Types edited here are applied to the editor immediately, including custom drawing handlers.

You can observe the default definitions for all built-in types here.

If you must remove a previously added type, make sure that no instances of that type exist anywhere within any board. Problems will surface in the editor if a removed type is encountered.

For most types, any edits you make to code will replace the existing type completely with the new code. For example, if you edit the type for RUFFIAN, the previous RUFFIAN code is discarded and replaced by what you write in the "CODE" member.

For the main type code (the EMPTY type), changes you make will not replace the previous main type code in its entirety. Instead, the individual dispatch labels will override those present in the default implementation for the type. Dispatch labels that are not overridden will continue to be invoked from the default implementation. In this manner, the main type code customizations only serve to edit the type piecemeal, instead of total replacement.

Other Properties at World Scope

The masks for a world file can be edited from the world properties scroll. Learn more about masks here.

The sound effects for a world file can be edited from the world properties scroll. Learn more about stored sound effects and playback here.

The GUI Manager is accessed from the world properties scroll. You can configure which GUI definitions are stored within the world file. Any GUI edited in the GUI editor can be uploaded into the world file and referenced by ZZT-OOP code. Learn more about the GUI editor here.

The WAD Manager is accessed from the world properties scroll. You can add any number of additional WAD lumps to the world file if you wish. ZZT Ultra lets you embed nearly any file within the world file as a lump, on the condition that the lump name cannot conflict with any lump name already in use by the world file format itself (e.g. STATELEM). ZZT Ultra will tweak any conflicting name that you provide to the WAD Manager.

Other Editor Commands

Press "Ctrl+T" to display tile information at the cursor location. From the scroll, it is possible to edit the color information without editing the type. You can also edit the status element at the cursor location if a status element exists there.

Press "Ctrl+S" to enumerate all status elements in the board, in their stored order. You can select a status element for editing with "ENTER", delete it with "Delete", or move the ordering with the Left/Right Arrows. It is rarely important the order in which status element objects appear within the board, but it might be useful to ensure that some objects get their turns handled before others. Keep in mind that the PLAYER object, if one exists in the board, is always relocated to the first position as part of save.

Press "Ctrl+O" to reveal hidden objects, temporarily drawing them as character code 1. A status element is said to be "hidden" if it has identical foreground and background color, or if it has the character 0, 32, 255, 219, 176, 177, or 178. With this command, you can conveniently "unblend" objects that are designed to blend in with the rest of the board for the purpose of locating them.

Press "O" to load a ZZT Object Library (.ZZL text format). Object libraries are external storage files representing an OBJECT type with predefined members and custom code. These .ZZL files were used originally in ZZTAE and KevEdit editors.

ZZT Ultra copies every OBJECT type from a loaded .ZZL file into the first few board positions of the current board, whereupon they can be manipulated or copied at will. While this is a convenient way to load .ZZL content, ZZT Ultra has a better way of porting status element objects with custom code: the code editor and JSON status element interfaces allow for copying and pasting of text. It is far easier to transfer custom code using the clipboard than it is to maintain .ZZL files.

Character Editor Interface

Press "=" to invoke the character editor from the world editor. The character editor interface allows you to edit the Code Page 437 character set and create your own customizations of the font and symbols. Any of the 256 characters in the set can be modified.

Character cells are described by their "bit" patterns. In the upper left of the display, a large-scale copy of the currently selected character bit pattern is shown. You can edit this bit pattern with the mouse or the keyboard (arrow keys and space bar).

To select a character for editing, click on a character from the character set at the bottom of the page. The preview will show up in the lower left corner, and the large-scale copy will show up in the upper left corner. You can also evaluate how each character would look when juxtaposed with other characters by clicking on the squares surrounding the preview. This can be useful when constructing multi-character segueways.

One can perform many effects on the currently selected character. The "M" and "F" keys mirror the cell, the "N" key negates the cell, and the "F2" and "F3" keys copy and paste cells to different character slots. You can also hold "Ctrl+Arrow" to rotate the cell in the horizontal or vertical directions, with a wrapping effect.

Character Heights and Counts

Each character set has an overall count and an overall height. The height is toggled with the "H" key, and can be 8, 14, or 16. The editor keeps track of different character sets for each height, so changing the height will load an alternate character set. The character count is usually 256, but it can be set lower if one wants to save a partial character set.

While the character count and character height are being edited, the actual display of the editing interface itself does not change. If you want to change the display such that it reflects the current character set, press "A" to apply the changes. If you exit this interface to the main part of the world editor, you will see that all characters, in both the GUI and the viewport, have been updated.

Press "R" to reset the character set to the default for that height. This can be helpful if you had made too many breaking changes and wish to "start over."

Loading and Saving Character Sets

To load a character set, press "L". There are two sources for character sets: embedded within the file (mask or WAD lump), or an external binary file.

Masks and WAD lumps do not necessarily conform to a customized character set. If you load from this type of data source, you will need to manually enter the name.

Binary files are stored as bit fields, with each byte representing one scanline (one row of a character cell). The file extension .CHR is a common source for character data, although any binary file can be read.

It is important to consider that height and count information is not stored along with the character data--you must make sure that the height is set correctly to 8, 14, or 16 before loading the character set. Failure to do this will result in a mismatched set, which looks strange. Note that MZX character sets nearly always have a height of 14.

To save a character set, press "S". The data destinations include a mask within the world file, a WAD lump within the world file, or an external binary file.

When a character set is saved, the "mask" destination will save the character bit patterns as a series of 0s and 1s. When a WAD lump or a binary file is saved, on the other hand, the bit fields are stored with one-byte-per-scanline (i.e. in binary format).

The character count is used to determine how many characters in the set will be saved to the destination. A full character set is 256. If the number is less than this, the character set is partial, and is usually subject to a nonzero starting offset before being applied within the context of the ZZT game itself.

See the #CHARSELECT command for how to use a modified character set within ZZT-OOP.

Loading, Saving, and Transferring Worlds

ZZT Ultra can load and save world data, either world-at-once or board-at-once, to disk files. The preferred format is WAD because everything that is created within the world editor can be stored within the WAD file format. ZZT Ultra can also read and write legacy formats like ZZT and SZT.

Loading Worlds

Press "L" to display a scroll for loading a world file. You must choose the file format to load: WAD, ZZT, or SZT.

The WAD file format is the most straightforward, because the WAD lumps stored within the file contain every component that the editor needs, with the least conversion. See the Game World File Format for specifics on the file format.

When a WAD file is saved, world properties starting with DEP_ and global variables starting with $ are not saved. It does not make sense to save deployment configuration properties or engine variables in the world file, since they will be overridden upon load later on.

The ZZT (original ZZT) and SZT (Super ZZT) file formats are converted automatically to ZZT Ultra's component configuration upon load. ZZT Ultra allows the user to edit content within these files, but there are compatibility issues to consider when saving a world file back to the disk.

Saving Worlds

Press "S" to display a scroll for saving a world file. You must choose the file format for the save: WAD, ZZT, or SZT. By default, this choice is the originally loaded format. A brand-new world created in ZZT Ultra will always have WAD as the default.

The editor's preferred format is WAD, so there is no trouble saving a WAD file. In contrast, ZZT Ultra must conduct a series of compatibility checks to determine if the world can be saved in ZZT or SZT formats.

If ZZT Ultra is unable to save the world file, Save Errors are reported in the file browser, with no prompt for disk file location. If ZZT Ultra is able to save the world file, but there are various other messages of importance, then Save Messages are reported to the file browser, with the prompt for a disk file appearing next.

The following is a complete list of save errors, warnings, and messages:

  • ERROR: Number of flags would be nn; max is nn
    This is shown when the global variables, when converted to flags, exceed the maximum allowable size (10 for ZZT, 16 for SZT).

  • ERROR: (prop) is out of the range [0, 32767]
    This is shown when a world or board property is out of the valid range for the target format. The allowed numbers depend on both an operating range, intrinsic to the property itself, and a data range, defined by the number of bytes that compose the property.

  • ERROR: Board (name) has invalid dimensions.
    ZZT requires all boards to have dimensions 60x25, and SZT requires all boards to have dimensions 96x80.

  • ERROR: Status element count is nn; max is nn.
    ZZT sets the upper limit for status elements at 151, while SZT sets it at 129.

  • ERROR: Off-grid status element: x,y
    Even though a status element can be located anywhere in theory, including on the BOARDEDGE portion of a board, a status element can only be stored as intended if it is within the visible portion of the grid.

    It should be noted that some legacy world files store off-grid status elements within boards that do not have any bearing on the functionality of the world. ZZT Ultra considers these to be extraneous and discards them when they are loaded. As a long-term storage best practice, status elements should not be off the grid.

  • ERROR: Board (name) has no PLAYER.
    The ZZT and SZT formats require that the PLAYER occupy position zero within the status element list in each board. If there is no PLAYER, a board will malfunction.

    ZZT Ultra does not require that a PLAYER exist within each board in the WAD format. This is because a board in ZZT Ultra is much more "free" in what it can do.

    If there are multiple PLAYER instances in the board, ZZT Ultra uses the CPY member to determine which of the instances to set as position zero (CPY=0). If none of the instances set CPY=0, the first instance in the list is picked.

  • ERROR: Board (name) is >= 32 KB; too large.
    Any board larger than 32 KB definitely will not work in ZZT or SZT.

  • Warning: KEYnn should be in range [0, 1]
    Some quantities in ZZT Ultra, such as inventory properties, can be set to unusual values that might work within ZZT or SZT, but could develop problems. Any suspect range of a property that is not an obvious deal-breaker is reported as a warning.

  • Warning: (name) length is > nn chars; will be clipped.
    The ZZT and SZT formats use fixed-length "Pascal-style" strings to represent names. If a name in ZZT Ultra exceeds the maximum number of characters supported by the format, this warning pops up, indicating the name will be shortened.

  • Warning: HEALTH is <= 0; player will start 'dead.'
    While it is possible to start the game with no health, it is strange for a ZZT or SZT world to have this set intentionally.

  • SECRET flag detected; will be moved to position 0.
    A classic way that users could be "blocked" from editing a pre-packaged world file was to set the SECRET flag. If this is detected in ZZT Ultra, it is moved to the first slot automatically. Modern editors are not "blocked" in this fashion, but here it is anyway.

  • Warning: (name) flag is not 1; results may be undefined.
    The original world flags were boolean in nature. In ZZT Ultra, it is possible to set a global variable to a non-boolean value. If a flag has a value other than 0 or 1, it is saved as if it has the value of 1 (i.e. "set" status).

    As a side note, a global variable with a value of 0 is not saved as a flag in ZZT or SZT.

  • Warning: Type (name) is uncommon; risky to use.
    MESSENGER and MONITOR are momentary types found within ZZT and SZT file formats. It is not wise to place these types in a board.

  • Warning: Type (name) is undefined in ZZT/SZT format.
    Some types are only defined in ZZT or SZT. While they could be used in theory in the opposite format, the full rendering capability and functionality of the type is almost certainly absent in the opposite format.

    ZZT Ultra performs some "type juggling" when loading and saving legacy files. For example, stars, bullets, and blink wall beam numbers are modified as needed. This translation happens casually (no messages are shown).

  • Warning: Type (name) is undefined outside of ZZT Ultra.
    Custom type numbers in ZZT Ultra can be posted to ZZT or SZT world files, but these numbers will not mean anything.

  • Warning: Double status element at (x, y).
    The original editors had problems with "doubled up" status elements existing at a single square. It should be considered a best practice to avoid multiple status elements pointing to a single square.

    ZZT Ultra automatically purges duplicates when it loads a legacy world file. However, it might be desired (for some strange reason) to keep duplicates within the saved legacy world file if the duplicates were originally in the legacy world file.

  • A 'dead smiley' was saved in (name).
    It is possible to have a board contain "dead" PLAYER types which lack status elements.

  • Warning: Board (name) is > 20 KB; carries risks.
    Any board larger than 20 KB could work in ZZT or SZT, but there are memory allocation and maintenance issues that might develop.

Transferring Boards

Press "T" to transfer a single board to or from a WAD file. The export option pushes the current board to a WAD file. The import option pulls a previously exported board from a WAD file to the current world, appending it the end of the list.

The transfer of boards is designed to work in the context of ZZT Ultra only. There is no direct support for legacy .BRD formats.

Further Information

There is a big difference between telling a person how to use this editor and telling a person everything he or she needs to know about ZZT, world design, or file formats. The following links will help you to understand what else there is to know regarding ZZT.

Return to Editor TOC

Return to Table of Contents

This page is Copyright © 2016 Christopher Allen.