Scratch Specification
A detailed explanation of how Scratch 3.0 works as a programming language.
WARNING
This page is experimental and might not render or work properly. It is intended to be a centralized version of the spec for those who may prefer it. You can view it properly through the home page.
Introduction
This document is a serious attempt to create a programming language specification of Scratch 3.0. It will detail the exact behavior of Scratch so that it can be accurately reproducible from this document alone, preserving its behavior and aiding in ports of it to other platforms. This project is entirely "for fun" (note the quotation marks) and is not affilated with the Scratch Foundation or related parties in any way whatsoever, though please donate to them if you can so that they may continue to support and improve Scratch for all.
Preliminaries
Before reading this specification:
- Be sure to have an understanding of computer science. A good vocabulary, knowledge, and understanding of computational concepts is useful.
- Being experienced with working in Scratch is immensely helpful. Although this specification will try to explain it in full, knowing the basic concepts and quirks of Scratch just by experience will let you skim through this document easily, as not all of it is necessary to read; just to reference for accuracy.
- Scratch 3.0 is built upon the modern web; although not entirely necessary, a basic knowledge of JavaScript can come in handy when it comes to understanding the inner workings, logic, and rules of Scratch, as it is what Scratch runs on. Scratch does a lot of things the same way JavaScript does.
- Be familiar with the scratchblocks syntax. This text-based format is used to represent Scratch blocks. Although the blocks currently render while reading in a web browser, it is still good to know how to interpret them textually, especially if block rendering support is somehow unavailable, e.g. when viewing the source Markdown files directly.
Sources
The information about Scratch in this specification is, of course, derived from Scratch sources, e.g. the Scratch VM, Wiki, Website, Editor, and Discussion Forums. Wikipedia and MDN Web Docs are linked to as well for additional information regarding general concepts and internal behaviors.
Contributing
Please contribute on GitHub (must be 13 or older, need a GitHub account) or comment on my Scratch profile (just need a Scratch account) if you can:
- Summarize key points of sections (things can get ridiculously wordy at times)
- Provide insight into the workings of Scratch (know info that should be here)
- Fact check info to verify accuracy (add links to projects, code, wiki, forums)
- Make sure everything looks good (correct formatting, spelling, grammar)
- Give some ideas, motivation, or feedback for improving this specification
See the TODO list for ways you can help!
FAQ
Questions that would be frequently asked if someone were to ask them.
WARNING
This specification is a work-in-progress and is probably not very helpful or accurate at the moment. However, progress is being made, little by little! Just be sure to take what it says with a grain of salt. Most of it has been written without much research, and it will be fact-checked and made more accurate in the future. How it should best present and explain information is still being figured out as well. It will just take a little experimenting before it gets to be a solid resource. Thank you for understanding!
Where to start?
- If you want a general understanding of Scratch's inner workings for whatever reason, find what interests you in the sidebar to the left. Use the search tool up at the top to find something specific. You can simply gloss over anything else you don't want to read.
- If you want formal definitions for basic Scratch terms, see Ideas.
- If you want to understand specific block behaviors, see Palette.
- If you want to know more on removed blocks, see Obsolete Blocks.
- If you want to know more on blocks from mods, see Nonstandard Blocks.
- If you want to know how scripts run, see Runtime.
- If you want to learn about the file format used for saving Scratch projects, see File Format.
- If you want an in-depth explanation of how Scratch receives input, renders graphics, and plays sounds, see Input / Output.
- If you want to understand how Scratch handles cloud variables and other web requests, see Networking.
- If you want a deep dive into Scratch Link and Scratch-to-hardware connectivity, see Devices.
What can Scratch do?
Although simplistic in nature, Scratch has many complex and useful features built-in.
At its core, Scratch can:
- Change values in a runtime
- Run scripts single-threaded
- Play sounds using speakers
- Show images and graphics
Also, in a fully functional environment, Scratch can access:
- A keyboard (detect keys the user presses)
- A mouse (read its position and button state)
- A microphone (gauge surrounding loudness)
- A clock (get local and UTC time in milliseconds)
- Wi-Fi (make network requests to external servers)
- Bluetooth (connect to supported hardware)
- A webcam (sense motion in a direction)
This specification aims to document everything that Scratch does as a programming language, which is actually... a lot!
What's the point?
This specification exists to document the behavior of Scratch 3.0 as a programming language. It can open the door to:
- Accurately porting Scratch to run natively on other platforms.
- It could help efforts to make Scratch available on platforms that aren't web-based (if any).
- @OceanIsEndless, the initial creator of this specification, has a lot of wild ideas on their mind regarding Scratch. Their ideas are likely not at all worth their time, but writing this spec will allow them to try doing interesting things such as creating a Scratch to Desmos packager, or porting Scratch to the Wii. A bit ambitious, yes, and absolutely crazy—but a specification like this could aid projects like these and more. It can help ensure compatibility and easy coding.
- It could theoretically help this super cool rapidly-developing all-in-one Scratch port to other platforms, though the spec may not be done before contributors over there figure out how Scratch works for themselves anyway. 😃
- Recreating parts of Scratch (blocks, scripts) for demonstration.
- For educational reasons, one might want to recreate the behavior of certain parts of Scratch without the full force of the Scratch editor on hand. This spec will eventually provide information ranging from exact block behaviors to full-on runtime execution, making understanding the way each part of Scratch works simple.
- Improving Scratch in the future while keeping it 100% compatible.
- It isn't known if this spec will reach a state that the developers of Scratch could use as reference, but if so, it could help ensure that Scratch projects remain functionally the same after code rewrites.
- Directly citing the workings of Scratch without linking wikis or code.
- Although the Scratch Wiki and code of Scratch work well for showing Scratch concepts and runtime behavior, one of them tends to abstract away particular functionalities while the other offers thousands of lines of pure JavaScript. This specification is meant to serve as one clear and concise document explaining the behaviors, blocks, and quirks of Scratch 3.0 in all its blocky glory.
- Reimplementing Scratch 3.0 in case of catastrophe.
- This kind of blends together all of the previous points. If the Scratch editor were to magically disappear or break entirely (it won't, but in theory), then the Scratch Wiki could guide you in making a fairly accurate reimplementation of Scratch, but would fall short in exactly reproducing the runtime behavior, procedures, and quirks of Scratch, from scratch (literally). Although the wiki strives to be all-encompassing (and it is indeed very far-reaching), a document solely dedicated to the functionality of Scratch will help preserve its literal, programmatic behavior in one organized doc.
- "Real" programming languages have them.
- Scratch is cool. It is Turing-complete. Lots of languages far less significant than Scratch have programming language specifications. And yet Scratch lacks one. The Scratch Wiki helps document the ideas of Scratch, but a singular document dedicated to specifying exactly all that Scratch does could help it secure official programming language status.
- Who knows what?
- If this spec is made reliable enough, it could be cited (or at least, the underlying sources that it will eventually reference for verifability) in the underdeveloped Wikipedia page about Scratch as a programming language.
It could be argued that this specification is reinventing the wheel in some ways. However, if it is ever completed, it could serve as a great resource for Scratch 3.0.
Why?
Why not?
TODO
This spec is a work in progress; it's nowhere near complete. Please contribute if you can! Anywhere that says TODO is something that needs to be worked on, as well as any sections that are empty or missing.
TODO: Cleanup
Various things need to be worked on to make this a good resource:
- ⚠️ ‼️ Cite reliable sources. ‼️ ⚠️ This specification should eventually provide references to the code of Scratch itself (not just wikis) to prove its claims and be an accurate source of information about the Scratch programming language. As it is in early stages with little to no actual research done, misleading or inaccurate information is sometimes presented (pointed out in issues #4, #6, and #7). It should also be made clear to others that this spec is more of an early draft and the content it hopes to cover has not been extensively investigated yet.
- Decide on formatting and structure guidelines. Currently, the rules of how this spec is to be formatted are not well defined, and the rules should probably be rewritten and refined to help provide more organized and comprehensive documentation (e.g. when to use links between sections, what terms to use in reference to Scratch ideas, how to best cite sources, what qualifies as a section, etc).
- Cleanup excessive linking and wordiness. Links to headings should only be applied if they offer further context about a section and have not been previously or recently linked to in said section. Additionally, this specification should explain everything about Scratch with no extra wordiness or fluff. Unfortunately, @OceanIsEndless has a strong tendency to do both of these. It is unclear what the spec's structure should be as well, and there may be too many or too little sections.
TODO: Blocks
This specification should eventually document every block ever! (A bit hopeful, but certainly possible, and most definitely necessary for Scratch 3.0 to be 100% functionally recreatable from this document.)
Below is a list of blocks that have been or still need to be documented here. (Fully specified blocks are crossed off.) Specifying standard blocks is the first priority. Once they are documented, the scope of this spec can be expanded to include hidden, obsolete, and even nonstandard blocks as well, probably in that order.
Click to view block list
Motion Blocks
- Standard
move () steps
turn cw () degrees
turn ccw () degrees
go to ( v)
go to x: () y: ()
glide () secs to ( v)
glide () secs to x: () y: ()
point in direction ()
point towards ( v)
change x by ()
set x to ()
change y by ()
set y to ()
if on edge, bounce
set rotation style [ v]
(x position)
(y position)
(direction)
- Hidden (specify what they do, even if nothing at all)
scroll right ()
scroll up ()
align scene [ v]
(x scroll)
(y scroll)
- Obsolete (imagine what they would do if kept operational)
scroll right ()
scroll up ()
align scene [ v]
(x scroll)
(y scroll)
- Nonstandard (blocks that mods of Scratch added)
- PenguinMod
move [ v] () steps
change by x: () y: ()
point towards x: () y: ()
turn around
if touching ( v), bounce
set rotation style [look at | up-down v]
move to stage [ v]
- Unsandboxed
(rotation style)
- PenguinMod
Etcetera... More will be written in time.
Concepts
This section explains the ideas, values, limits, and logic of Scratch.
Ideas
The following ideas are foundational to Scratch and referenced throughout this specification:
Asset
Costume
A costume is an image file and a type of asset that can be graphically rendered to represent a target. It can be identified by its name or number. Costumes can either be bitmap or vector.
Sound
A sound is an audio file and a type of asset that can be audibly played to the user via blocks. It can be identified by its name.
Block
This will have to be better explained and added to the nonexistent section for script execution.
The fundamental component of Scratch as a programming language. In fact, it is similar to a function call in other programming languages. Every block:
- Accepts values or blocks as arguments
- Has a specific pre-defined operation that it performs
- Can be run and reports (i.e. outputs, returns) a single value (or none at all)
Blocks can be run, meaning that its operation is performed using the arguments it is given and the value resulting from the operation is reported, if any. When put together, blocks create scripts.
Standard Blocks
Blocks that exist in Scratch 3.0. Generally, standard blocks are supported, meaning they are being actively maintained and probably will not be removed from Scratch in the future. They are the most commonly used blocks in scripts. All of them are documented in a dedicated section.
Hidden Blocks
Standard blocks that exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally. Some are functional, some are not. Scripts may use them on occasion, but they are found less often than other standard blocks due to their obscurity. In the future they may be removed from Scratch entirely, and their consistent behavior or stability is not guranteed.
Clone
TODO: Research... 🤔🤔🤔
An independent, temporary copy created of a sprite that retains all of the original sprite's scripts, variables, lists, costumes, and sounds. It exists on its own entirely separate of the original sprite, so the scripts it runs only affect itself. Unlike sprites, it does not have a name, is not saved in project files, and can be deleted with blocks.
Since it does not have a name, it cannot be directly referenced via existing blocks (e.g. you cannot tell another sprite to glide to it). They are deleted when the runtime stops, and can also be deleted manually using the delete this clone
block.
Clones can be created with the create clone block so long as the maximum number of clones has not been reached. Code can be written specifically for the clones of a sprite via the use of the when I start as a clone block. The stage is the only target which cannot be cloned, whereas both sprites and clones can themselves be cloned.
Edge
The usefulness of defining "Edge" is up for debate. It may be best left to the section about fencing. Feel free to offer insight!
A boundary around the viewing area of the stage that restricts the costume of a sprite from going off-screen.
Flag
The usefulness of defining "Flag" is up for debate. Feel free to offer insight!
The button that is clicked to start a project. It is also known as the green flag. In simple terms, it makes the project Go
. When clicked, it runs any scripts placed under when flag clicked blocks.
JavaScript
Definitions for general terms indirectly related to Scratch may be put into their own section instead, however this is up for debate. Feel free to offer insight!
The programming language that Scratch 3.0 runs in. The logic it uses is largely similar to the logic Scratch uses due to Scratch's dependence on JavaScript for performing operations and manipulating values. In fact, this is where the type of value undefined is taken from; it is a type of value in JavaScript for representing what is not defined or known. Thanks to the quirks of Scratch and no-op hidden reporter blocks, we can obtain this type of value.
List
A series of items stored together in sequence. Each item is referenced by its numerical index (aka item #), a positive integer ranging from 1
to the length of the list (inclusive). Lists can be empty, meaning that they have a length of 0
and contain no items. There is also a maximum number of items that a list can hold, aka a limit to its length.
Mod
A modification (altered version) of the Scratch 3.0 runtime that is nonstandard and may introduce new blocks, features, or changes not present in standard Scratch. The majority of this spec will be documenting standard Scratch behavior. For information on nonstandard blocks and behaviors in mods, see Nonstandard Blocks.
Project
A stage and optionally some sprites packaged together to do something. They can be loaded into a runtime and executed. They can also be saved as project files.
Runtime
The environment in which a project is run. It keeps track of the project's current state and executes its code. Projects files can be loaded into and saved from runtimes.
Script
A set of blocks put together to create code. Here is an example of a script:
Blocks are put together in the following ways:
- TODO 😄
Sprite
A kind of target that can exist on its own, have variables only it can set, and be moved, pointed, scaled, and hidden, all of which are things that the stage cannot do.
Stage
A special target, with one and only one existing in every project that is always shown behind all sprites. It is sort of like the global scope found in some programming languages, but it also exists as its own entity.
Unlike sprites, it cannot be moved, pointed, scaled, hidden, or have variables that only it can set. However, it can do everything else a sprite can.
Target
An object that runs blocks, shows images, and plays sounds. It has its own variables and scripts to perform operations. It can take the form of either a sprite or the stage.
A target exists as its own independent unit. However, targets can interact with each other in some ways, e.g. via messages.
User
The individual who is interacting with the project and provides input. They may optionally have a username that the project can use to identify them.
Variable
A named container belonging to a target that holds exactly one value and is interacted with via blocks. The following operations are often performed with variables:
- Get: Read the current value of the variable.
- Set: Modify the current value of the variable.
Some variables are created on a project-by-project basis for general use by scripts. For example, a (score)
variable can be created to keep track of an arbitrary point value. Others are directly built into the runtime and cannot be deleted. For example, the (x position)
variable always exists in every sprite to set its rendered horizontal position.
General purpose variables can be interacted with using variables blocks. Runtime variables have their own dedicated blocks instead and are usually limited or sandboxed in some way, unlike general purpose variables.
Values
Values are data stored in the runtime that can be interacted with and manipulated by blocks. In Scratch, the following types of values exist:
There are lots of terms used to refer to these types of values and particular subsets of them. They are referenced throughout this specification and explained below:
Value
A general value. This can be a string, number, boolean, or in rare cases undefined. Variables can hold individual values, and a list can store many of them as items.
Angle
A number intended to be in degrees. [sin v] of ()
, [cos v] of ()
, and [tan v] of ()
expect angles as input.
Answer
A string provided to the project by the user as input via the ask and wait block.
Boolean
A special type of value used to represent the result of a logical operation. It is always either true
or false
.
True
A kind of boolean used to represent a yes or an affirmative answer as a result of a logical operation. When casted to a string, it is written as true
. When casted to a number, it is casted to 1
. It is considered truthy, as it is itself the definition of truthy.
False
A kind of boolean used to represent a no or a negative answer as a result of a logical operation. When casted to a string, it is written as false
. When casted to a number, it is casted to 0
. It is considered falsy, as it is itself the definition of falsy.
Direction
An angle determining how a sprite is pointed on the screen. It is always wrapped to remain in the range -179 and 181 (exclusive). An angle
Or in scratchblocks:
The way a sprite's direction impacts how it is rendered is determined by its rotation style.
Integer
A whole number, or a number that is not a fraction (e.g. 42
, -37
). Many blocks report integers (e.g. round ()
, costume [number v]
, loudness
, item # of () in [list v]
) and expect integers (e.g. item () of [list v]
), just to name a few.
Item
Key
A name used by Scratch for referring to a key on the user's keyboard. Specific keys are referred to by name. To refer to any arbitrary key (as in, "press any key to continue"), the name any
can be used.
It is good to note that Scratch does not standardly support special keys other than the ones listed below, making it more versatile across platforms (i.e. it won't conflict with keyboard shortcuts used by other applications running on the user's computer).
Keyboard Key | Key Name (string) |
---|---|
⌨️ (any key) | any |
space bar | space |
↑ arrow | up arrow |
↓ arrow | down arrow |
→ arrow | right arrow |
← arrow | left arrow |
Return ↵ | enter |
A, B, ...Z (alphabet keys) | a , b , ...z (the lowercase letter) |
1, 2, ...0 (number keys) | 1 , 2 , ...0 (the numerical digit) |
Other keys | The label of the key or the letter it makes when typed as text |
TODO: Document all keys and figure out exactly what keys Scratch does and doesn't support and how it handles unlisted keys)
Length
A positive integer representing how many letters or items there are in a string or list, respectively.
Letter
An individual UTF-16 code unit. Several joined together create a string. In Scratch, letters cannot be directly interacted with per se; getting a letter from a string just reports another string containing only that letter.
Name
A string with the intention of identifying something. This can be applied to a great number of things, but is usually used in regards to a variable, list, costume, sound, user, or sprite.
Number
A numerical value. Most numbers are real and can be positive (+
), negative (-
), whole (#
), or fractional (#.#
). In JavaScript, these numbers are internally stored as double-precision 64-bit binary format IEEE 754 values. Thus, Scratch follows largely the same rules JavaScript does when operating on numbers, though with exceptions. In addition to real numbers, special kinds of numbers exist too, which are for situations that cannot be fully expressed with real numbers.
Infinity
A special number that is always greater than any other number. When casted to a string, it is written as Infinity
. It is created when the result of a mathematical operation is too large to be represented as a real number.
-Infinity
A special number that is always lower than any other number. When casted to a string, it is written as -Infinity
. It is created in the same manner as Infinity.
Whether -Infinity
or Infinity
is produced by an operation is determined in the same way that a real number would be negative or not. For example, (1) / (n)
produces a positive number, while (-1) / (n)
produces a negative number. In the same manner, (1) / (0)
produces positive infinity, while (-1) / (0)
produces negative infinity.
NaN
A special number that is literally not a number. When casted to a string, it is written as NaN
. It is created by doing unknown or unrepresentable things with numbers, such as multiplying Infinity
by 0
, adding Infinity
to -Infinity
, or getting the square root of a negative number. Unlike Infinity, it does not have a negative counterpart. It is interpreted as a 0
when passed as input to other mathematical operations, unlike in JavaScript where it causes most operations to report NaN
.
Opcode
A name that identifies the operation a block performs when run. For example, the opcode of the move () steps
block is motion_movesteps
, and when run it moves the sprite by the given number of steps, as named.
Rotation Style
A string that determines how a sprite's direction impacts the way it is visibly rotated when rendered. Officially, it can only be one of the following strings: all around
, left-right
, or don't rotate
.
all around
: The sprite faces in its direction clockwise. At0
, it faces up; at90
, it faces right; at180
, it faces down; and at-90
, it faces left.left-right
: If the sprite's direction is less than0
, it faces left (-90
). Otherwise, it faces right (90
).don't rotate
: The sprite always faces right (90
).
The following table describes a sprite's rendered direction when using different rotation styles. (Its actual direction value remains the same; only the way it looks like it's pointed changes.)
Direction | All Around | Left-Right | Don't Rotate |
---|---|---|---|
0 | 0 (up) | 90 (right) | 90 (right) |
45 | 45 (up-right) | 90 (right) | 90 (right) |
90 | 90 (right) | 90 (right) | 90 (right) |
135 | 135 (down-right) | 90 (right) | 90 (right) |
180 | 180 (down) | 90 (right) | 90 (right) |
-135 | -135 (down-left) | -90 (left) | 90 (right) |
-90 | -90 (left) | -90 (left) | 90 (right) |
-45 | -45 (up-left) | -90 (left) | 90 (right) |
All Around
Left-Right
Don't Rotate
String
A type of value consisting of a series (i.e. string) of letters, also known as text. All strings are considered truthy except for the empty string, the string 0
, and the string false
(case-insensitive), which are considered falsy.
Empty String
A string containing no letters. It has a length of 0
and is one of the only strings considered falsy. Also known as a "null string," it is typically used in place of a value where there is none, e.g. getting an item from a list when it does not exist, or getting the answer provided by a user when they have not been asked anything yet.
Undefined
A special value that represents nothing. When converted to a string, it is written as undefined
. This type of value is uncommon but can be produced by hidden reporter blocks. In most cases, however, Scratch uses 0
or an empty string to represent nothing.
Username
A name used to reference a user. In standard Scratch, usernames:
- Are always 3 to 20 letters long (inclusive)
- Can only contain the following symbols:
- Uppercase Latin letters (A-Z)
- Lowercase Latin letters (a-z)
- Numerical digits (0-9)
- Underscores (_)
- Hyphens (-)
Also, official ("real") usernames are registered with the Scratch website. They are unique (different from each other) and are case-insensitive, meaning that if a username "Endless-Ocean" is registered, there cannot also be an "endless-ocean" or "EndlEss-ocEan", though there can also be an "endless_ocean", "Endless--Ocean", and "Endless-Ocean1" if not already registered.
Official usernames can only be changed under extraordinarily rare circumstances (e.g. the username contained sensitive information about the user that the Scratch team decided to change for them), meaning that once it is created, it usually cannot be altered later.
Scripts can detect the current user's username via the (username
) block. If the user is signed in, the block reports their username. If the user is signed out, the block reports an empty string. In the official Scratch editor, the username reported by the username block should remain constant for the entire run of the project.
The only exception to this rule in official contexts is when the user does the following steps in sequence:
- Uses the official Scratch website
- The user cannot sign into their account from the offline editor
- Loads a shared project while signed out of their account
- This does not work with an unshared project because the user cannot view it while signed out
- Signs in to their account from the same window while the project is open
- A menu exists for the user to sign in to their account without reloading the page
Then the reported username is changed from the empty string to the username that the user signed in with, without reloading the project. After this happens, the user cannot change their username again without reloading the project or modifying the runtime directly, e.g. via developer tools.
Due to the aforementioned limitations of real usernames, project can technically check if the user's username is "real" or not by:
- Crossreferencing it with a list of known usernames (or making a request to the Scratch API using cloud variables and an external service such as scratchattach) to see if it is registered with the Scratch website
- Remembering the usernames that the username block has reported (e.g. via cloud variables) to see if it encounters the same username with different casing
- Checking if the username is changed while the project is running (impossible through normal means unless the user is signing in after being signed out)
A project could potentially utilize any of these ways to detect if it is actually being run in the official Scratch environment or an unofficial version of it.
Thus, for a truly accurate recreation of Scratch, the (username)
block should only report registered usernames with the Scratch website, and a project which remembers usernames (e.g. via cloud variables) should never encounter the same username it has seen before with different casing, except in extraordinarily rare cases where the casing of a user's username was officially changed by the Scratch team, which is not known to have happened ever. The username should also not be changed while the project is running; the moment the project is started, whatever username the username block reports will be the username for the entire duration of time for which it runs, unless the user was signed out when the project began and signs in while the project is running.
In most cases, however, projects will probably not notice anything wrong with the username (but a few niche ones could break), so long as it only contains valid characters (A-Z, a-z, 0-9, _, -) and is between 3-20 letters in length, as previously stated. In general, usernames are really just any arbitrary string that identifies a user.
X Position
A number representing a horizontal position on the Scratch coordinate plane. All sprites have one.
TODO: document coordinate system
Y Position
A number representing a vertical position on the Scratch coordinate plane. All sprites have one.
TODO: document coordinate system
Other Values
Inclusion of this section is up for debate. Feel free to offer insight!
Other kinds values can potentially exist in modified or bugged versions of Scratch. This is because Scratch is built on JavaScript, and although it is highly unlikely for a project to work with any type of value other than the ones listed above, there is always the potential for other JavaScript primitives to be glitched into the project, e.g. by setting the value via developer tools, or some wider unknown issue.
They will not be specified in this specification as of yet (since they cannot be obtained through official means), but other values that could potentially be encountered in the rarest of cases are:
null
: A special value representing nothing. Distinct from undefined in that it is meant to explicitly be nothing, whereas undefined exists for representing unknown behavior or values.- The writers of this specification do not know if
null
can be produced by existing blocks without modification.- If it is found to be an obtainable value, it may be documented further. Otherwise, it will not be, and is likely not necessary for inclusion in a reimplementation of Scratch.
- This value can be casted to other data types. (
null
was obtained via "custom extensions" in a modification of Scratch that still has largely the same behaviors as standard Scratch to see how it would behave if somehow obtained.)
- The writers of this specification do not know if
Limits
These constant values will show up a lot throughout this specification. They can be changed to one's liking, however for true accuracy to Scratch, they should all have their "Standard Scratch:" values. Alternative values are provided as well.
Stage Bounds
Stage Width
The horizontal size of the stage. This is an arbitrary positive integer.
Standard Scratch: 480
Widescreen: 640
Stage Height
The vertical size of the stage. This is an arbitrary positive integer.
Standard Scratch: 360
TODO: Explain edges, and provide key distinctions between the Stage and the graphics window?
Left Edge
The horizontal position of the left edge. This is derived from the stage width.
Formula: stage width / -2
Standard Scratch: -240
Right Edge
The horizontal position of the right edge. This is derived from the stage width.
Formula: stage width / 2
Standard Scratch: 240
Top Edge
The vertical position of the top edge. This is derived from the stage height.
Formula: stage height / 2
Standard Scratch: 180
Bottom Edge
The vertical position of the bottom edge. This is derived from the stage height.
Formula: stage height / -2
Standard Scratch: -180
Quantities
Max Items
The maximum length of a list, aka the most items that one list can hold. This limit is imposed to prevent excessive memory usage by projects. This is an arbitrary positive integer.
Standard Scratch: 200000
Modified Scratch: None (many Scratch mods do not enforce this limit, though memory overflow may eventually occur)
Max Clones
The maximum number of clones that can exist at a time. If this limit is reached, another clone cannot be created until one is deleted. This limit is imposed to prevent excessive memory usage by projects. This is an arbitrary positive integer.
Standard Scratch: 300
Modified Scratch: None (many Scratch mods do not enforce this limit, though memory overflow may eventually occur)
Logic
Internally, Scratch follows certain rules and steps to perform operations. They are provided here for reference.
Casting
Most blocks automatically convert values between types for use using certain logic, also known as casting. The logic Scratch uses to perform most conversions is specified below.
To String
Scratch uses the following logic to convert any given value to a string:
- If the value is a string:
- Return the value, as it is already a string.
- If the value is a number:
- Follow the logic JavaScript does to cast a number to a string and return it.
- TODO: specify this better
- If the value is NaN, return the string
NaN
. - If the value is Infinity, return the string
Infinity
. - If the value is -Infinity, return the string
-Infinity
.
- Follow the logic JavaScript does to cast a number to a string and return it.
- If the value is a boolean:
- If the value is undefined, return the string
undefined
. - If the value is something else, follow the logic JavaScript has for the
toString
method of that value to convert it to a string and return it. (Likely unnecessary though, as no known "other values" can be encountered.)- If the value is somehow null, return the string
null
. - TODO: Explain this step better or maybe just omit it because this step is not needed
- If the value is somehow null, return the string
To Number
Scratch uses the following logic to convert any given value to a number:
- If the value is NaN, return the number
0
. - If the value is a number, return the value as it is.
- If the value is undefined, return the number
0
. - If the value is true, return the number
1
. - If the value is false, return the number
0
. - If the value is a string or something else:
- If the value can be converted to a number according to these rules, return it.
- Otherwise, return the number
0
. - TODO: specify string -> number coercion better b/c JavaScript logic
To Boolean
Scratch uses the following logic to convert any given value to a boolean:
Falsy
A value is falsy, or casted to false, if the value is:
- an empty string (no letters, length is
0
), - the strings
0
orfalse
(case-insensitive), - one of the numbers
0
,-0
, orNaN
, - undefined,
- null (rare),
- or false.
Truthy
Any value that is not falsy is considered truthy and casted to true.
To Direction
Scratch uses the following logic to convert any given value to a direction:
Plug the casted value into the following equation as
to find : Here is the same equation written in blocks:
Return
( direction
).
Fencing
TODO: This section has an excessive amount of fluff and does not provide any actual information and will have to be rewritten... sometime
In Scratch, whenever the position of a sprite changes, it then fences (aka restricts) the position of the sprite to fit inside of a fence (aka boundary) that is intended to keep it within the viewing area of the stage. Additionally, whenever the size of a sprite changes, it then fences (aka restricts) the size of the sprite to remain reasonably visible and not too large so as to cause rendering problems. This is primarily so that sprites do not randomly disappear due to erroneous code, but it is also an intentional feature of Scratch that does get utilized by some projects.
Scratch uses the following procedures to determine what the position and size of a sprite should be limited to depending on the width and height of its current costume, as well as its direction.
Fencing Position
- TODO 😄
Fencing Size
- TODO ;D
Each fencing procedure is only applied after the position or size of the sprite changes (if the position changes, only the position is fenced; if the size changes, only the size is fenced). Because of this behavior, if one switches the costume to a particularly large or small costume, moves or resizes it, and then switches the costume back without changing the position and size afterward, then the sprite will remain at the same position and size that it had with the large or small costume (since fencing is not applied when switching costumes), allowing projects to circumvent fencing if needed.
Runtime
TODO: Coming soon, probably
At runtime, Scratch projects are executed, or run. The Scratch Virtual Machine is responsible for providing a project with the memory and services needed for it to run. It contains the project in a sandboxed Scratch environment, which makes it possible for projects to run across several platforms. This section serves to explain how projects are interpreted and executed by the Scratch VM, including script and target handling.
Palette
This section aims to document the programmatic behavior of every block in Scratch 3.0.
INFO
This spec is in early stages, and its scope is still being considered. Although this section is primarily meant to document blocks that exist in the official version of Scratch 3.0, the extent to which it should try to document obsolete and nonstandard blocks has not yet been determined. Feel free to offer insight!
The following blocks are being documented here:
- Standard Blocks: All blocks that are supported or exist in Scratch 3.0.
- Nonstandard Blocks: All blocks that are supported or exist in modifications of Scratch 3.0.
- Obsolete Blocks: All blocks that existed in previous versions of Scratch, and how they would probably behave if they were still functional in Scratch 3.0.
Standard Blocks
This section documents each and every block that is available in Scratch 3.0, and its precise functionality.
INFO
How to organize and refer to these blocks is up for debate. Naming headings for blocks by opcode could work (and probably will) but may seem too cryptic. Feel free to offer insight!
Example block
INFO
This is an example section about a block. It does not exist in Scratch.
The heading for a section about a block should be its opcode, as used in the SB3 file format.
Operation:
A brief overview of the block's function and essential info.
Block:
Arguments:
Name: | Casted to: | Provides the: |
---|---|---|
ARG | the kind of value this argument is casted to before use by the block, linking to the procedure used to cast it | What it provides to the block. |
Procedure:
A deep dive into what the block does in fulfilling its operation.
Motion blocks
These blocks relate to motion, or moving sprites. They manipulate the x position, y position, and direction of a sprite in order to position it in the desired manner. Notably, they do not do anything when used from the stage.
Standard motion blocks
These motion blocks are officially supported in Scratch 3.0:
motion_movesteps
Operation:
Moves the sprite forward the given number of pixels in the direction that it is facing. Negative numbers move the sprite backwards.
Block:
Arguments:
Name: | Casted to: | Provides the: |
---|---|---|
STEPS | number | Number of steps (aka pixels) to move. |
Procedure:
The x position of the sprite is changed by the sine of the sprite's direction multiplied by the number of steps to move, and the y position of the sprite is changed by the cosine of the sprite's direction multiplied by the number of steps to move.
This can be expressed as:
Where STEPS
to move,
In scratchblocks, this operation can also be replicated as:
After the sprite is moved, its position is fenced.
Hidden motion blocks
These motion blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Looks blocks
These blocks relate to the looks, or appearance of targets. They manipulate the size, costume, layer, visiblility, and graphic effects of a sprite in order to make it appear a certain way.
Standard looks blocks
These looks blocks are officially supported in Scratch 3.0:
TODO
Hidden looks blocks
These looks blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Sound blocks
These blocks relate to sound, or the playback of audio. They play the sound files that a sprite has access to and manipulate the volume and sound effects of a sprite in order to make it stream sounds however is needed.
TODO
Standard sound blocks
These sound blocks are officially supported in Scratch 3.0:
TODO
Hidden sound blocks
These sound blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Events blocks
These blocks relate to the start of a script. They cause scripts to run in order for the project to do things.
Standard events blocks
These events blocks are officially supported in Scratch 3.0:
TODO
Hidden events blocks
These events blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Control blocks
These blocks relate to the execution of other blocks. They cause scripts to run in more complex ways in order for the project to perform more logical operations.
Standard control blocks
These control blocks are officially supported in Scratch 3.0:
TODO
Hidden control blocks
These control blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Sensing blocks
These blocks relate to sensing, or detecting various values. They can read information that couldn't be determined otherwise in order to make the project more aware of its runtime context.
Standard sensing blocks
These sensing blocks are officially supported in Scratch 3.0:
TODO
sensing_username
Operation:
Reports the username of the user that has loaded the project in the context of the Scratch website.
Block:
Arguments:
None
Procedure:
- If the user is signed into their Scratch account (username known):
- Their username is known, as the user is registered with Scratch and signed into their account.
- Report the user's username.
- If the user is not signed into their account (username unknown):
- Their username is not known, as the user is using Scratch without being signed into an account.
- Report an empty string.
Technically, this block can report any username registered with the Scratch website or the empty string without breaking anything. Although it is meant to report the username of the user who has loaded the project, there is no way for a project to confirm that the reported username is actually theirs.
Hidden sensing blocks
These sensing blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Operators blocks
TODO: Add description
Standard operators blocks
These operators blocks are officially supported in Scratch 3.0:
TODO
Hidden operators blocks
These operators blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Variables blocks
TODO: Add description
Standard variables blocks
These variables blocks are officially supported in Scratch 3.0:
TODO
Hidden variables blocks
These variables blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
List blocks
TODO: Add description
Standard list blocks
These list blocks are officially supported in Scratch 3.0:
TODO
Hidden list blocks
These list blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Custom blocks
TODO: Add description
Standard custom blocks
These custom blocks are officially supported in Scratch 3.0:
TODO
Hidden custom blocks
These custom blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility with projects created in older versions of Scratch or being used internally:
TODO
Special custom blocks
This section may be moved to a relevant section, though it will have to be clarified that these blocks can be loaded into Scratch, they just don't do anything outside of mods.
Usually, when a custom block or parameter is used outside of its definition, it does nothing or returns 0
. However, there are specific custom blocks and parameters that have unique behaviors when used outside of their definitions, specifically in certain Scratch mods.
A strategy that some Scratch mods use to add their own blocks to Scratch without breaking compatibility (making the project not load in standard Scratch) is by adding them as custom blocks without definitions. In normal Scratch, when a custom block does not have a definition, it won't do anything special; however, when the blocks are run in mods of Scratch, they can be coded to have different behaviors. The behaviors of these blocks in standard Scratch and modifications are specified below:
TODO: Specify!!!
Music blocks
TODO: Add description
TODO: Add sections
Pen blocks
TODO: Add description
TODO: Add sections
Video Sensing blocks
TODO: Add description
TODO: Add sections
Text to Speech blocks
TODO: Add description
TODO: Add sections
Translate blocks
TODO: Add description
TODO: Add sections
Makey Makey blocks
TODO: Add description
TODO: Add sections
micro:bit blocks
TODO: Add description
TODO: Add sections
LEGO EV3 blocks
TODO: Add description
TODO: Add sections
BOOST blocks
TODO: Add description
TODO: Add sections
WeDo 2.0 blocks
TODO: Add description
TODO: Add sections
Force and Acceleration blocks
TODO: Add description
TODO: Add sections
CoreEx blocks
These two extension blocks do not do anything and simply existed with the purpose of testing Scratch 3.0's extension system. They can still be used in projects, though they do not do anything useful and the odds of encountering them in the wild (normal Scratch projects) are highly slim.
Standard CoreEx blocks
There are no standard CoreEx blocks, as they were never intended to be used in projects.
Hidden CoreEx blocks
These CoreEx blocks exist in Scratch 3.0 but are not actively supported or used on their own, either being kept for compatibility reasons or being used internally for testing:
TODO
Obsolete Blocks
INFO
This is an interesting idea, but its inclusion is up for debate. Feel free to offer insight!
This section reimagines blocks that were supported in earlier versions of Scratch, but have since been removed from Scratch 3.0 or left in an inoperative state. Its goal is to closely recreate what the functionality of these blocks would have been if they had been kept in Scratch and were supported by Scratch 3.0.
This way, one could theoretically create an implementation of Scratch 3.0 that accurately supports every block from every official Scratch version, though obviously with subtle differences due to changes in behavior between Scratch versions.
Unlike the rest of this specification, the content of this section is more up to the imagination, as it dreams of how obsolete blocks would behave in modern Scratch, and is not actually observing the behavior of these blocks directly (though it should stay as close as possible to the block's original behavior).
Nonstandard Blocks
INFO
This section is not a high priority, as this specification is primarily meant to document standard Scratch. In the future, it is hoped this spec will include other branches of Scratch. This way, the behavior of projects created with them can be officially documented and remain recreatable if needed (e.g. for highly compatible ports of Scratch).
This section serves to document blocks that do not exist at all in Scratch, but have been added unofficially to modifications of Scratch. They are specified here in order to allow projects using these nonstandard blocks to function properly if one were to create a reimplementation of the Scratch VM with supporting these blocks in mind.
This is a dynamic section and may never be able to satisfy any particular standards for completeness. You can help by adding missing blocks with reliable sources (e.g. links to source code).
Example nonstandard block
INFO
This is an example section about a nonstandard block. It does not exist in Scratch or any modifications of it.
Operation:
A brief overview of the block's function and essential info.
Block:
Arguments:
Name: | Casted to: | Provides the: |
---|---|---|
ARG | the kind of value this argument is casted to before use by the block, linking to the procedure used to cast it | What it provides to the block. |
Procedure:
A deep dive into what the block does in fulfilling its operation.
TurboWarp
TurboWarp is a Scratch mod that compiles projects to JavaScript to make them run really fast. It maintains strong compatibility with Scratch, while also supporting a wide range of custom extensions and weird, new blocks.
TODO: Document TurboWarp blocks
TurboWarp blocks
These blocks are "weird, new blocks" specific to TurboWarp. This category of blocks is named after TurboWarp itself.
Last key pressed block
Operation:
Reports the key that was most recently pressed on the keyboard.
Block:
Arguments:
None
Procedure:
When the runtime first starts, no keys have been pressed. If the block is run before any keys are pressed, it reports the empty string. Otherwise, the name of the last key to have been pressed is reported.
Addon blocks
These blocks are added by TurboWarp addons. They are not actually real blocks, but rather special custom blocks without definitions in disguise!
PenguinMod
PenguinMod is a mod of TurboWarp. It supports most TurboWarp extensions and introduces some community-made ones of its own.
TODO: Document PenguinMod blocks
snail-ide
Snail IDE is a mod of PenguinMod. It supports most of PenguinMod's blocks and adds some of its own.
TODO: Document Snail IDE blocks
Unsandboxed
Unsandboxed is a mod of TurboWarp for building games. It is compatible with TurboWarp's blocks and adds some of its own.
TODO: Document Unsandboxed blocks
Adding Platforms
If you know of a Scratch modification that is in use by a decent number of people and has new blocks that should be specified, please contribute information on it! Though if you do, please remember that this a language specification for Scratch's runtime behavior, not a wiki or other online resource. General documentation for modifications are best put elsewhere. To add one, this specification needs:
- An entry for the modification
- Add a section above this one under Nonstandard blocks
- Give a brief description that highlights what it adds to Scratch as a language (must add new blocks and/or alter runtime behavior)
- Specification of its unique blocks
- See Example nonstandard block for details on how to add an entry for a block. Be sure to put the entry under a relevant category, which should then be entered below the relevant platform's section. For example, the
log ()
block in TurboWarp is in the Addon blocks category, which is then under the TurboWarp section, since that is the platform it was added to. - If a mod adds a new block, and a mod is made of that mod (thus inheriting the new block), do not document the block twice. Blocks should be documented under the platform they first appear on. If blocks are shared between platforms, find the section for the one it was initially added to and specify it over there.
- If the same block just so happens to exist on several platforms without any clear origination (or does not work the same way), then it is OK to document them separately, especially if they have identical opcodes but different behavior.
- See Example nonstandard block for details on how to add an entry for a block. Be sure to put the entry under a relevant category, which should then be entered below the relevant platform's section. For example, the
Though please make sure that the platform you wish to add is actually a modification of Scratch 3.0, and not an entirely different application. This spec is for Scratch 3.0 and offshoots of it, but a platform must share near identical base behaviors with Scratch 3.0 to be added here. For example, Snap! was built off of an early version of Scratch, but is now a completely independent first-class block-based language with its own programming paradigm, and is not built with or at all related to Scratch 3.0. Other block-based Scratch-like apps deserve their own spec instead.
File Format
This section will be expanded once other stuff gets documented. For now, runtime behavior is more pressing than file formatting.
Scratch projects can be saved and loaded from a computer as files. Scratch has several project file formats, each with their own complicated structures and loading behaviors. Even with a perfectly accurate runtime environment, a saved project that is not properly loaded may not work as it was intended to, and could very well break! The purpose of this section is to lay out how project files are created and interpeted.
SB3
The .sb3 file format is the standard format for storing Scratch 3.0 projects, the version of Scratch that this specification documents. In reality, it is a renamed .zip file that contains the following files:
project.json
, a .json file storing info.- Various image files used as costumes.
- Various audio files used as sounds.
TODO: Specify!!!
SB2
The .sb2 file format is the standard format for storing Scratch 2.0 projects, the version of Scratch preceding Scratch 3.0, the version that this specification documents.
The standard Scratch 3.0 editor is compatible with .sb2 files. It has a procedure for converting .sb2 files to .sb3 files, which it then loads.
TODO: Specify!!
SB
The .sb file format is the standard format for storing projects from Scratch 1.4 and earlier, which are early versions of Scratch that work drastically different than modern Scratch due to the major changes in between. Unlike .sb2 and .sb3 files, .sb files are stored in binary using a much less human-readable format.
Despite major differences, the standard Scratch 3.0 editor remains compatible with .sb files. It has a procedure for converting .sb files to .sb2 files, which it then converts to .sb3 files and loads.
TODO: Specify!
Input / Output
TODO: Coming soon, probably
Scratch 3.0 is able to receive user input, render graphics, and play sounds. There is some added complexity to how Scratch does these things which will be explained in this section.
Networking
INFO
This section will be expanded in the future, but it remains incomplete for now. Other sections such as Ideas, Runtime, and Palette are a higher priority to write at the moment. However, once started, it does not seem it should be too difficult to complete.
In the meantime, here are some resources that may be useful if one would like to learn more about Scratch's handling of external network connections:
- TurboWarp Cloud Variable Protocol (highly similar to the cloud variable protocol used by Scratch)
fetchWithTimeout
Source Code (function used in official Scratch runtime by certain extensions to make requests to the Internet)
Feel free to offer insight!
When connected to the Internet, the Scratch runtime can interact with external servers to provide support for cloud variables and certain extension blocks.
Scratch Link
INFO
This section will be expanded in the future, but it remains incomplete for now. Other sections such as Ideas, Runtime, and Palette are a higher priority to write at the moment, and writing this section well (such that it provides accurate and useful information) will require lots of research and effort.
In the meantime, here are some resources that may be useful if one would like to learn more about Scratch Link's inner workings and protocols:
Feel free to offer insight!
Scratch 3.0 is able to connect to supported programmable hardware components through the use of an external application called Scratch Link. When installed on a user's device, it interfaces with the Scratch runtime to allow certain hardware extension blocks to connect with and control connected devices. Its protocols and functionality are documented here to provide the full functionality of Scratch as a programming language.