If you add a "wait 0 seconds" block before a broadcast, and the code is running in parrallel with another chunk of code, the two broadcasts should still broadcast at the same time.
The broadcast in the chunk of code with the "wait 0 seconds" block is called second.
You can see a minimal example of this built in scratch here.
Just hit the play button and observe how Receiver1 and Receiver2's LocalNum variables differ.
Windows 10 (10.0.18356 Build 18356) Chrome 73 (73.0.3683.86)
This is intentional actually! The "wait 0 seconds" block is equivalent to "wait one frame", and this is made good use of in a good deal of projects - changing the block to not yield would certainly break compatibility with many projects (especially since this is the same behavior as in Scratch 2.0).
Edit - Just to share some input on why this can be useful, well, it helps to resolve parallelism like in your project. Without the "wait 0 seconds" block, the result of this script is nondeterministic. (Actually, it will always result in the same value, but that depends on the internal way that Scratch orders scripts to be executed, which is not visible to the creator of the project. Try removing the "wait 0 second" from the Sender sprite. Note that when you run the project, the final GlobalNum is 2. Then right-click → duplicate the "set GlobalNum to 1" script, and remove the original "set GlobalNum to 1" script. If you run the script again, the final GlobalNum value will be 1. Scratch executed the older script first -- but of course, in the Scratch GUI, there is no way of telling which script is newer besides by demonstrating in a project like this!)
(BTW, it is worth noting that the LocalNum of both receiver sprites becomes the same value. That's because when you "broadcast" the name of a when-I-receive script, really you're just setting a flag that tells Scratch to execute this script later - you are not running it now. And as it would turn out, Scratch will execute all the scripts in a single sprite before moving on to another sprite. This means that the other "when I receive ParallelizeCalls" script inside the Sender sprite will have run before Scratch executes the scripts in Receiver1 and Receiver2 - and so those scripts will both see the same value for GlobalVar.)
In practice, it's better to avoid parallelism problems at all when possible. Consciously keeping track of all the implementation behavior above is very difficult, and debugging the related sort of problems in your program can cause headaches. Use sequential "broadcast and wait" scripts so that scripts which must happen in a certain order do so; and attach scripts which don't depend on other scripts to a single shared broadcast. Or make use of lists and variables to keep track of data, and reflect that data on the next frame, etc.. There are a host of different ways to approach this sort of trouble, but generally it's best avoid situations that depend on a certain type of parallelism, because - as hypothetically consistent as it may be, it just isn't worth it to depend on it working exactly as you'd hope.
Yeah DON'T CHANGE THAT ;) grin
On Wed, 27 Mar 2019 at 00:39, Florrie notifications@github.com wrote:
This is intentional actually! The "wait 0 seconds" block is equivalent to
"wait one frame", and this is made good use of in a good deal of projects -
changing the block to not yield would certainly break compatibility with
many projects (especially since this is the same behavior as in Scratch
2.0).—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/LLK/scratch-vm/issues/2072#issuecomment-476912777,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AGbNvprjL4M4cioyxMiUYE35bVyH-JfPks5var3OgaJpZM4cMi8T
.
This is intentional actually! The "wait 0 seconds" block is equivalent to "wait one frame", and this is made good use of in a good deal of projects
Awesome! When I reported this I was actually secretly thinking "I kind of hope they don't change this because this would be super useful!" So I'm glad to hear it's intentional hehe.
(BTW, it is worth noting that the LocalNum of both receiver sprites becomes the same value. That's because when you "broadcast" the name of a when-I-receive script, really you're just setting a flag that tells Scratch to execute this script later - you are not running it _now_. And as it would turn out, Scratch will execute all the scripts in a single sprite before moving on to another sprite. This means that the _other_ "when I receive ParallelizeCalls" script inside the Sender sprite will have run before Scratch executes the scripts in Receiver1 and Receiver2 - and so those scripts will both see the same value for GlobalVar.)
Thanks for writing up such a detailed post! That makes a whole lot more sense than whatever internal schema I had before. Thinking of the broadcasts like a flag rather than a function call or a queue makes a lot of things make more sense, like why when you have two broadcasts trigger at the same time you only get one receive instead of two.
I'll definitely keep all of this in mind as I proceed (and probably take a different approach as you suggested).
Thank you again!
Beka
Yes, as above, this is normal and expected behaviour for Scratch 3 (and was same with Scratch 2).
For an overview of the Scratch 2 execution engine, you might find these posts helpful:
https://scratch.mit.edu/discuss/post/2437600/
https://scratch.mit.edu/discuss/post/2413813/
https://scratch.mit.edu/discuss/post/2223919/
https://scratch.mit.edu/discuss/post/2515915/
Scratch 3 is written to run scripts in (pretty much) the same way as Scratch 2, so its behaviour is essentially the same as Scratch 2. (One difference – a good one, IMO – is that, in the script editor pane, changing the layer order of scripts with the same event hat block no longer potentially changes the execution order for those scripts; the creation order now determines the script execution order. [Of course, you can still swap the script execution order of two such scripts by swapping all the blocks from under the hat blocks, and if you remove the wait block from your project, you can easily test that for yourself...])
Most helpful comment
Yes, as above, this is normal and expected behaviour for Scratch 3 (and was same with Scratch 2).
For an overview of the Scratch 2 execution engine, you might find these posts helpful:
https://scratch.mit.edu/discuss/post/2437600/
https://scratch.mit.edu/discuss/post/2413813/
https://scratch.mit.edu/discuss/post/2223919/
https://scratch.mit.edu/discuss/post/2515915/
Scratch 3 is written to run scripts in (pretty much) the same way as Scratch 2, so its behaviour is essentially the same as Scratch 2. (One difference – a good one, IMO – is that, in the script editor pane, changing the layer order of scripts with the same event hat block no longer potentially changes the execution order for those scripts; the creation order now determines the script execution order. [Of course, you can still swap the script execution order of two such scripts by swapping all the blocks from under the hat blocks, and if you remove the wait block from your project, you can easily test that for yourself...])