Guide To ZZT Operation
by David Hammond (Nanobot)

There are many "bugs" in ZZT that lead people to wonder what exactly happens. In this document, I hope to uncover many of these and have them make sense. I will also talk about functions in ZZT that are known and proven, but you may just not know about them. Some of these are built-in functions that you use all the time and just don't realise it.

I'll start with the monitor. What is a monitor? Well, you may notice that when you're looking at the title screen of a game, the player isn't simply replaced by an empty. There's still something there; something invisible. That is the monitor. It allows the keyboard commands listed in the sidebar, such as Play and World. It's the "second" element meant to be used functionally. I call this the Controller Element.

Controller Elements are elements that react to keystrokes. The player and the monitor are two known Controller Elements. They each have their own set of keys that they react to. By default, the Controller Element that is "meant" to be on the board is listed first in the stat element parameter section of the .ZZT board data. I'll just refer to that as the "board data" when talking about elements that have parameters.

However, Controller Elements work normally no matter where they are in the board data, in terms of their internal functions. You may then ask, "What about player clones? They don't move when you press the directions." True. Internally, they don't cause themselves to move.

Here's what happens when you press a keystoke. Let's say there are 5 players on the board (1 active one (the first element in the board data) and 4 clones). You press up. Every player, in turn, reacts to the keystroke. The first player (the active one) checks to see if it is blocked to the North. It isn't, so it changes the y-coordinate for the first element in the board data (the player) to 1 less than its current y-coordinate and the x-coordinate equal to its current one. That will be updated at the beginning on the following cycle. The next player then does the same thing. It isn't blocked to the North, so it changes the FIRST player's y-coordinate to one less than the SECOND player's y-coordinate and its x-coordinate equal to its own (the second player's). Note that that would place the first player above the second. The third player does it as well, but say it is blocked to the North. It performs the normal function of trying to SEND whatever is to the North of it to TOUCH and doing nothing else. The fourth player operates and isn't blocked, so the coordinates of the first player are set above the fourth player. The fifth player is blocked, and tries to send whatever is above it to TOUCH. The next cycle begins and the first player appears directly to the North of the fourth player (third player clone). It is in the situation we have come to know as "stuck."

In a nutshell, the player always ends up to be the pressed direction of the LAST player in the board data who isn't blocked in that direction. If all player clones happen to be blocked in that direction and the first player (the active one) isn't, it moves in that direction normally.

When I said that each Controller Element in the board data functions normally, I didn't just mean in terms of keystrokes. There are many other functions that the player can perform. Many of them have been thought to be sort of "global" functions that are performed completely internally. For example, when you light a torch, did you know that it's actually the player that is causing it to waste away? It's quite true. You see, when you press "T", the player reacts by setting an internal counter to 200. This counter has a function not unlike that of the Time counter. Every cycle, the player reduces this counter by 1. When it reaches 0, it deactivates the torch. Energizers work pretty much in the same way, though it's the energizer element itself that actually sets the counter, and the counter is set to 64. Since it's a regular player function, placing player clones on the board cause this process to speed up, because 1 is subtracted from these counters by EACH player on the board at once. So if you could have 200 players on the board (which is impossible because of the 151 stat elements per board limit), the torch would run out the very cycle you lit it.

There's one more thing to note about the torch deterioration process. Like bombs, in the stage directly before it completely disappears, it "cleans up" what has been done. When there is 1 left to the Torch Active counter, it removes the visible area created by the torch. If the player doesn't have time to do this (other players decrease the counter too quickly), the visible spot will remain until made dark again by normal refreshing done by moving the player.

Here's a nice little piece of information: did you know RESTART isn't a command? Seriously, it isn't. It's actually the abbreviated version of "#SEND SELF:RESTART" or "#SEND RESTART". By default, every object has its first line marked as the equivilant of a label entitled "RESTART". However, since this isn't actually part of the object's code, you cannot zap (or restore) the label. What use is it to know this, then? Well, you can use the command "#SEND MARVIN:RESTART" to make the object Marvin go back to the beginning.

I'm sure mostly everyone who has been working with ZZT for a while had that moment when suddenly, for absolutely no reason, an object wouldn't place an element using the PUT command. That's when you realise that nothing can be #PUT in the bottom row. Unfortunately, I don't have any definite reason why. The best guess I can make is that when Tim made the bounds check function (to prevent #PUTing things into the sidebar or off the board in other directions), he got the last y-coordinate off by one. Sadly, there is no way to actually PUT an element in that last row. You'll just need to work around it.

Now, let's talk about explosions. What are they exactly? Is there an Explosion element you can place on the board? Unfortunately, no. Allow me to explain exactly how bombs work. When you touch a bomb, all it does is set its first parameter to 9. It then reduces its first parameter by 1 each cycle. When the parameter reaches 2, it replaces any empties within 56 pixels from the bomb element with randomly-colored breakables (regular breakables without stats or anything), sends all elements in that area to "BOMBED", and destroys any breakable stat elements in the area as well. Note that when the first player in the board data is destroyed, it places it back on the board, plays the "hurt" sound, takes away 10 health, and leaves the "Ouch!" message. So the player is, in fact, breakable. When the bomb's parameter reaches 1, it changes every breakable in the 56 pixel area (including breakables that were already there) into empties, and the bomb dies.

If you have any more questions regarding operations such as these in ZZT, feel free to e-mail me and I'll try to explain them. nanobot@mysticalwinds.zzn.com