dMZX Forums: Wait 1 versus Cycle 1 - dMZX Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Wait 1 versus Cycle 1 Yatta!

#1 User is offline   Wervyn 

  • I can see you
  • Group: DigiStaff
  • Posts: 1,855
  • Joined: 24-December 00
  • Gender:Male
  • Location:Caras Galadhon

Posted 05 September 2008 - 02:28 PM

I've harped about the problem with wait 1 and subroutines for awhile now. Specifically, that sending a robot to a subroutine after it's done a wait 1 causes it to wait 1 again when it returns, because wait 1 is technically a multi-cycle command. This means that you can't reliably use inter-robot subroutines in an engine that involves busyloops, without causing some sort of slowdown. At least, not with wait 1.

As I was poring over Terryn's list of cycles and commands, looking for another cycle-ending command without side effects or multiple cycles, I suddenly spotted the perfect solution: the lonely, forgotten cycle command. Oft seen in ZZT to set the cycles per execution to 1, but never in MZX because cycles per execution is 1 by default, no one ever touched it because there are much better ways to slow down a robot than to tell it to execute only every nth cycle. But the command ends the cycle.

Here's my proposal: we change our nebulous, unwritten best-practices that say you should break up your busyloops with a wait 1 command, and instead start instructing people to do that with a cycle 1 command. It accomplishes exactly the desired effect, ending the cycle and letting other robots have a chance at execution, and it does it without mucking up subroutines. And it even has "cycle" in the name, to imply this different interpretation of its purpose. Thoughts?

"But how do we know when irrational exuberance has unduly escalated asset values."
To lie is to change the truth.
..Ignorance is to be unaware of the truth.
....Incompetence is to be unable to grasp the truth.
......And escape is to run away from the truth.
It is useless to run, since the truth is right next to you.

-Wervyn
0

#2 User is offline   hob nado 

  • Ancient Member
  • PipPipPipPipPipPip
  • Group: Members
  • Posts: 4,718
  • Joined: 23-September 00
  • Gender:Male

Posted 05 September 2008 - 08:14 PM

A retcon, I like it.

While we're at it, we'll make the PASQUALE and MULLIGAN commands evil.
0

#3 User is offline   Old-Sckool 

  • megazeux breaker
  • PipPipPipPip
  • Group: Members
  • Posts: 649
  • Joined: 07-June 05
  • Gender:Male

Posted 05 September 2008 - 09:20 PM

hmm, so would the proper way to do this be
:q
cycle 1
cycle "('integer-of-choice')"
goto q

and just plop that into the global?

This post has been edited by Old-Sckool: 05 September 2008 - 09:21 PM

<Nadir> mzxers don't make GAMES, usually
<phthalocyanine> they make experiences.
<Nadir> demos, more like
<Nadir> a glimpse into what could have been if mzx wasn't such a bore to work with
<Nadir> actually, i'm being unfair
<Nadir> i would have made mzx games if it was capable of running on more than 20 computers worldwide in 1998
<Nadir> >:D

<%Alice> functor
<%nooodl> i hear C++ has a thing called functors and they're completely different from Haskell functors...
<rorirover> the result is the most horrid thing in C++, it's basically black magic and it transforms any code you're writing into some eldritch monstrosity
0

#4 User is offline   Wervyn 

  • I can see you
  • Group: DigiStaff
  • Posts: 1,855
  • Joined: 24-December 00
  • Gender:Male
  • Location:Caras Galadhon

Posted 06 September 2008 - 06:01 AM

No, you entirely missed the idea. Nothing stuck in global, nothing extra placed anywhere, no need to correct the cycle wherever you use it. What I'm saying is instead of this:
: "loop"
. "This is a loop that does stuff."
inc "local" by 1
wait for 1
goto "loop"
: "#test"
* "~F&local&"
set "local" to 0
goto "#return"

Do this:
: "loop"
. "This is a loop that does stuff."
inc "local" by 1
cycle 1
goto "loop"
: "#test"
* "~F&local&"
set "local" to 0
goto "#return"

These will do exactly the same thing, except that if you have a robot that does THIS:
: "loop"
send "test" to "#test"
wait for 1
goto "loop"

