Microsoft MakeCode

Sequence of execution between outer blocks in Arcade

I wanted to investigate the sequencing of the block execution particularly around the on start and controller events. We’ve been working on a basic level framework and it raised some questions about when certain blocks and events run. This is my code to investigate this:

arcade-Block-Sequencing-Experiment-v1

That confirmed that the controller events can run during the on start block. I’d imagine some programmers want that to happen and some don’t. The former is more flexible but it does create an interesting dilemma for writing correct code if variables are initialised in the on start block for use elsewhere.

In the simulator (0.14.4 5.21.6), I see the forever blocks execute at a similar but very slightly less frequent than on game update - I’ve seen this is documented on Game Loop. A MakeCode or Scratch programmer will be used to using forever blocks. Is on game update a complete replacement for forever blocks in the Arcade world? Is there any reason to ever use a forever block?

I tried this on the PyGamer. There I see the forever block appears more synchronised in frequency of execution with the on game update. I think there’s a bug somewhere too for the version compiled for the device. Sometimes I can get it so I press button B to view the console data (enabled via show console) and the values “freeze” with the exception of the button counter. I need to play around a bit more with this to work out how to trigger it as it’s very timing dependent…

Added later: I put in GH: microsoft/pxt-arcade Console output may show incorrect variable values on a real device #1251 for issue on the device.

re: controller event registration

It’s easiest to see what’s happening here if you switch to JavaScript and see what it produces:

function logCounters(desc: string) {
    console.log(desc)
    console.logValue("forever1", forever1Count)
    console.logValue("forever2", forever2Count)
    console.logValue("forever3", forever3Count)
    console.logValue("buttonA", buttonACount)
    console.logValue("ongameupdate1", ongameupdate1Count)
    console.logValue("ongameupdatesevery1", ongameupdateevery1Count)
}
controller.A.onEvent(ControllerButtonEvent.Pressed, function () {
    buttonACount += 1
})
controller.B.onEvent(ControllerButtonEvent.Pressed, function () {
    logCounters("onBbutton")
})
let ongameupdateevery1Count = 0
let ongameupdate1Count = 0
let buttonACount = 0
let forever3Count = 0
let forever2Count = 0
let forever1Count = 0
let onstartExecuting = true
forever1Count = 0
forever2Count = 0
forever3Count = 0
buttonACount = 0
ongameupdate1Count = 0
ongameupdateevery1Count = 0
logCounters("onstart1")
pause(5000)
logCounters("onstart2")
pause(5000)
logCounters("onstart3")
onstartExecuting = false
forever(function () {
    forever1Count += 1
})
forever(function () {
    forever2Count += 1
})
forever(function () {
    forever3Count += 1
})
game.onUpdate(function () {
    ongameupdate1Count += 1
})
game.onUpdateInterval(100, function () {
    ongameupdateevery1Count += 1
})

This is just an option in the authoring of the blocks, whether the block will come before or after the on start - as you mentioned, different people would prefer different behaviors here (or even the same person for different programs), but for controller events the main reason it comes before is that somebody may want to do things in the on start - make choices, choose a character, etc - and having any sort of interaction at all would require the events to be registered before the on start. If someone needs this behavior to be different - to register after the on start, or to change controller events after some point - then generally that’s probably the point where they would want to switch to JavaScript for more fine tuned control.

re: on game update vs. forever

on game update events run synchronously as part of the game loop; an easy way to make the game have a choppy / framey ‘aesthetic’ would be to put a pause into the event controller event

forever loops start as part of the game loop, but run independently. You can put a pause in one without the game freezing - for example, this lets you have events that run on a variable timer (whereas on game update interval will always have the same interval)

Generally you probably want on game update, but forever still has distinct uses. A more advanced use would be for making custom ‘event handling’ for events that don’t have blocks for them / are arbitrary:

Thanks for the detailed reply, that’s a lot of very useful info to digest.

I had put a 50ms pause an on game update block - I hadn’t realised that was a contributor to slightly poor performance.