This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#1 2013-01-06 16:47:32

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Detecting fast repeated messages

I have multiple sprites sending the same message (e.g. "score") to a single sprite. I would like to be able to detect all sent messages but, apparently, it happens that if two sprites send the "score" message one too close to the other, the second "score" message restarts the script that starts with the "when I receive score" block, without the script being really able to do anything. So several "score" messages, if they are too closely followed by other "score" messages, are lost.

Is there a way, that hopefully doesn't involve the usage of variables, that will allow me to run at least the very first block of the script starting with the "when I receive score" block, even if other "score" message are almost immediately resent by other sprites?

Offline

 

#2 2013-01-06 16:53:37

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: Detecting fast repeated messages

It should work if you have no repeat blocks in your script...


http://block.site90.net/scratch.mit/text.php?size=30&text=%20A%20signature!&color=333333

Offline

 

#3 2013-01-06 17:11:30

technoguyx
Scratcher
Registered: 2008-10-18
Posts: 1000+

Re: Detecting fast repeated messages

Not that I know of.

You could make your life a bit easier and just use a variable, or a list as a "stack" of all the broadcasts sent. (a list would let you pass arguments for the sprite to manipulate.)

Receiver sprite:

when gf clicked
forever
    wait until <(length of [queue v]) > [0]> //proceed only if data is available
    say (join [deleted: ](item [last] of [queue v])) //do something with data
    delete (length of [queue v]) of [queue v] //eliminate the data we just used
end
Sender sprite:
when gf clicked
forever
    ask [type something nob] and wait
    add (answer) to [queue v]
end


http://getgnulinux.org/links/en/linuxliberated_4_78x116.png

Offline

 

#4 2013-01-06 17:11:51

tcb
Scratcher
Registered: 2008-03-25
Posts: 100+

Re: Detecting fast repeated messages

If you put a counter variable at the beginning of your code, and reset it to zero at the end, then you will know that multiple messages have been recieved.

[scratcblocks]
When message recieved clicked
change [counter v] by (1)
say [Do Code] for (2) secs
set [counter v] to (0)
[/scratchblocks]

EDIT: I tried, I failed. I hope the point gets accross though.

Last edited by tcb (2013-01-06 17:13:45)


http://goo.gl/eCQLihttp://goo.gl/sK54shttp://goo.gl/jC0dehttp://goo.gl/yhGLQhttp://goo.gl/wqvsQ

Offline

 

#5 2013-01-06 17:18:40

blob8108
Scratcher
Registered: 2007-06-25
Posts: 1000+

Re: Detecting fast repeated messages

Is this better in "Help with Scripts"?

One workaround I've used, when I also want to pass some information to the other script, is to use a list as a sort of queue. One script receives the broadcast and adds the value of a variable to the end of the list. A forever loop removes the first item from the list and does whatever you need to do with it.

Edit: I see I was too slow  tongue  I imagine you get the idea.

Last edited by blob8108 (2013-01-06 17:20:07)


Things I've made: kurt | scratchblocks2 | this cake

Offline

 

#6 2013-01-07 05:02:38

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

Thanks to everyone. Using variables and lists is exactly what I was proposing in my "tutorial" projects http://scratch.mit.edu/projects/s_federici/1383298 and http://scratch.mit.edu/projects/s_federici/1383090. But I was wandering if there was also a non-variable-based solution.

As for what mathwizz says, my script has no repeat blocks. But it gets immediately interrupted, without any block being run in the receiving script. As I knew that IF blocks are not interrupted, I also tried to use a dummy IF as the very first block and I put the whole receiving script inside it. But this too didn't work.

Any further suggestion is welcome  smile

Offline

 

#7 2013-01-07 07:06:07

blob8108
Scratcher
Registered: 2007-06-25
Posts: 1000+

Re: Detecting fast repeated messages

Can we see the offending script?


Things I've made: kurt | scratchblocks2 | this cake

Offline

 

#8 2013-01-07 11:20:01

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

blob8108 wrote:

Can we see the offending script?

