全局自制积木
原版 Scratch 的自制积木只属于做它的那个角色,别的角色要用就得抄一份,之后改一处得改十处。 Gandi 3.0 的全局自制积木是一处定义、所有角色都能调的那种:定义改了,散在各个角色里 已经摆好的调用块跟着一起变。

只有模块能定义#
模块是一种只装代码的角色,舞台上没有它的位置。在「角色」面板工具条最右边点「新建」→ 「新建模块」,填个名字就有了;对话框里写着「模块是只放代码的角色,只有模块能定义全局积木」。模块的身份 在新建时定下来,改名既变不成普通角色,也变不回模块,见角色栏。
在模块里做自制积木时,「制作新的积木」对话框底下的「全局积木」开关才能打开(别的角色 里它是灰的,下面写着「只有模块里的积木能设为全局」)。
打开之后,「分类」自动填上模块名:模块叫「工具」,这块积木就归到积木栏的「工具」小标题下。 分类只是个默认值,改成别的一样。
名字就是名字,前面不加任何东西。代价是全作品不能重名:一个模块里已经有「初始化」, 另一个模块就做不出第二块「初始化」,做的时候会被拦下来,改个名就是了。
把开关关掉,积木退回成这个模块自己的本地积木。
让它在所有场景里都能用#
多场景作品里,「全局积木」开关旁边还有一个所有场景。
全局积木住在模块里,而模块本身是一个角色 —— 它属于哪个场景,它的积木就只在那个场景里有。 所以想「定义一次,每个场景都能调」,要动的不是积木,是把这个模块变成跨场景角色: 勾上「所有场景」就是这个意思。模块随即出现在角色栏最下面的「跨场景」一组里,每个场景都有它, 它的全局积木也就处处都能调。
勾掉就退回单场景 —— 模块回到它原来那个场景,别的场景里那些调用块就找不到定义了。
单场景作品不画这个开关,那时它什么都不改变。
积木栏里分两档#
只要一个角色同时有全局积木和自己的自制积木,「自制积木」这一类就分成两段, 上面「全局」,下面「本角色」:

只有一档的时候不画标题,那时标题起不到区分作用。每一段里按分类分小节,同一个模块的积木 默认归在以模块名命名的那一节里。
积木配了分类时,分类是每一档里的小节:没分类的排在 这一档最前面,然后每个分类一条可折叠的小标题。同一个分类在两档里各出现一次时,折叠的是 「这个分类」,两处一起收。
「制作新的积木」按钮和「返回 ( )」积木不算在这两段里,还是在最上面。
改定义,所有地方一起变#
在定义块上右键「编辑」,或者在任何一块调用块上右键「编辑」,改完按「完成」:
| 改了什么 | 已经摆好的调用块 |
|---|---|
| 改名 | 跟着改名,填在里面的值不动 |
| 加一个参数 | 多出一个空格子(输入框带一个空的文本槽,布尔槽是空的) |
| 删一个参数 | 少一格,其余格子里的值不动 |
| 换形状(普通 ↔ 返回值 / 布尔) | 换成对应形状的调用块 |

范围是整个作品,不只是眼前这一个工作区:
- 已经开着的别的角色的工作区,当场重画;
- 从来没打开过的角色,直接改它存着的积木数据;
- 别的场景里的角色也一样算在内。
整次改动算一步撤销。在定义它的那个模块里按一次 Ctrl + Z,全作品一起退回去,
而不是每个角色各留一个撤销点;后者会导致在角色 B 按一次撤销之后,作品当场就对不上。
从调用块跳到定义#
调用块上右键,菜单里有「跳到定义」:

它按三步找:先在当前这一页找,找到就只滚过去;再翻已经开着的别的工作区,找到就滚 过去并把那个面板带到前面;都没有的话,才去作品里查是谁定义的,切到那个角色(必要时连 积木页一起切),把定义块居中、闪一下黄光,同时提示一句「定义在「工具」里」。
先找当前这一页,是因为绝大多数定义就在手边,也避免一个同名的积木把人带到别的角色去。
右键菜单里的「编辑」在不是定义者的角色里也能用:它会先跳到定义处,再把编辑对话框打开。
删除有人用的全局积木#
在定义块上右键「删除」,如果这块积木还有角色在用,就删不掉,右上角会提示是谁在用:

名单最多列四个角色,再多就写成「等 N 个角色」。查的是整个作品,包括没打开过的角色和 别的场景里的角色。
⚠️ 这里有个缺口:只有定义块下面空着的时候拦得住。 定义里已经接了积木的话,右键「删除」 会直接把定义删掉,不提示、不拦截,别的角色里那些调用块就成了没有定义的孤儿。要删一块全局 积木,先把定义里的积木清空,再删。
两处需要注意的行为#
被删的那一格里插过积木时#
如果别的角色里某个调用块的那一格里插的不是默认值,而是用户自己拖进去的一块积木(比如 一个变量、一段运算),删参数之后那块积木不会丢,但也不会留在格子里,而是被移出来 成为一段独立的脚本:
- 没打开过的角色里,它落在原来那段脚本左上角右下方一点的位置;
- 已经开着的工作区里,它就地留在原处。
撤销把参数加回来的时候,回来的是一个空格子,那块积木不会自动回去,需要手动拖回。
两个模块定义同名积木没有处理#
跨角色找定义、找调用,用的键只有 proccode(也就是积木的名字),VM 每一层 缓存都按它索引。所以万一作品里真的出现两块同名的全局积木:
- 「跳到定义」永远跳到排在前面的那一个,另一个从调用块这边跳不过去;
- 改其中一个的定义,两个的调用块都会被改;
- 运行时也是排在前面的那个说了算。
正常操作走不到这一步:做积木时会全作品查重名(「已经有一个叫「初始化」的 积木了」),所以这只会出现在导入的作品、或者手改过的作品里。
细节#
- 删掉一块全局积木之后,别的角色如果工作区已经开着,它的积木栏里还会列着这块积木, 直到那个工作区重新建起来(切走再切回来,或者刷新)。
- 模块在每一个场景里都在,所以模块定义的全局积木在所有场景里都看得到。
- 拦下删除时提示里写的是角色的原始名字,模块会带着
#modules/前缀显示。