--{{0}}--
This template turns a LiaScript code block into a real Scratch 3 project.
Attach @Scratch to a code block – and instead of the text editor you get the
blocks and the stage of Scratch:
- ▶ starts the project (like the green flag), ⏹ stops it. In a task
with
@Scratch.check, ▶ also runs the check. - The green flag and the stop sign above the stage work as in Scratch.
In a task with
@Scratch.checkthe flag only tries the project out, and a big Check button next to them runs ▶ with the check. - Every start with ▶ and changes creates a new version. Use the arrows below the project to go back and forth between your versions.
- The project itself stays text in the code block – readable, easy to write for teachers, and understandable even without Scratch.
- Blocks, menus and texts follow the language of the course – in all languages Scratch supports.
when green flag clicked
repeat (4)
move (80) steps
turn right (90) degrees
wait (0.5) seconds
end
@Scratch
Scratch is a project of the Scratch Foundation, in collaboration with the Lifelong Kindergarten Group at the MIT Media Lab. This template is not an official Scratch product; it uses the freely licensed Scratch components.
To use the template in your own course, add one of the following lines to the header of your course.
Fixed version (recommended, will not change anymore):
import: https://raw.githubusercontent.com/LiaTemplates/ScratchBlocks/0.4.0/README.md
Latest version (may change at any time):
import: https://raw.githubusercontent.com/LiaTemplates/ScratchBlocks/main/README.md
Then attach one of the macros to a code block:
| Macro | for | Blocks |
|---|---|---|
@Scratch.level1 |
grades 1–2 | 8 large blocks, one sprite, read aloud |
@Scratch.level2 |
grades 3–4 | events, motion, looks, sound, simple control |
@Scratch.level3 |
grades 5–7 | everything except lists, custom blocks and clones; many sprites |
@Scratch.level4 |
grade 8 on | all of Scratch, sb3 import and export |
@Scratch |
= level4 |
|
@Scratch.profile(name) |
own profile | see Custom profiles |
@Scratch.check(level) |
tasks | project + hidden check, see Tasks with checks |
The German names @Scratch.stufe1 … @Scratch.stufe4 and
@Scratch.profil(name) work as well.
In the @onload of your course you can also register your own profiles
(window.LiaScratch.defineProfile, see Custom profiles)
and your own costumes, backdrops, sounds and sprites
(window.LiaScratch.defineAsset and defineSprite, see
Own sprites, backdrops and sounds).
--{{0}}--
The Scratch interface lies on top of the code block. What is stored, however, is always the text in the code block.
- Drag blocks – every change is written into the code block right away. With the Text button (from level 3 on) you can look at it.
- Press ▶ – the project starts. All sprites begin at their start position, so a program runs the same way every time.
- Change the start position – drag a sprite to another place on the stage while the project is not running.
- Versions – with ◀ and ▶ below the project you get earlier versions back. Blocks and stage follow along.
If the code block is empty, the project starts with a white stage and the sprite Robo.
When a project opens, the blocks of Robo are shown. Without a sprite Robo, the first sprite with scripts is shown, otherwise the front-most sprite. A click on a sprite below the stage shows its blocks.
@Scratch
--{{0}}--
In a LiaScript classroom, several students can build one project together.
Switch the code block to the collaborative editor (the classroom button below the project). From then on everyone works on the same project:
- Every change in the blocks is sent like typing – only the part that changed. Two students can work on different scripts or sprites at the same time; both changes are kept.
- If both change the very same value at the same moment, all participants still end up with the same project, but the value may be a mix of both.
- Changes of others appear right away – except while you are dragging a block or a sprite, editing a field, or while the project is running. Then they follow as soon as you are done.
This works best with the text format. A project stored as
project.json is synchronized as well, but changes made at the same time can
break the JSON; the last working project then stays loaded.
--{{0}}--
There is a profile for every age group. It defines which blocks are offered and how large they are.
The profiles build on each other: a project from level 1 also runs in level 4, just with more blocks to choose from.
Few, large blocks and a single sprite. Tap a block in the palette to hear it read aloud.
Task: Let Robo walk a square.
when green flag clicked
move (80) steps
turn right (90) degrees
@Scratch.level1
Adds keys and mouse clicks, forever loops, simple conditions and sounds.
Task: Steer Robo with the arrow keys. Click on the stage first.
when [right arrow v] key pressed
change x by (10)
when [left arrow v] key pressed
change x by (-10)
@Scratch.level2
Variables, operators, sensing, broadcasts and the pen. More sprites can be added.
Task: Robo draws a polygon. Change the number of corners.
[Sprite Robo]
variables: corners = 6
when green flag clicked
erase all
pen down
repeat (corners)
move (60) steps
turn right ((360) / (corners)) degrees
end
pen up
@Scratch.level3
All of Scratch with lists, custom blocks and clones. Projects can be loaded
and saved as .sb3.
[Sprite Robo]
lists: words = Hello, LiaScript, Scratch
define say all words
set [i v] to (1)
repeat (length of [words v])
say (item (i) of [words v]) for (1) seconds
change [i v] by (1)
end
when green flag clicked
say all words
@Scratch.level4
--{{0}}--
The template speaks the language of your course: set language: in the
header of your course, and blocks, menus, buttons and the text in the code
block follow.
All 80 languages Scratch supports are available, for example de, fr,
es, et, ar, ja or zh-cn. English is the default and is always
understood in the text as well, so you can write English text in any course.
The same program in a course with language: de and with language: et:
Wenn die grüne Flagge angeklickt kui klõpsata ⚑
wiederhole (4) mal korda (4) korda
gehe (80) er Schritt liigu (80) punkti
Ende end
- Section headers and properties use Scratch's own words for Stage,
Sprite, costumes, sounds … in that language; where Scratch has no
translation, the English word is used.
x:andy:are the same in all languages. - Where a block would be ambiguous in a language (e.g. the green flag without a readable spelling), it is written with its symbol (⚑ ↻ ↺) or in English.
- If the page is translated, e.g. with Translate with Google in LiaScript's settings, blocks, menus and buttons switch to the new language right away, using Scratch's own translations (the Scratch interface is excluded from the machine translation). The text in the code block stays in the language of the course, so stored projects and their versions do not change; text in the display language is understood as well.
- Button texts, dialogs and pen blocks come from Scratch's own translations. The few texts of this template itself (e.g. the result of a check) exist in English and German; other languages show them in English.
--{{0}}--
The code block contains the project in scratchblocks notation – the same notation that is used in the Scratch Wiki and the Scratch forums.
A project consists of sections for the stage and for every sprite. Each section starts with a header in square brackets, followed by properties and finally the scripts. Scripts are separated by empty lines.
[Stage]
backdrops: white
variables: score = 0
when green flag clicked
set [score v] to (0)
[Sprite Robo]
costumes: robo-a, robo-b
sounds: pop
x: -100
direction: 90
size: 100
when this sprite clicked
change [score v] by (1)
play sound [pop v]
next costume
@Scratch
| Property | Meaning | Default |
|---|---|---|
costumes: |
costumes from the library or your own; a * marks the current one, e.g. robo-a, robo-b* |
robo-a, robo-b |
backdrops: |
backdrops of the stage, * marks the current one |
white |
sounds: |
sounds from the library | pop |
x:, y: |
start position | 0 |
direction: |
start direction in degrees | 90 |
size: |
size in percent | 100 |
visible: |
yes or no |
yes |
draggable: |
can the sprite be dragged while the project runs? | no |
variables: |
name = start value, separated by commas |
|
lists: |
name = value, value, …, several lists separated by ; |
|
monitors: |
variables and lists shown on the stage |
Without headers, all scripts belong to the sprite Robo on a white stage.
--{{0}}--
Some projects cannot be written completely as text, for example when they contain their own images or recordings.
In that case the code block can also contain Scratch's project.json. A
project opened with Load sb3 automatically appears in this form; its own
images and sounds are embedded.
{
"targets": [
{
"isStage": true,
"name": "Stage",
"variables": {},
"lists": {},
"broadcasts": {},
"blocks": {},
"comments": {},
"currentCostume": 0,
"costumes": [{ "name": "white", "asset": "white" }],
"sounds": [],
"volume": 100,
"layerOrder": 0,
"tempo": 60,
"videoTransparency": 50,
"videoState": "on",
"textToSpeechLanguage": null
},
{
"isStage": false,
"name": "Robo",
"variables": {},
"lists": {},
"broadcasts": {},
"blocks": {
"a": {"opcode":"event_whenflagclicked","next":"b","parent":null,"inputs":{},"fields":{},"shadow":false,"topLevel":true,"x":0,"y":0},
"b": {"opcode":"looks_sayforsecs","next":null,"parent":"a","inputs":{"MESSAGE":[1,[10,"Hello!"]],"SECS":[1,[4,"2"]]},"fields":{},"shadow":false,"topLevel":false}
},
"comments": {},
"currentCostume": 0,
"costumes": [{ "name": "robo-a", "asset": "robo-a" }, { "name": "robo-b", "asset": "robo-b" }],
"sounds": [{ "name": "pop", "asset": "pop" }],
"volume": 100,
"layerOrder": 1,
"visible": true,
"x": 0,
"y": 0,
"size": 100,
"direction": 90,
"draggable": false,
"rotationStyle": "all around"
}
],
"monitors": [],
"extensions": []
}@Scratch
--{{0}}--
Sometimes you only want to show blocks, for example in a hint or next to an
explanation. @Scratch.blocks draws them as a picture, without an editor and
without a stage. The blocks are written in the same notation and appear in the
language of the course.
``` scratch @Scratch.blocks
when green flag clicked
repeat (10)
move (25) steps
end
```when green flag clicked
repeat (10)
move (25) steps
end
The German alias is @Scratch.bloecke. The picture is an SVG with the text of
the blocks as its accessible label.
--{{0}}--
A task consists of two code blocks directly below each other: the Scratch project and a hidden check written in JavaScript.
The check starts with a minus in front of its file name (-Check), so it
stays collapsed. When ▶ is pressed, the check starts the project and then
evaluates it. The result appears below the project.
Task: Robo should walk at least 150 steps to the right, using a repeat loop – with at most 4 blocks.
when green flag clicked
move (10) steps
await run(3)
expect(sprite("Robo").x >= 150, "Robo should walk at least 150 steps to the right.")
expect(blocks.uses("control_repeat"), "Use a repeat loop.")
expect(blocks.count() <= 4, "Can you do it with at most 4 blocks?")@Scratch.check(level1)
These commands are available in a check (German names in brackets):
| Command | Meaning |
|---|---|
await run(s) (lauf) |
starts the project and waits at most s seconds |
expect(condition, text) (erwarte) |
reports text if the condition is not met |
sprite(name) (figur) |
state of a sprite: x, y, direction, size, costume, visible, says, variable(name), list(name) |
stage (buehne) |
state of the stage: backdrop, variable(name), list(name) |
blocks.count() (bloecke.anzahl()) |
number of blocks in the project |
blocks.count(opcode) (bloecke.anzahl()) |
how often the project uses this block |
blocks.uses(opcode) (bloecke.nutzt()) |
does the project use this block? |
blocks.fields(opcode, field) (bloecke.felder()) |
values of a field in all these blocks, e.g. blocks.fields("event_whenkeypressed", "KEY_OPTION") → ["right arrow", "left arrow"] |
blocks.of(name) (bloecke.von()) |
the same queries, only for the blocks of one sprite (or "Stage") |
blocks.scripts() (bloecke.skripte()) |
every script as a list of block names in running order, e.g. ["event_whenflagclicked", "looks_say", "control_wait", "looks_say"] |
Block queries only count blocks that are part of a script, i.e. hang below a
hat block such as when green flag clicked. Loose blocks lying next to a
script do not count.
The names of the blocks (control_repeat, motion_movesteps …) can be found
in the Scratch Wiki.
--{{0}}--
If the four levels are not enough, you can define your own profiles in the header of your course.
A profile extends one of the levels. The list blocks defines which blocks
are allowed; maxBlocks limits the number of blocks.
<!--
import: https://raw.githubusercontent.com/LiaTemplates/ScratchBlocks/0.4.0/README.md
@onload
;(window.LiaScratchSetup = window.LiaScratchSetup || []).push(function (scratch) {
scratch.defineProfile("maze", {
base: "level1",
blocks: ["event_whenflagclicked", "motion_movesteps", "motion_turnright"],
maxBlocks: 5
})
})
@end
-->Use it with @Scratch.profile(maze).
| Option | Meaning |
|---|---|
base |
level the profile builds on |
blocks |
allowed blocks (opcodes) or "all" |
exclude |
blocks to remove |
zoom |
block size (level 1: 1.1, level 4: 0.675) |
sprites |
may sprites be added? |
textView |
show the Text button |
sb3 |
buttons to load and save .sb3 |
speech |
read blocks aloud, and the result of a check (the first hint) |
maxBlocks |
at most this many blocks (0 = unlimited) |
resetOnRun |
put sprites back to their start state on ▶ |
dragSprites |
false: only sprites with draggable: yes can be moved on the stage (keeps start positions fixed in tasks) |
flag |
false: hide the green flag and stop sign above the stage (default: shown) |
--{{0}}--
The template brings a small library of its own: these sprites, backdrops and sounds are part of the template, so they also work offline. Your course can add more, see the next section.
| Name | Type |
|---|---|
robo-a |
costume |
robo-b |
costume |
white |
backdrop |
pop |
sound |
beep |
sound |
All of them were made for this template and are in the public domain (CC0). The Scratch Cat is deliberately not used, it is a trademark of the Scratch Foundation.
--{{0}}--
Your course can bring its own images and sounds. Register them once in the header of your course, then use them by name, just like the built-in ones.
Every asset gets a short name (its key). defineSprite combines costumes and
sounds into a sprite: a new sprite with this name starts with them.
<!--
import: https://raw.githubusercontent.com/LiaTemplates/ScratchBlocks/0.4.0/README.md
@onload
;(window.LiaScratchSetup = window.LiaScratchSetup || []).push(function (scratch) {
scratch.defineAsset("jungle", {
type: "backdrop",
url: "https://raw.githubusercontent.com/your-name/your-course/main/assets/jungle.png"
})
scratch.defineAsset("crystal", {
type: "costume",
url: "https://raw.githubusercontent.com/your-name/your-course/main/assets/crystal.svg",
rotationCenterX: 20,
rotationCenterY: 20
})
scratch.defineAsset("chime", {
type: "sound",
url: "https://raw.githubusercontent.com/your-name/your-course/main/assets/chime.mp3"
})
scratch.defineSprite("crystal", {
name: "Crystal",
costumes: ["crystal"],
sounds: ["chime"]
})
})
@end
-->In the code block:
[Stage]
backdrops: jungle, white*
[Sprite Crystal]
x: 100
when this sprite clicked
play sound [chime v]
switch backdrop to [jungle v]
| Option | Meaning |
|---|---|
type |
"costume", "backdrop" or "sound" |
url |
address of the file: https://…, relative to the course, or a data: URL |
svg |
the SVG image itself as text, instead of url |
format |
"svg", "png", "jpg", "wav" or "mp3" – only needed if it cannot be detected from the file |
rotationCenterX, rotationCenterY |
rotation centre in pixels of the image; default: its centre |
bitmapResolution |
2 for PNG/JPG images drawn at double resolution (like Scratch's own) |
defineSprite(key, { name, costumes, sounds }) registers a sprite: a sprite
section [Sprite Crystal] (its name or its key) without costumes: starts with
these costumes and sounds. Without name, the key is the name of the sprite.
Notes:
- The key is also the name of the costume in Scratch and in
checks:
sprite("Crystal").costume == "crystal". It may contain letters, digits,_and-. The built-in names (robo-a,white,pop…) cannot be redefined. - Prefer absolute URLs, e.g. of files in the GitHub repository of your course. The server must allow loading from other pages (CORS), GitHub does. Relative URLs are resolved against the README of the course, as far as the page reveals it.
- In PNG and JPG images, one image pixel is one pixel on the stage (480 × 360).
Backdrops of at least 960 pixels width count as double resolution, so a
960 × 720 backdrop fills the stage. For sharp costumes, draw them twice as
large and set
bitmapResolution: 2. GIF and WebP are converted to PNG. - The course's
@onloadcan run before this template is loaded, sowindow.LiaScratchmay not exist yet. That is why the definitions are pushed intowindow.LiaScratchSetup: the template runs them as soon as it is loaded, before the first code block starts. Once it is loaded, a push runs immediately. The same works fordefineProfile; a code block with a profile that is not defined yet waits up to 3 seconds for it. - Assets are loaded in the background; code blocks wait for them. If a name is unknown or a file could not be loaded, the code block shows it with its line number.
--{{0}}--
This slide registers a costume itself, with a script right above the code
block. In your course, defineAsset belongs into @onload in the header.
<script run-once modify="false">
(function define() {
// on a direct link to this slide, the template may still be loading
if (!window.LiaScratch) { setTimeout(define, 100); return }
window.LiaScratch.defineAsset("star", {
type: "costume",
svg: '<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60">…</svg>'
})
})()
</script>[Sprite Robo]
costumes: robo-a, star
when green flag clicked
repeat (8)
next costume
turn right (45) degrees
wait (0.3) seconds
end
@Scratch
The template is an npm project. The sources are in src/, Parcel bundles them
into dist/index.js.
npm install # install dependencies (patches scratch-vm for Parcel)
npm run build # create dist/index.js
npm test # tests for the text format (all blocks, all languages)
npm run typecheck # check TypeScript
npm run gen # regenerate src/format/specs.json and src/locales.json
npm run serve # open this course locally with live reloadStructure of src/:
| File | Purpose |
|---|---|
element.ts |
<lia-scratch>: interface, ▶/⏹, synchronization |
bridge.ts |
connection to the LiaScript code block (read, write, observe ACE) |
textdiff.ts |
small edits instead of rewriting the text, merging with a classroom |
project.ts |
text ⇄ VM, start state of the sprites |
format/scratchtext.ts |
readable text format (scratchblocks notation) |
format/language.ts |
everything language-dependent in the text format |
format/json.ts |
compact project.json |
format/specs.json |
table of all blocks and menus, generated from scratch-blocks |
locales.json |
UI texts and keywords of all languages, generated from scratch-l10n |
i18n.ts |
language of the course, UI texts |
workspace.ts |
scratch-blocks workspace, toolbox per profile |
stage.ts |
stage: mouse, keyboard, dragging sprites, "ask and wait" |
profiles.ts |
levels 1–4 and custom profiles |
assets/library.ts |
built-in costumes, backdrops, sounds and sprites |
assets/registry.ts |
own assets of a course (defineAsset, defineSprite) |
check.ts |
commands for checks |
dom-guard.ts |
keeps foreign nodes out of <body> (see below) |
vendor/scratch-gui/ |
glue code from scratch-gui 15.1.1 (AGPL-3.0) |
Notes:
- LiaScript manages the children of
<body>by their index. Blockly, scratch-render-fonts and scratch-vm add nodes of their own there, which breaks LiaScript's rendering.dom-guard.tsmoves them to<head>or into a container next to<body>right away. - The run controls and versions of LiaScript are shown below the Scratch
interface. Both only swap their visual places (
position: relative), no node of LiaScript is moved. - scratch-blocks loads the icons of the blocks (green flag, arrows) by URL. By
default a fixed version on jsDelivr is used. For offline use, set
window.LiaScratchMediain@onloadto your own copy of the foldernode_modules/scratch-blocks/media/. dist/index.jsis about 11 MB (4 MB compressed), most of it scratch-vm.
The macros in the header of this file:
@Scratch: @Scratch._run(@uid,level4)
@Scratch.level1: @Scratch._run(@uid,level1)
@Scratch.level2: @Scratch._run(@uid,level2)
@Scratch.level3: @Scratch._run(@uid,level3)
@Scratch.level4: @Scratch._run(@uid,level4)
@Scratch.profile: @Scratch._run(@uid,@0)
@Scratch.check: @Scratch._check(@uid,@0)
@Scratch._run
<script>
window.LiaScratch.run("@0", send, "@'input", "@1")
</script>
<lia-scratch id="@0" profile="@1"></lia-scratch>
@end
@Scratch._check
<script>
window.LiaScratch.check("@0", send, "@'input(0)", "@1", async function (api) {
const { run, expect, sprite, stage, blocks, lauf, erwarte, figur, buehne, bloecke } = api
@input(1)
})
</script>
<lia-scratch id="@0" profile="@1" check></lia-scratch>
@endThe element <lia-scratch> finds the code block right before it, hides its
editor and keeps blocks, stage and text in sync. New versions are created by
LiaScript itself as soon as ▶ is pressed.
License: AGPL-3.0, like the Scratch components it is built on. Courses that import this template can be licensed freely. The licenses of all bundled components and the Scratch trademark notice are listed in NOTICE.