Destroy within an on sprite of kind Food overlaps block

I’ve got a bug in a game where the last Food sprite eaten isn’t destroyed when the level changes. This results in it lingering in a graphical sense on the next level.

The code is a bit big and I’ve not yet managed to reduce it to a simple example for reproduction of the bug. The essence of it seems to be the ordering within the on sprite overlaps block. If I change the foodCount variable to be decremented after the destroy it’s ok but in its original position the bug appears. I could just change this but I’d like to understand why this fails.

arcade-Chomper-V58modified-on-sprite-overlaps-Food-debugging-screenshot-code1

I’m not sure if this is a problem in my code or in the Arcade system and it’s not clear if this is a race condition or not.

The second play sound in there is added for debugging to let me determine if the code is reached. The strange thing is when the bug appears and the last food item is not destroyed that second sound plays. I can’t think of any explanation other than the destroy on otherSprite failing. Is that possible?

There’s a test of foodCount being zero in the on game update which triggers the transition to the next level. This is clearly implicated because if I add five pauses of 100ms in the if block for that then the bug goes away too. It’s doing the normal kind of clean up, new tile map, splash screen but I’m not sure if there’s anything an application could do there which would prevent the aforementioned destroy sprite working?

The full code is https://arcade.makecode.com/75342-75047-13962-10112 - the last one from Presenting: Chomper

I had a brief play with the debugger. No revelations there. It does show the destroy happening after the splash screen pops up but I’m not too sure how much to read into the sequencing of operations across the “threads” in debug mode.

Play tone pauses until the note is complete (you can see this when you have multiple in a row - it doesn’t smush them into one sound)

in this case, the pause from the sound is deferring the destruction of the food sprite until after the sound completes - which is then occurring when you’re in a different scene (splash screen), so it’s not removing itself from the original scene; when you place the foodCount-- after the sprite destroyed, there isn’t a pause that yields to the other fibers and the food is destroyed.

It’s really subtle, but here’s how you can see it using the debugger; see that the playtone yields and other fibers take over, and when you press play again it will hit the next breakpoint on sprite destroy when the splash screen is up.

Thanks for the analysis and detailed reply.

To a Blocks programmer the whole Scene thing is not very evident as it’s just the name of a drawer and a name that feels almost arbitrary. It seems a little odd that the on block is passed two sprites and they become transiently invalid in some way during the display of some text on screen but then are fine after that. Certainly from the Blocks world, this is not very intuitive. Is the moral of the story here to ensure no code runs while a splash screen is up? I’ll go fix the game!

On the debugger front, is single stepping fairly accurate when it comes to showing how the code would run with debug off? And what version of the debugger are you using, it looks different to production?

On the upside, I did stumble across GH: microsoft/pxt-arcade: Velocity of sprite is reduced incorrectly for constrained movement on diagonal control #1727. while trying to recreate this from a small program.