Sure. You can have a look at http://scratch.mit.edu/projects/s_federici/3024202. If you click on two or more cows that are very close to each other, often you don't get all the points you should (1 point per cow). The "offending" script is the one starting with <when I receive "guadagni un punto"> in the n1 sprite.

The "guadagni un punto" message is sent by the cows sprites called "mucca".

Last edited by s_federici (2013-01-07 11:20:44)

Offline

 

#9 2013-01-07 15:13:03

blob8108
Scratcher
Registered: 2007-06-25
Posts: 1000+

Re: Detecting fast repeated messages

s_federici wrote:

blob8108 wrote:

Can we see the offending script?

Sure. You can have a look at http://scratch.mit.edu/projects/s_federici/3024202. If you click on two or more cows that are very close to each other, often you don't get all the points you should (1 point per cow). The "offending" script is the one starting with <when I receive "guadagni un punto"> in the n1 sprite.

The "guadagni un punto" message is sent by the cows sprites called "mucca".

That's... very interesting. I cannot see why that is.  hmm


Things I've made: kurt | scratchblocks2 | this cake

Offline

 

#10 2013-01-08 08:34:09

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

blob8108 wrote:

s_federici wrote:

blob8108 wrote:

Can we see the offending script?

Sure. You can have a look at http://scratch.mit.edu/projects/s_federici/3024202

That's... very interesting. I cannot see why that is.  hmm

Really? No clue? Someone is willing to... try harder?  smile

Offline

 

#11 2013-01-08 11:36:42

LS97
Scratcher
Registered: 2009-06-14
Posts: 1000+

Re: Detecting fast repeated messages

Any script that is topped by an event hat block (including the green flag and the broadcasts) will restart automatically instead of starting a new instance. It's somewhere in some documentation in some place that I read some time ago.

So the only solution is to use a counter variable to tell you how many times you still have to do something, and they should be a fail-safe method.

Offline

 

#12 2013-01-09 06:07:58

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

LS97 wrote:

It's somewhere in some documentation

Yes, Scratch is a "reentrant" programming language (scripts can be restarted even before they are completed). I would have just preferred that script invocation could be traced without having to use variables. Maybe just allowing the very first block of the script to be always run (otherwise, the script is not interrupted, it is never started...).

Offline

 

#13 2013-01-10 03:27:44

blob8108
Scratcher
Registered: 2007-06-25
Posts: 1000+

Re: Detecting fast repeated messages

As I understood it, though, Scratch should finish the script topped with the broadcast before switching back to another script that might call the broadcast again.  hmm


Things I've made: kurt | scratchblocks2 | this cake

Offline

 

#14 2013-01-10 06:57:26

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

blob8108 wrote:

As I understood it, though, Scratch should finish the script topped with the broadcast before switching back to another script that might call the broadcast again.  hmm

No. As I said, Scratch is a reentrant programming language, so it starts again all scripts that have a hat as their very first block, as soon as the hat condition is true again.

Indeed, in my tutorial projects linked above, the problem is really how to make a script run until it is finished before starting it again (by "stacking" events that are intercepted by the hat). But in order to do it, I had to use blocks from the Variable category. I was wandering now if this can be done even without Variables.

Offline

 

#15 2013-01-10 08:46:54

blob8108
Scratcher
Registered: 2007-06-25
Posts: 1000+

Re: Detecting fast repeated messages

s_federici wrote:

blob8108 wrote:

As I understood it, though, Scratch should finish the script topped with the broadcast before switching back to another script that might call the broadcast again.  hmm

No. As I said, Scratch is a reentrant programming language, so it starts again all scripts that have a hat as their very first block, as soon as the hat condition is true again.

Indeed, in my tutorial projects linked above, the problem is really how to make a script run until it is finished before starting it again (by "stacking" events that are intercepted by the hat). But in order to do it, I had to use blocks from the Variable category. I was wandering now if this can be done even without Variables.

Indeed. But doesn't Scratch only execute one script at a time? While the script with the broadcast is running, I don't see how it can get called again unless Scratch switches back to executing one of the other scripts that contain the broadcast.