Then the first robot will consistently print 1 for the second case, whereas it will print 0 for the first.

Of course I'm the only person who actually cares about this. No one else I know thinks MZX's ability to handle arbitrarily many subroutine calls at the same time is cool enough, or designs engines complicated enough, to worry about the timing issues wait 1 causes, or actually use this workaround. I just thought that if anyone ever did, it might be useful to have a record of it.

"I also build dollhouses out of chewing gum wrappers."
To lie is to change the truth.
..Ignorance is to be unaware of the truth.
....Incompetence is to be unable to grasp the truth.
......And escape is to run away from the truth.
It is useless to run, since the truth is right next to you.

-Wervyn
0

#5 User is offline   Old-Sckool 

  • megazeux breaker
  • PipPipPipPip
  • Group: Members
  • Posts: 649
  • Joined: 07-June 05
  • Gender:Male

Posted 06 September 2008 - 03:47 PM

lol, I guess I confused Cycle function with the commands counter.
so just Cycle 1 ftw
<Nadir> mzxers don't make GAMES, usually
<phthalocyanine> they make experiences.
<Nadir> demos, more like
<Nadir> a glimpse into what could have been if mzx wasn't such a bore to work with
<Nadir> actually, i'm being unfair
<Nadir> i would have made mzx games if it was capable of running on more than 20 computers worldwide in 1998
<Nadir> >:D

<%Alice> functor
<%nooodl> i hear C++ has a thing called functors and they're completely different from Haskell functors...
<rorirover> the result is the most horrid thing in C++, it's basically black magic and it transforms any code you're writing into some eldritch monstrosity
0

#6 User is offline   Pyro1588 

  • wojtek
  • PipPip
  • Group: Members
  • Posts: 145
  • Joined: 20-October 02
  • Gender:Male
  • Location:Minnesota

Posted 07 September 2008 - 07:21 PM

and this is primarily to avoid timing issues? do your recommend using it in simpler robots that don't need to worry about timing as much?
<Tox> bah. I may as well give in and shop australia. D:
<pyro1588> "welcome to australia, can i help you find what you're looking for?"
<Tox> pyro1588, I'm giving you the most reproachful of glares right now.
--------
Go show those nutty Koreans what us crazy Europeans are made of pirate.gif pirate.gif pirate.gif - Saike
<exophase> The old Commodore strategy of, "Go friggin' bankrupt!"
<wervyn> Go away! I'm writing the same engine I always do!
0

#7 User is offline   Wervyn 

  • I can see you
  • Group: DigiStaff
  • Posts: 1,855
  • Joined: 24-December 00
  • Gender:Male
  • Location:Caras Galadhon

Posted 07 September 2008 - 08:55 PM

I recommend using it in any robot that is going to be sent to a subroutine by another robot, and contains a continuous loop. If you're not using subroutines, this makes no difference at all. If you don't have a loop, it makes little difference since the final return point is probably going to be "end". One may ask why you should use subroutines at all and not just labels, since if you have an engine loop it probably has a single break point, either right before a goto or right after a label. The reason is because you can send a robot to a subroutine and be absolutely sure that subroutine will execute, whereas if you only send the robot to a label, there's a chance that the message might get stepped on if the robot gets sent to another label by something else. This is basically THE reason I think inter-robot subroutines are so cool.

"Brought to you by SPAMlite, part of this balanced breakfast."
To lie is to change the truth.
..Ignorance is to be unaware of the truth.
....Incompetence is to be unable to grasp the truth.
......And escape is to run away from the truth.
It is useless to run, since the truth is right next to you.

-Wervyn
0

#8 User is offline   Pyro1588 

  • wojtek
  • PipPip
  • Group: Members
  • Posts: 145
  • Joined: 20-October 02
  • Gender:Male
  • Location:Minnesota

Posted 08 September 2008 - 03:24 PM

on the subject of sending other robots, how exactly does mzx handle execution order? my understanding is that it normally starts at 0,0, executes "commands" number of commands (or until a break like "wait 1" or "cycle 1" is reached,) then moves on to 1,0 and so on. is this correct?

