When green flag clicked different behavior

Try my solution; I think it should work better.

I tested it with the large project and it seems to work even without adding the WAIT block to all green flag hats. Can you explain which is the difference with using the same script but without the "second time?" variable?

So, the goal of the script is, when the green flag is clicked, to stop all the other scripts and then broadcast another green flag to start the other scripts of the project. But that broadcast will trigger this script, too; it's a "when green flag clicked" script. On that second invocation, we don't want it to stop and start everyone again. So it has to remember that this is the second time, and it shouldn't do all that. (The reason it clears the flag is that later on the user might actually click the green flag again, and then we should stop and start the other scripts.)

Brian's solution works with my very large project without having to change the projects scripts. I guess it could be the right solution embedding the code inside a custom block with a meaningful name

yeah, that's a good idea.

Griffpatch uses the broadcast [green flag]

I do taht too

I missed answering this part. Broadcasting the green flag (or __shout__go__) is exactly equivalent to pushing the button; it runs when (flag) clicked scripts.

Alright, I've adapted Brian's solution a bit:


simulate Scratch stop

It's pretty good, but I'm still not completely sold on it because green flag scripts need the WAIT 0 SECS to work consistently. Otherwise, the scripts execute in the order you dropped them, which can lead to undesirable behavior. It's really not intuitive, so I'd prefer if users don't have to add that block when they want a new green flag script.

Ok, I have a suggestion. Currently, event hat execution order looks like this:

  • Execute the scripts of the first sprite in stage.children (i.e. the sprite on the back layer)
  • ...
  • Execute the scripts of the last sprite in stage.children (i.e. the sprite on the front layer)
  • Execute the scripts of the stage

To execute an individual sprite/stage's scripts:

  • Execute the first script in this.scripts.children (i.e the first script which was dropped in the pane)
  • ...
  • Execute the last script in this.scripts.children (i.e the last script which was dropped in the pane)

I think it would make more sense for scripts to execute in the visual order they and their owners appear in the scripts pane and sprite corral.

So execute the scripts of the stage, then sprite 1, sprite 2, etc. If there are clones, then maybe execute the scripts of the original first, and then the clones in the order in which they were created.

Then for each sprite/stage, execute the scripts in order of their y positions, and in order of their x positions for scripts with the same y.

Callout to @jens because this old topic has newly turned in to an actual actionable request about the Snap! editor itself. But this would be a very, very low priority, since the problem it's trying to solve is so weird in the first place. Much better imho would be that if someone wants two levels of green flagness they should just create another message that the first-level script can send to the second-level scripts, instead of them using when green flag clicked.

Indeed. But the first level is required to be a green flag event by Snap!, and the second-level is required to be a green flag event by my own stubbornness with not unnecessarily changing scripts. :slight_smile:

When you start thinking about the order in which scripts are executed in a single tick that's a sure-tell indicator that your design is way off. There are ways to reliably manage control flow and that's not one of them.

Yeah I said that too. But now that we've both said it, it's official! :~P

Ok yeah, probably shouldn't encourage this by making the execution order something predictable. So that throws the original solutions to green flag behavior out.

I definitely want to keep Snapinator's current behavior as its default—converting Scratch scripts to something syntactically equivalent, unless there are missing features or significant implementation differences in the blocks themselves. Since this is mainly a difference in the behavior of the green flag and stop sign, this doesn't fall in that category, and I don't want to uglify scripts to deal with it.

If there's a demand for it, I could definitely add an option for emulating the minutiae of Scratch, but it's not going to be pretty.

I will, however, emulate Scratch's stop behavior by default. That can be added elegantly without screwing up existing scripts, and quite a few projects do seem to depend on it.

Once I implement that, just click the stop sign before clicking the green flag again. :slight_smile:

Yes, exactly. This is an important part of my lessons to my students. And this is the source too of the infamous "Click green flag twice to avoid glitches" warning in an increasingly large number of Scratch projects :slight_smile:

It seems to be quite a difficult lesson. Scratch already provides the tools you need to synchronize multiple threads, but hardly any Scratchers seem to use them.

Even among adults, during most of my life, operating systems were just expected to crash every so often (including ones like MacOS Classic and Windows) for mysterious reasons that were mostly due to sloppiness about critical sections. (Although the early versions of Unix had a different synchronization-related problem, namely adding a disk block to a file before removing it from the free list. That was imho amazingly stupid.)

Yes, this is a part that I developed and improved in 10 years. I couldn't accept that people, after learning Scratch, could not be sure that what they were building could or could not work as expected for "unknown" reasons. So my students are learning that if you need that something happens before something else is run, they must impose a sequence (strong, by using a single script, or less strong, by syncronizing scripts by means of messages or variables).