I wrote an earlier story on visual programming with Scratch. You should read that one if you don’t know what I mean by visual programming.
Basically it is about snapping together different blocks visually representing code, instead of writing programming statement in an editor.
In the last story I did mention MakeCode from Microsoft and gave some first impressions. Here I will give a more in depth evaluation of what it is like teaching children to program using MakeCode.
The Good Parts
I have spent several days with my youngest son (8 years) making games with MakeCode Arcade.
He has had a lot of fun doing this. We bought the Kitronik ARCADE handheld game console. This allows you to put retro 8-bit style pixel art games made with Microsoft MakeCode and download them to this device. If it wasn’t for the COIVD19 crisis he could have taken it out and show games he has made to his friends.
Microsoft has made a pretty polished and comprehensive package for making games. You have a much wider selection of blocks than in Scratch and they are more versatile. You can more easily configure them to modify behavior of standard blocks.
Not only does MakeCode allow you to draw Sprites like in Scratch but you can also have a tiling system well suited for making game levels composed of multiple tiles.
Adding something like button control of your sprite requires dragging out just one special block that does everything for you.
The Bad Parts and Why Scratch is Probably Better
When I started Scratch looked more limiting to me and MakeCode looked more advanced and flexible. I started leaning heavily towards MakeCode. Especially since it allowed us to program MineCraft.
However once you get a more in depth understanding of each system you start to appreciate Scratch more. MakeCode has a problem which has often bothered me with everything I have ever used from Microsoft. Microsoft likes you give you shortcuts right in your hands.
Meaning they want to give you lots of stuff that makes relatively simply stuff even easier and quicker to do. However a frequent weakness of Microsoft technology is that is that it is not well thought out conceptually. As your solutions get larger the Microsoft solutions often get messy. Understanding what is going on is also often difficult.
I have past memories of working with Microsoft technologies where a lot of what I did sure was simple to snap together but it was kind of like magic. It was not obvious how it worked and it was rather brittle. If something broke and you had to understand what was going on under the hood then you where screwed.
The problem rears its head with MakeCode as well. In Scratch you have a sheet of code blocks for each sprite in your game. You can easily make a Sprite just to contain code. The principle is quite similar to how real professional game engines are organized, so it is a pretty good and well established concept.
It makes it possible to modularize larger programs. MakeCode in contrast quickly become a mess when you make larger programs. You only have one sheet in which all your code has to be placed. You end up with blocks floating around everywhere.
MakeCode Null Object Problem
A big problem with how MakeCode is organized is that it works a lot like regular programming languages where referring to uninitialized variables is a real possibility.
Especially because a lot in MakeCode is event driven it is not easy for a beginner to keep track of what objects actually exist at any given time.
I saw my son get tripped up by this several times. Understanding what null objects where and how to debug such problems was quite hard for him. I had to show him what was wrong but found it quite hard to give him a good explanation of what the problem was and how to avoid it.
It was struggling with this problem which made me realize how well designed Scratch is. There is simply no way you can end up with a null object of any sort in Scratch.
Scratch is basically a prototype based language. For each unique sprite you define a prototype, which contains a drawing of several costumes (frames) as well as a canvas to place your code blocks.
You can clone a sprite prototype which creates another event which you must process to tell your clone how to behave. Scratch does not have a way of putting these clones in specific variables. This also means there are is no way to have a clone variable with a null object.
This is different from MakeCode where you explicitly create a sprite object, initialize it with an image and place it in a variable. The downside here is that if you refer to this variable somewhere else in your code, it may not have been bound to a sprite object yet. Hence the null object problem.
How does Scratch manage to avoid dealing with instances of sprites directly? When doing things like collision detection in Scratch you just check if there is a collision between an instance of one prototype and an instance of another prototype. You never know which specific instance you are colliding with.
However each sprite can check for collision against instance of the other type of sprite. Hence each sprite would be executing collision code on a specific instance. Every instance will run the same collision check code. But only one particular instance will actually collide.
Specialized vs Versatile Code Blocks
MakeCode has a number of highly specialized code blocks that does convenient stuff. E.g. you can just drop in a single block and configure it to be able to move your main sprite in any direction.
Scratch does not have quite as specialized blocks. Scratch has aimed to create fewer but more versatile blocks. I feel that using Scratch force the user to understand more how things work. You have to actually combine various blocks to achieve what one block can sometimes magically do in MakeBlock.
Because Scratch has fewer blocks which are more composable you can more easily keep an overview in your head over all the blocks that exist and what they can do.
Scratch programming then becomes more about thinking about how basic blocks can be combined to create new functionality. This is kind of refreshing for an old school programmer such as myself who is used to wasting quite a lot of time hunting down the specific function or class that solves my problem. You can skip the whole hunting exercise with Scratch. Just combine blocks.
MakeCode has far more blocks, more extensions etc so that you spend more time looking for blocks and thinking about whether there is a particular block that solves your particular problem. In this regard I think Scratch is better at teaching you to be a programmer. It focuses more on problem solving rather than something akin to googling skills.
MakeCode Arcade really push the idea that you should draw your own sprites and tiles. That is both good and bad. I actually like this a bit because it forced my son to actually draw all the stuff he wanted in his game himself.
There is a certain satisfaction in moving around sprites you made yourself.
However it is also somewhat limiting. If you have higher ambition and want a more elaborate world it can be fun to combine graphics from others. You can buy a ton of high quality game assets for almost nothing. I want to highlight a couple I like a lot.
Game Developer Studio e.g. has tons of cheap kid friendly assets which match each other very well. Kenney also has a wide variety of child friendly assets for games, many for free. And there are many beautiful pixel art game assets such as these ones from Malibu Darby.
Ready made assets are also fun to play with for kids they can assemble ready made parts in different ways, to create their own creations.
Today I wish I has spent more time with Scratch to understand better its strengths. I would probably have pushed my son a bit more to familiarize himself with Scratch rather than MakeCode.
MakeCode is very well curated. So unless you invest some time as a parent, it is much quicker to get into MakeCode. There are more tutorials and examples laid out in way that is quick to get into.
Scratch feels more like MIT gave people the tools and then a large community had to make the resources themselves. The Scratch community looks very strong to me but it is not entirely obvious how to begin to learn. At least it was not for me.
Personally I plan to experiment more with Scratch as I think this is a better tool for children to learn programming. That you can switch to “real” programming from MakeCode is nice but I think you sacrifice too much to do it. To accomplish that they make a visual code block system which simply is not as user friendly. The compensate with a lot of specialized blocks which get your started quickly. But you don’t always develop a good understanding of how things work and can be combined.
Alternatively I think REPL based coding in something like Julia or Racket is better. When stepping over to “real” programming I think a focus on more traditional stuff like working more with just text and numbers make more sense.