ZZT-OOP Programming Language

Reference Manual

Program format

Program Format

Besides direct commands, ZZT-OOP programs contain other statements that serve varying purposes. Each type of statement has an associated symbol:
 $  @  #  /  ?  :  '  !  !-
Their meanings:
When this is on the first line of an object, it identifies the object by name. If an object is not given a name, there is no way to direct messages to it except when using ALL and OTHERS.
Identifies a programming language command.
Causes the object to move one space in the given direction. If it is blocked, it will wait until it is free.
Tells an object to try to move in a given direction. If its movement is blocked, the command will be ignored.
Identifies the part of the program that handles a specified message. Whenever the program receives the message, it will execute statements following the label. In ZZT.DAT text format, labels can also be followed by a ;, like so:
The text appears white, and hyperlinks move right to the line of text, retaining any text before it. Unfortunately, this command does not work in ZZT-OOP. However, most .HLP files implement it.
Comments have no effect, but serve to remind you (the programmer) what you were doing when you wrote the program. They also serve as "pre-zapped" labels which can be #restored.
When program execution comes to a line of text, the text will be displayed on the screen. If only a one-line message is given, it will be flashed on the bottom of the screen as a message. For multiple lines, a "scroll" will be opened up on screen and the text will appear. The contents of any window can be printed using Alt-P.
This makes text white and centers it. It can be used for titles, dialogue, or just about anything! Note: this command does not work in a one-line message. It simply shows the $.
A hypertext-like button. When this statement is included among text descriptions, it appears to the player as a button... Then, as the user views the text, he may position the cursor on the button and press enter, causing the supplied message to be sent.
This creates a hyperlink, just like !, but this one opens up a ZZT window and displays the contents of the given file, as well as displaying instructions above. If no extension is specified, HLP is used.


An object can send and receive (exchange) messages with itself, other objects, and the game itself.

Messages caused by the game itself:

When player touches Program
Program is hit by bullet
Bomb explodes near program
Program WALKs into wall
Player touches an ENERGIZER


Compass directions
No direction, stationary.
The direction toward the player, or the direction away from the player, if you are energized.
The direction in which the object is currently walking.
Either North or South, at random.
Either North or East, at random.
CW <direction>
Clockwise from the given direction, i.e. CW NORTH = EAST
CCW <direction>
Counter-clockwise from the given direction. CW NORTH = WEST
RNDP <direction>
A random direction perpendicular to the given direction. For example, RNDP NORTH = either EAST or WEST
OPP <direction>
Opposite the given direction. i.e., OPP NORTH = SOUTH

Here are some example commands to demonstrate the use of directions:

#GO CW RNDNS 'Go either east or west.
#GO OPP SEEK 'Go away from the player.
#WALK CW FLOW 'Turn clockwise from the direction we're walking in.

Flag manipulation:

Objects can manipulate simple variables called flags. A flag assumes one of two possible states: SET and CLEAR. Objects can alter flags, then take action accordingly.

Flags are not associated with individual objects or boards. A flag set by one object can be accessed by all other objects on all boards.

Three commands are useful here:

#SET <flag variable>
#CLEAR <flag variable>
Set and clear flag variables.
#IF [NOT] <flag> [THEN] <msg>
Tests the condition of a flag. If the flag is SET, the message is sent. Otherwise, the instruction is ignored.

If NOT is included, the message is sent if the flag is NOT SET. Otherwise, the instruction is ignored.

In addition to userdeclared flags, several "internal" flags can be accessed by any object:

This flag is SET whenever the object is aligned with the player either horizontally or vertically.
This flag is SET whenever the object is adjacent to (touching) the player.
BLOCKED <direction>
This flag is SET when the object is not free to move in the given direction, and CLEAR when the object is free to move in the direction.
This flag is SET whenever the player has touched an energizer and can not be harmed by creatures and bullets.
ANY <color> <item>
This flag is SET if there are objects of the given type on the screen.

Programming commands:

