mit-scratchblock-programming

What is the architecture behind Scratch programming blocks?


I need to build a mini version of the programming blocks that are used in Scratch or later in snap! or openblocks.

The code in all of them is big and hard to follow, especially in Scratch which is written in some kind of subset of SmallTalk, which I don't know.

Where can I find the algorithm they all use to parse the blocks and transform it into a set of instructions that work on something, such as animations or games as in Scratch?

I am really interested in the algorithmic or architecture behind the concept of programming blocks.


Solution

  • This is going to be just a really general explanation, and it's up to you to work out specifics.

    Defining a block

    There is a Block class that all blocks inherit from. They get initialized with their label (name), shape, and a reference to the method. When they are run/called, the associated method is passed the current context (sprite) and the arguments.

    Exact implementations differ among versions. For example, In Scratch 1.x, methods took arguments corresponding to the block's arguments, and the context (this or self) is the sprite. In 2.0, they are passed a single argument containing all of the block's arguments and context. Snap! seems to follow the 1.x method.

    Stack (command) blocks do not return anything; reporter blocks do.

    Interpreting

    The interpreter works somewhat like this. Each block contains a reference to the next one, and any subroutines (reporter blocks in arguments; command blocks in a C-slot).

    First, all arguments are resolved. Reporters are called, and their return value stored. This is done recursively for lots of Reporter blocks inside each other.

    Then, the command itself is executed. Ideally this is a simple command (e.g. move). The method is called, the Stage is updated.

    Continue with the next block.

    C blocks

    C blocks have a slightly different procedure. These are the if <> style, and the repeat <> ones. In addition to their ordinary arguments, they reference their "miniscript" subroutine.

    For a simple if/else C block, just execute the subroutine normally if applicable.

    When dealing with loops though, you have to make sure to thread properly, and wait for other scripts.

    Events

    Keypress/click events can be dealt with easily enough. Just execute them on keypress/click.

    Something like broadcasts can be done by executing the hat when the broadcast stack is run.

    Other events you'll have to work out on your own.

    Wait blocks

    This, along with threading, is the most confusing part of the interpretation to me. Basically, you need to figure out when to continue with the script. Perhaps set a timer to execute after the time, but you still need to thread properly.

    I hope this helps!