探究:Scratch sb格式文件结构

0. 前言
Scratch是麻省理工(下称MIT)开发的图形化编程工具。这款工具曾是笔者所热衷的软件,曾陆续使用其开发出一些小作品并获得一些小奖项
但是,在对计算机有更多了解后,笔者发现绝大多数格式文件本质都是压缩包(docx,pptx)或文本,那么Scratch专属sb3格式是否也是如此呢
1. 探索
1.1 文本还是压缩包
首先,我们启动 Scratch 3.29.1

尝试保存一个空项目,用记事本打开


打开一片乱码,那么显然,我们的方式不对,但是

这里出现两个文件名,所以,我很肯定,这是个压缩包
1.2 里面有什么

用压缩软件打开

里面是3个svg图像,两个wav音频和1个json,这个json显然是核心,但是我们先打开其他文件看看

第一个svg图像是默认精灵的外观,我们接着打开其他
分别是:
默认背景“啵”音效
默认精灵“喵”音效
默认精灵的两个造型
1.3 project.json
最激动人心的时刻来了,我们打开最后的project.json

很乱,我们用VSCode打开

映入眼帘的是一个targets数组,我们先看数组里的第一个对象
经过略微研究,我得到了部分标签的信息
2. 结论
2.1 一个“类”
显然,一个targets数组对象不是用Scratch官方所给的“精灵”或是“背景”能描述的,因为它同时包括两者。所以我们赋予它一个新的名字,这很容易让我们想到C++、Java、JS等面向对象编程语言中的“类(Class)”的概念,所以我们称它为类
这是我们目前能确定下来的标签
2.2 变量
接着,我们创建第二个变量
这时,variables对象就会多出来一个数组,标签是随机字符
可见,数组第一项为名称,第二项为值
但是数组名称真的是随机字符吗?我们抱着试一试的态度修改project.json,在variable对象中增加一个数组,标签略作修改,名称为testVariable,值为5

如图,确实多了一个变量,
2.3 列表
接着我们建立一个列表,名为list
此时lists对象也会多出一个数组
由此可得,列表的名称是随机字符,第一项为列表名称,第二项为列表的值,第二项中的每 一项都是列表中的对应项
2.4 命令
最后就是我们的重头戏:积木
积木数据存储在类对象的blocks对象中,一个blocks对象子对象大致长这样
上方是一个“移动10步“积木
opcode是区分对象操作的标识,这里我们也给他起个名字,叫“命令(Command)”
但是需要注意,一个blocks对象子数组不单单描述一个积木,如一个“移到”积木会包含两个对象,命令分别是“motion_goto”,“motion_goto_menu”,第一个命令的输入会将第二个命令的标识符传入以调用
next应该是存储下一个积木的标识符,parent即父积木,由于此处没有给他拼接启动积木,所以为空(Null)
inputs是当一个积木有参数时,Scratch会读取inputs对象中的每一个数组为参数,如STEPS指代该数组唯一的参数,即移动步长。第一项为参数索引,第二项为参数值,但令笔者百思不得其解的实际上是参数值的第一项,即图中4。经过笔者实践发现,该值实际上大部分积木种类中是相同的。参数值第二项即参数值本身
3. 用途
实际上,这些东西当读者阅读Scratch源码时就可以知道,但是毕竟不是所有人都有时间阅读冗长的JavaScript源码。笔者以解析文件格式为目的,鼓励大家发现事物实质。
如果读者有兴致,可以本文为参考,自行编写一款Sb3文件编辑器,从此摆脱Scratch文件系统束缚,开始自己的编辑之旅