WAIT 1 and CYCLE 1 each have their own sets of pros and cons, but it may take a little time to explain exactly what they are. If you don't care enough about MegaZeux's inner workings to read any further, this advice will probably be good enough for casual users:
Keep using WAIT 1.
That said, there are some useful things to be learned from this post that you might not already know.
WAIT 1 THEORY
In the olden ages, Gemini released a MegaZeux demonstration that was supposed to show the benefits of using WAIT 1 in Robotic code. It can be found here. Wait, 2 stars and bad ratings? I don't have to use WAIT 1, right? Nope, Gemini just didn't explain it particularly well, hence the bad reviews. WAIT 1 and CYCLE 1 will not make your Robotic code "faster". The reason why you need to use one of these commands is different, and needs a little more explanation.
THE CYCLE
A "cycle" is just MegaZeux's way of saying a "frame" or a division of run time in MegaZeux. Simply put (and incredibly oversimplified), during every cycle, everything on the board runs once or moves once per cycle. Take the default player or a built-in at its fastest speed: every time it moves is one cycle.
set "MZX_SPEED" 2
The MZX Speed affects how many of these "cycles" or "frames" are executed per second given this equation: 62.5 / (MZX_SPEED - 1) Speed 2 is twice as fast as speed 3 and three times as fast as Speed 4. Speed 1 is a special case -- it does not limit the number of frames executed per second, which can be a good thing in some cases but generally is undesirable. Running MZX at an unchecked framerate like this will have different results on different people's computers, for better or worse. MZX_SPEED defaults to 4. If you set MZX_SPEED to any value, it will disappear as an option from the F2 Menu unless you set MZX_SPEED to 0 after setting it to the desired value.
ROBOT EXECUTION
Every cycle, all of the robots and built-ins need to execute their code once. To fully understand how this works, you need to understand the way the board is executed.
- First, the built-in player is handled, including all inputs and effects like wind.
- The global robot is run; a cycle of the global robot's program is executed.
- Next, something called the board scan is performed. MegaZeux goes over every char of the board (left-to-right, top-to-bottom), updating all of the built-in types like goblins and pushers. Robots are also executed during this scan; a cycle of each robot's program is executed when encountered.
- The reverse send is handled (more on this later).
What constitutes a cycle of any particular robot's code? This is based on several factors.
CYCLE-ENDING COMMANDS
Several commands in MegaZeux will end a robot's cycle regardless of what code follows.
cycle 5
The cycle command alters how often the robot executes its code. Changing the robot's cycle value is similar to changing the speed of a built-in enemy -- if you change it to 2, the robot will only execute or move every other cycle. The cycle command itself ends a robot's cycle.
wait for 10 end
These commands allow a robot to receive sent labels with the Reverse Send, and I'll come back to these later. Some of these commands will take a certain number of cycles based on input values -- WAIT ends a number of cycles for that robot equal to the number given to it. END stops the robot from executing entirely.
go EAST 1 / "n" try NORTH else "noThanks" move all c?? customblock p?? NORTH move player to SOUTH gotoxy 0 0 put player at 20 81 . "and several others I couldn't be bothered to list"
These all end the robot's cycle, but they aren't particularly special. As a guideline, anything that results in directly moving the robot itself, the player, or anything on the board will end a cycle.
shoot NORTH shootmissile NORTH shootseeker NORTH spitfire NORTH
In MZX 2.83, these were cycle ending commands. This does not end the cycle in any other versions.
color fade in color fade out
According to some documentation somewhere these used to end the cycle at some point in MZX's history, but they don't anymore. They will go into effect mid-cycle, causing a delay in processing robots and potentially showing the board mid-update.
: "loop"
See Lancer's post below
THE COMMANDS COUNTER
Alright, so if a robot doesn't have one of the cases above not in red, won't it just run forever? Not necessarily! The commands limit is meant to prevent this from happening. In earlier versions of MegaZeux, this limit was 40 commands per cycle, but a counter was added so the user can control its value.
set "COMMANDS" 4000
This means that the robot will execute up to 4000 lines of code if it doesn't run into a cycle ending command. When it reaches the 4000th line of code, it will stop so the next robot can execute its program. This counter defaults to 40. If you notice a robot of yours executing "slow" or something its supposed to be displaying lagging or flickering, you might need to increase the COMMANDS counter. Note that to set it any higher than 32767, you need to wrap the number in an expression:
set "COMMANDS" "(100000)"
set "COMMANDS" "(-1>>1)"
This might seem odd, but what it actually does is sets COMMANDS to the highest possible integer value in MegaZeux, 2 147 483 648. This causes your robot to run forever unless stopped by a cycle-ending command, essentially disabling the COMMANDS limit. In MegaZeux versions before 2.9X, this was dangerous as it would freeze MegaZeux if a coder accidentally put an infinite loop in their Robotic, but in MegaZeux 2.90, features were added so that users can break out of these loops. Using very high COMMANDS values like this is now safe.
In worlds developed in pre-2.9X versions, however, you should set your COMMANDS counter at a reasonable limit (like 10 million) so people playing with older MZX versions can still use Escape to exit from testing.
WHY SHOULD I USE WAIT 1 AND CYCLE 1 THEN
One of the test cases in Wait 1 Theory actually did show a benefit of using wait 1, which I will replicate here. Take this example:
set "COMMANDS" 32767 : "l" copy block 0 0 10 10 10 0 goto "l"
This seems fine, right? I just want it to keep copying that block while the player is on the board... okay, now make 100 robots that copy this robot. MegaZeux is probably slow now, and if it isn't, it may be using up a decent portion of your computer's processing capabilities just to copy some block over and over again! If it still isn't, multiply commands by 100. Well, I don't need commands to be 32767 in this case, but maybe some other more complex engine on the board needs that many commands just to complete its code by the end of its cycle. This is where CYCLE 1 and WAIT 1 come in. Both of these commands will end a robot's cycle and usually nothing more, and are both ideal for ending the robot's cycle so it doesn't execute this copy block command 32767 times every cycle.
: "l" copy block 0 0 10 10 10 0 wait for 1 goto "l"
There, that's better! Now that it's only running this command once per robot per cycle, it's not so bad!
WAIT 1 vs CYCLE 1
WAIT 1
+ Allows labels to be sent by the Reverse Send
+ Can wait for multiple cycles if you give it a bigger number.
+ Does not repeat when returning from externally sent subroutines (MegaZeux 2.90+ only)
- When returning from a subroutine sent from another robot, due to an MZX bug WAIT 1 is executed again, which will cause the robot to become stuck on that WAIT 1 if it is receiving a new subroutine every cycle. This is due to the robot's stack not storing the internal line position and affects other commands like GO DIR # and / "string". This only affects MZX versions prior to 2.90; in 2.90 and later, subroutine calls will properly store the internal line position.
CYCLE 1
+ Does not allow labels to be sent by the Reverse Send
+ Does not repeat when returning from externally sent subroutines
- Can't wait for multiple cycles without changing the cycle value.
- Different numbers need to be used if the robot is operating at another CYCLE value; this is mostly unused nowadays, but still something to keep in mind.
THE REVERSE SEND
Alright, here's a little bit of quirky MZX-behaviour that may be taken for granted or not even known about to most people. After every robot is executed initially, all robots are checked again in reverse. If a robot 1) is already ended, is waiting with the WAIT command, is waiting for its cycle (see: the CYCLE command with a value greater than one), or the first command it encounters for a given cycle is WAIT or END; and 2) was sent a label by a robot later in the list, the robot's program will begin execution AGAIN during the same cycle! For example:
- Robot "Arf" is at 10,10. Robot "Barf" is at 80,80.
- "Arf" ENDs immediately on the first cycle it it runs. "Barf" waits.
- "Arf" is still ended. "Barf" sends "Arf" a label. "Barf" is further down on the board than "Arf" is, but "Arf" receives and executes the label on the very same cycle due to the reverse send.
Reverse send affects only the robots which ended their cycle in a way that allows the reverse send to occur. If "Arf" had ended the cycle with a CYCLE 1 when "Barf" sent the label, "Arf" would not have acted on it until the next cycle, because CYCLE 1 does not allow the reverse send to occur. Based on how your game works, the reverse send may be desirable behavior or it may actually break your engine.
CONCLUSION
So, from the pros/cons list, you probably noticed that WAIT 1 comes out ahead functionally for casual use, mostly for if you're using lots of robots on the body of the board that are sending labels back and forth. CYCLE 1 had some very important use cases when subroutines were in the mix before MegaZeux 2.90 -- multi-purpose robots that need to run every cycle, say, so animations don't skip, or something else that's very timing-intensive doesn't go unnoticed, but the robot still also needs to receive subroutines.
CYCLE 1 can also be used if you just want to avoid the reverse send altogether, which depending on your design, may be beneficial. If you have a robot using CYCLE 1, it will always wait on handling any label sent to it until the next cycle.
Due to the strict criteria for reverse send, it can not be used to get multiple executions per cycle out of a single robot.
Final note: the global robot is not eligible for receiving labels by reverse send, meaning WAIT 1 and CYCLE 1 are indistinguishable for it in MegaZeux 2.90 onward.
EDIT: updated terminology
EDIT: updated COMMANDS for 2.9X
EDIT: fixed reverse send info