Introducing a JavaScript library for exploring Scratch projects: sb-util

Introduction

We’re excited to introduce sb-util, a new JavaScript library that makes it easy to query Scratch projects via .sb3 files. This npm library allows developers (or even teachers and students) to parse and introspect Scratch projects for a range of purposes, from data visualization to custom tooling.

Previously, working with Scratch project files required manually unzipping the .sb3 package files, parsing the project.json file inside, and scanning the package for associated assets such as costumes, sounds, and backdrops. The new library not only provides project data via an easy-to-use API with full Typescript type annotation, but it also exposes assets and blocks in idiomatic, iterable collections with convenience methods for querying objects using CSS selector syntax.

Here is a short example of querying a sprite by a given name in just three lines of code:

import { loadSb3 } from 'sb-util';
const sp = await loadSb3('foo.sb3');
let sprite = sp.sprites('[name="Cat"]').first();

Examples

We hope that sb-util will make it easier for the entire Scratch community to write scripts, tools, applications, and tests related to Scratch projects. Researchers can use the library to study the contents of Scratch projects programmatically. For example, sb-util makes it easy to answer questions about projects individually or in aggregate. What is the projected network download time for this collection of projects given their number of assets? How many sound files do students typically add to their projects? What types of blocks do kids tend to use most frequently?

Developers can use sb-util to write custom scripts such as file converters or search applications and tooling authors can use sb-util to simplify testing, parsing, and validation of Scratch projects. Bocoup is already using sb-util to unify and simplify project parsing across a variety of internal and open source projects.

One of the most exciting use cases is that of Scratch users who use sb-util to peer under the hood of projects they create in the Scratch Editor. The sb-util API is an approachable way to start to explore the way that Scratch projects are serialized and understand fundamental lower-level programming concepts about the Scratch VM, such as how it interprets blocks using opcodes to execute programs.

Walkthrough

To demonstrate the usage of sb-util, we will demonstrate how to build a simple data visualization of block counts for a sample project. We want to eventually show a pie chart with the total number of each shape of block visualized. To follow along with this example, see the examples/datavis directory in the sb-util repository.

First, we can load our sample project (in this case a project JSON file) and get all of the project blocks with:

import { loadProjectJson, BlockShapes } from 'sb-util';
const sp = await loadProjectJson('../../tests/data/accelerator.json');
const blocks = sp.blocks();

Next we want to iterate over all of the possible block shapes in order to count them. Sb-util conveniently exports a Typescript enum (or JavaScript object).

let outputData = [];
for (let [key, shape] of Object.entries(BlockShapes)) {
    ...
}

Inside the body of the for loop, we can retrieve and count all of the blocks of a given shape with the following query:

        const shapeBlocks = blocks.query(`:${shape}`);
        const totalShapeCount = shapeBlocks.count();

Finally we can increment a dictionary of block counts for each block shape using an inner loop with the propsIterable method:

        const blocksCount = {};
        for (let block of shapeBlocks.propsIterable()) {
                blocksCount[block.opcode] = (blocksCount[block.opcode] || 0) + 1;
        }
        outputData.push({ name: shape, count: totalShapeCount, blocks: blocksCount });

To see the entire code together and the frontend d3 code we used to visualize the final pie chart, check out the full example code on GitHub.

Conclusion

We’re excited to launch sb-util and see how the Scratch community puts it to use. In the future, we hope to be able to standardize the interface for Scratch projects and unify code for parsing and saving Scratch files, across multiple different projects—including perhaps even official upstream Scratch repositories.

In the meantime, get involved and let us know if you have ideas, issues, or contributions on GitHub.

Comments

Contact Us

We'd love to hear from you. Get in touch!

Phone

+1 617-379-2752

Mail

P.O. Box 961436
Boston, MA 02196