and if it is, what happens when a robot is sent?
<Tox> bah. I may as well give in and shop australia. D:
<pyro1588> "welcome to australia, can i help you find what you're looking for?"
<Tox> pyro1588, I'm giving you the most reproachful of glares right now.
--------
Go show those nutty Koreans what us crazy Europeans are made of pirate.gif pirate.gif pirate.gif - Saike
<exophase> The old Commodore strategy of, "Go friggin' bankrupt!"
<wervyn> Go away! I'm writing the same engine I always do!
0

#9 User is offline   Wervyn 

  • I can see you
  • Group: DigiStaff
  • Posts: 1,855
  • Joined: 24-December 00
  • Gender:Male
  • Location:Caras Galadhon

Posted 08 September 2008 - 03:56 PM

You're correct about the execution order. Additionally, the global robot executes first (and its position is -1,-1 for record keeping, though that doesn't really matter much).

When a robot is sent to a label by another robot, its program counter is changed to that label immediately, but it doesn't get to execute until it's its turn. So, if another robot sends it to another label before that turn comes around, the first label will be ignored, since the robot will never have executed it.

Subroutines work the same way, with one important difference: when the program counter is changed to a subroutine label, the previous location is saved on the robot's call stack, immediately at the time the subroutine is sent. This means that when you send multiple subroutines in a single cycle, even from the same robot, they will all be executed in the reverse order in which they were received (provided of course that you end all your subroutines correctly with goto "#return". The robot will have saved the label for each subroutine it received on the call stack, and will hit each of them in turn as it encounters the #return commands.

The big caveat with this: DON'T send robots both labels and subroutines. You can mess up the call stack this way. I THINK that built-in labels like :touch and :keyX are okay (have not tested this since I just thought of it now), since I think they are trapped and sent in between robot execution for the board, and thus will be at the base of the call stack before any sent labels are received. But I could be wrong about this, particularly when it comes to how :shot labels and bullets are processed. Use at your own risk.

"I'm too lazy to think of anything clever to put here."
To lie is to change the truth.
..Ignorance is to be unaware of the truth.
....Incompetence is to be unable to grasp the truth.
......And escape is to run away from the truth.
It is useless to run, since the truth is right next to you.

-Wervyn
0

#10 User is offline   Kom 

  • Senior Member
  • PipPipPipPip
  • Group: Members
  • Posts: 611
  • Joined: 05-March 07
  • Gender:Male

Posted 22 September 2008 - 05:04 AM

Another thing i noticed...

In this example, each robot was used separately with the control. I will explain what happened along with some of my thoughts with each test robot.

Control robot
set "commands" "(32767*16)"
: "d"
send "d" to "#d"
send "d" to "d2"
wait for 1
goto "d"


robot A
: "d"
inc "local" by 1
wait for 1
goto "d"
: "#D"
* "&local&"
goto "#return"

This robot would only display 1, meaning it went through the increment command only once. It would display a 0 if it was placed after the control robot. Now, this is because every time the robot would return from its subroutine, it would go back and execute the wait 1 command, which is a known problem (i think).

Robot B
: "d"
inc "local" by 1
cycle 1
goto "d"
: "#D"
* "&local&"
goto "#return"

within this example, the number displayed would constantly increase, showing that the cycle 1 command acts as a wait 1 in which the robot would not return and wait again, but continue on after the subroutine.

Robot C
: "d"
inc "local" by 1
wait for 1
goto "d"
: "D2"
* "&local&"
goto "d"

the number would increase in this, because the wait is at the end of the loop, making it, still iterate each cycle, because at the end of the label it was sent to, it would go back and continue on from the beginning of the loop.

Robot D
: "d"
inc "local" by 1
goto "d"
: "D2"
* "&local&"
wait for 1
goto "d"

This robot iterated for every cycle available, and thus continuously displayed a very high number, but due to being sent to a label every cycle, it could only iterate the original loop once, before it was essentially stuck within the second label.

This whole thing is very interesting, but i don't think it's terribly useful for me, i don't ever seem to send other robots to subroutines, or at least not every cycle. I suppose if whatever controls robotic was fixed, causing subroutines called externally to go to the next command, and not the one it got called on would probably make the cycle command completely useless at this point, since it would then be outdone by the wait command once again.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

3 User(s) are reading this topic
0 members, 3 guests, 0 anonymous users