Then again, maybe I'm assuming that the execution order isn't completely arbitrary?  hmm


Things I've made: kurt | scratchblocks2 | this cake

Offline

 

#16 2013-01-10 10:58:20

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

blob8108 wrote:

doesn't Scratch only execute one script at a time

Again, no. Scratch is a parallel (or "concurrent") programming language. Indeed scripts from different sprites (but even from the same sprite) are run at the same time (almost). This is done by running a block at a time from each active script. Even this is not really exact: long running blocks (e.g. "glide" or "wait") are often interrupted by running other blocks from other scripts.

Anyway, there are some non interruptable sequences. For example, as far as I know, the blocks contained inside an "IF" block are run without interruption, so to avoid that other scripts will change the truth of the condition (that could make inconsistent the sequence contained inside the "IF" block).

Offline

 

#17 2013-01-10 13:29:57

Digimath
Scratcher
Registered: 2007-07-07
Posts: 100+

Re: Detecting fast repeated messages

s_federici wrote:

...
Is there a way, that hopefully doesn't involve the usage of variables, that will allow me to run at least the very first block of the script starting with the "when I receive score" block, even if other "score" message are almost immediately resent by other sprites?

If you could protect the thread what then happens to the second message?  Would it just get dropped?


I've updated my text adventure game.
Colossal Cave 150http://scratch.mit.edu/static/projects/Digimath/3003787_sm.png

Offline

 

#18 2013-01-10 14:53:12

blob8108
Scratcher
Registered: 2007-06-25
Posts: 1000+

Re: Detecting fast repeated messages

s_federici wrote:

blob8108 wrote:

doesn't Scratch only execute one script at a time

Again, no. Scratch is a parallel (or "concurrent") programming language. Indeed scripts from different sprites (but even from the same sprite) are run at the same time (almost). This is done by running a block at a time from each active script. Even this is not really exact: long running blocks (e.g. "glide" or "wait") are often interrupted by running other blocks from other scripts.

Anyway, there are some non interruptable sequences. For example, as far as I know, the blocks contained inside an "IF" block are run without interruption, so to avoid that other scripts will change the truth of the condition (that could make inconsistent the sequence contained inside the "IF" block).

Aha! How interesting, thanks  smile  I hadn't realised this...

So after half an hour of editing your script down, I appreciate the problem now!

This seems to be enough to replicate it:

set [score v] to [0]
show

when green flag clicked
broadcast [guadagni un punto v]

when green flag clicked
broadcast [guadagni un punto v]