All ZZT-OOP commands are preceeded by the pound sign (#). The following commands are supported:

Descriptions of commands:

#SEND <message>
Similar to basic's "GOTO" command. #SEND followed by the name of a label within the program will cause program execution to continue at that label.
...program loop goes here...
#SEND <objectname>:<message>
Causes the execution of a different program to continue at a specified label within that program. By using this command, several creatures can be coordinated. For example, the player touches Creature A. Creature A tells Creature B to attack the player.
#SEND CreatureB:AttackPlayer
Note: If the program receiving the message is in the locked state, the command will be ignored. See the #LOCK command for more information.

Note: If there are two or more programs with the given name, the message will be sent to all of them.

#SEND ALL:<message>
Sends a given message to ALL of the objects on the board.
#SEND OTHERS:<message>
Sends a given message to all objects on the board except the object itself. In all #SEND commands, the SEND may be omitted, but messages with the same name as a command can't be sent in this way.
Causes program operation to halt. The object will just sit idly by until stimulated by a message.
Causes the program to go back to the top and start over.
#GO <direction>
Causes an object to move in a specified direction. The object will push boulders forward if they are in the way. If the object can not move in the given direction, it will stand by until either it can move, or it is stimulated by a message. In other words, it is equivalent to /.

Valid directions

#TRY <direction> [<msg>]
Causes the object to move in the given direction if it is not blocked. Otherwise, the given message will be sent.
#WALK <direction>
Sets the object moving in the given direction. The object will continue moving and executing commands. To cause a program to cease walking, issue the "Walk idle" command:
When an object WALKs into a wall, it automatically receives a THUD message. Unfortunately, it will keep going back to the same label over and over until #ZAP THUD is used.
Directs the creature to do absolutely nothing until it is updated next. Same as the /I command.
This command takes away all of the player's health, terminating the game. If the player has a high score, it will be recorded. Interestingly, if you immediately follow #endgame with #give health (n), the game will not be terminated, and the player's health will be set to n. Program execution continues past #endgame. In fact, only 3 commands halt program execution. #END, #DIE, and #BECOME.
The object will instantly vanish when this command is issued. Program execution halts, and the object is erased from the screen. The game will continue on without it. It is equivalent to #become empty.
#SHOOT <direction>
Attempts to fire a bullet in the given direction.
#SHOOT SEEK 'fires a bullet toward the player
#THROWSTAR <direction>
Causes the object to throw a star in the given direction. The star will try to collide with the player. It is not recommended that you use stars in excess, as they are virtually impossible to avoid.

Throwstar WOULD be equivalent to #put <direction> star, but #put will destroy any fakes or water in its way.

#ZAP <message>
Disables the first occurance of a label by turning it into a comment. For example, #ZAP TOUCH would turn the label :TOUCH into the comment 'TOUCH. Allows a program to have several routines with the same labels, so that the desired label is called at the appropriate time. Remember that the #SEND command always calls the first occurence of a label. For example:
:TOUCH 'will be called first time creature is touched
"You touched me for the first time"
:TOUCH 'will be called all subsequent times
"You touched me again."
#ZAP <objectname>:<message>
Zaps another object's label.
#RESTORE message
Changes a ZAPped label back into a normal label. Then, on subsequent calls to the label, the original one will be called instead of a secondary one.
#RESTORE <objectname>:<message>
Restores another object's label.

Note: <objectname> can be replaced with ALL or OTHERS to #zap or #restore labels of all objects or all other objects, respectively.

Puts a program into the "locked" state, so it will not be affected by any incomming messages. Often, conflicts occur when two messages are sent to a program in a short amount of time. The second message interrupts the program before it can finish handling the first one. However, if a program LOCKs itself when dealing with messages, it can not be disturbed.
Removes a program from the "locked" state, so it is free to receive incomming messages. Any messages that happened to arrive while it was LOCKed are lost.

'code to handle "touch" message goes here...
#GIVE <item> <quantity>
Gives a certain quantity of an item to the player. Good for giving bonus points, selling ammo, awarding extra health, etc.
#GIVE AMMO 10 ' gives the player 10 extra shots
Note: All items are integers with a range between 0 and 32767. The torch display can only display the left 3 digits, so it will appear as 327, but is actually 32767.
#TAKE <item> <qty> [<message>]
Attempts to take a certain quantity of an item from the player. If the player does not have the given amount, none will be taken, and if a message is given, it will be sent.
#TAKE GEMS 2 TooPoor
"Thank you for the gems!"
"You don't have enough gems!"

TIME can also be used in #give and #take statements, as long as the time limit is turned on in the information menu. However, #give takes the time closer to 0, even cycling back to the limit and harming the player, and #take will give the player more time. If #take would give the player more time than the time limit, it does not work and the message in #take is sent.

#PLAY <music>
Plays a musical score in the background as the game continues.
Music format
    _-> [Optional parameters]  [Notes] --_
   /                                      \
32nd note follows
Triplets: cut previous duration into thirds. For example, "Q3ABC" would play the notes A, B, and C, with all three taking up the time of a quarter note.
Adds time-and-a-half. For example, "H." would turn a half-note into a half-note tied to a quarter note.
Up octave
Down octave
Notes & rests
Piano notes, can be followed by:
Rythmic sound effects
(no effect, denotes triplet)
Hi snare
High woodblock
Low snare
Low tom
Low woodblock
Bass drum
Other notations
Open and close brackets let you separate music code into parts. They are much like comments.
#CHANGE <kind> <kind>
Changes every specified item on the board into another item. <kind> is the name of an item, creature, or terrain as listed in the editor (by pressing F1, F2, F3, F4 or F5), but with all punctuation and spaces removed. LINE, BULLET, EMPTY and STAR are also valid values for <kind>.
'Turns all lions on the board into gems.
'Changes all keys into east-west sliders.
'Changes all red keys into clockwise conveyors.
Names of Objects
#PUT <direction> <kind>
This causes a specified item to be placed adjacent to the object issuing the command.
'Places a blue key north of us.
'Puts a tiger in the direction of the player.
Names of Objects
#BECOME <kind>
Causes the object to suddenly change form into a specified item or creature. The object's program then ceases to exist.

Names of Objects

#CHAR <number>
Causes the object to change form, so that it is represented on the screen as a different character. <Number> can range from 0 to 255, and should be the ASCII code of the new character.

ASCII Character Codes

#CYCLE <number>
Sets the speed at which an object is updated. This can range from 1 (fastest) to 255 (ridiculusly slow). When no CYCLE speed is specified, it defaults to 3.
#BIND <objectname>
When a Program executes this instruction, its code will be replaced by the code of another object, and it will start executing instructions from the beginning.

This is a useful and space-saving technique. Rather than creating ten objects with the same program (which would be stored in memory ten times), create one object with the program, and nine others that contain only a BIND statement.