when I receive [guadagni un punto v]
change [score v] by (1)
(I've also swapped "next costume" for "change score by 1"; you get the idea.)

If you run this with single-stepping set to "Flash blocks (slow)", you can see how the first two scripts broadcast the message, but the receiving script only actually runs once the first two have both finished. (Put all these scripts on one sprite, so you can see the blocks flashing!)

Honestly, I think the only way you can fix this is to replace the broadcasts with "change score by 1", etc.  smile


Things I've made: kurt | scratchblocks2 | this cake

Offline

 

#19 2013-01-10 16:01:27

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: Detecting fast repeated messages

s_federici wrote:

blob8108 wrote:

doesn't Scratch only execute one script at a time

Again, no. Scratch is a parallel (or "concurrent") programming language. Indeed scripts from different sprites (but even from the same sprite) are run at the same time (almost). This is done by running a block at a time from each active script. Even this is not really exact: long running blocks (e.g. "glide" or "wait") are often interrupted by running other blocks from other scripts.

Anyway, there are some non interruptable sequences. For example, as far as I know, the blocks contained inside an "IF" block are run without interruption, so to avoid that other scripts will change the truth of the condition (that could make inconsistent the sequence contained inside the "IF" block).

No, that's not correct either. Scratch runs each script in serial until it yields, which happens, e.g., when the script ends or when a loop finishes one iteration. After each process (script) has been run until it yields once, the evaluator goes back and does the next set in serial, and repeats this until there are no more running processes.

Last edited by nXIII (2013-01-10 16:02:07)


nXIII

Offline

 

#20 2013-01-10 16:03:57

blob8108
Scratcher
Registered: 2007-06-25
Posts: 1000+

Re: Detecting fast repeated messages

nXIII wrote:

s_federici wrote:

blob8108 wrote:

doesn't Scratch only execute one script at a time

Again, no. Scratch is a parallel (or "concurrent") programming language. Indeed scripts from different sprites (but even from the same sprite) are run at the same time (almost). This is done by running a block at a time from each active script. Even this is not really exact: long running blocks (e.g. "glide" or "wait") are often interrupted by running other blocks from other scripts.

Anyway, there are some non interruptable sequences. For example, as far as I know, the blocks contained inside an "IF" block are run without interruption, so to avoid that other scripts will change the truth of the condition (that could make inconsistent the sequence contained inside the "IF" block).

No, that's not correct either. Scratch runs each script in serial until it yields, which happens, e.g., when the script ends or when a loop finishes one iteration. After each process (script) has been run until it yields once, the evaluator goes back and does the next set in serial, and repeats this until there are no more running processes.

So the issue is that the broadcast is being pushed into the "queue" after the currently running scripts? It seems to be executed in the "next set", as you described it.


Things I've made: kurt | scratchblocks2 | this cake

Offline

 

#21 2013-01-10 18:00:05

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

blob8108 wrote:

This seems to be enough to replicate it:

set [score v] to [0]
show

when green flag clicked
broadcast [guadagni un punto v]

when green flag clicked
broadcast [guadagni un punto v]

when I receive [guadagni un punto v]
change [score v] by (1)

I guess this will "taglia la testa al toro" (literally "cut the head to the bull" that is "settle things once and for all"  smile  ).

Thanks for spending your time on this.

Offline

 

#22 2013-01-10 18:45:39

nXIII
Community Moderator
Registered: 2009-04-21
Posts: 1000+

Re: Detecting fast repeated messages

blob8108 wrote:

So the issue is that the broadcast is being pushed into the "queue" after the currently running scripts? It seems to be executed in the "next set", as you described it.

The issue is that two broadcasts are being sent in one execution frame. When a broadcast is sent, the implementation simply starts new processes for each hat responding to that event. When a hat already has a process attached, it is replaced by the new process (at the beginning of the script, regardless of the previous process's position). This leads to the behavior you see: the hat is only evaluated once.


nXIII

Offline

 

#23 2013-01-10 21:07:18

Digimath
Scratcher
Registered: 2007-07-07
Posts: 100+

Re: Detecting fast repeated messages

nXIII wrote:

The issue is that two broadcasts are being sent in one execution frame. ....

So, then, the trick is to have each cow release control a different number of times before calling the score routine.  This will let you pick up six cows for a score of 6.  http://scratch.mit.edu/projects/digimathtryit/3030833

Last edited by Digimath (2013-01-10 21:08:06)


I've updated my text adventure game.
Colossal Cave 150http://scratch.mit.edu/static/projects/Digimath/3003787_sm.png

Offline

 

#24 2013-01-11 02:07:55

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

Digimath wrote:

So, then, the trick is to have each cow release control a different number of times before calling the score routine

Wow!!!!!!!!!!!! This is really cool! And, I shouldn't say this but I will say it: I knew there was a non-variable-based way of getting this result! It works incredibly well. I says incredibly as it is not really clear to me why it does work  smile  Any further detail/example?

Offline

 

#25 2013-01-11 02:23:09

s_federici
Scratcher
Registered: 2007-12-18
Posts: 500+

Re: Detecting fast repeated messages

nXIII wrote:

Scratch runs each script in serial until it yields, which happens, e.g., when the script ends or when a loop finishes one iteration

Thanks for correcting me. Do you have a full list of all yielding blocks? As you says, one of them is the repeat block (the base of the 1S1S projects), other ones are timed blocks are "wait" and "glide". Which else?

Offline

 

Board footer