From 0900eaa72c58bef91931d03ebf2fa6bdaf2d47c0 Mon Sep 17 00:00:00 2001 From: Grady Link Date: Fri, 25 Jul 2025 18:22:01 -0700 Subject: [PATCH 1/4] feat: init vitepress --- .gitignore | 4 +- .vitepress/config.mts | 17 + README.md | 1329 -------------------------------- bun.lock | 345 +++++++++ index.md | 1696 +++++++++++++++++++++++++++++++++++++++++ intro.md | 69 ++ package.json | 10 + 7 files changed, 2140 insertions(+), 1330 deletions(-) create mode 100644 .vitepress/config.mts delete mode 100644 README.md create mode 100644 bun.lock create mode 100644 index.md create mode 100644 intro.md create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 496ee2c..a17f774 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -.DS_Store \ No newline at end of file +.DS_Store +.vitepress/cache/ +node_modules/ diff --git a/.vitepress/config.mts b/.vitepress/config.mts new file mode 100644 index 0000000..6273922 --- /dev/null +++ b/.vitepress/config.mts @@ -0,0 +1,17 @@ +import { defineConfig } from "vitepress"; + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "Scratch Specification", + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + sidebar: [ + { + items: [ + { text: "Contents", link: "/" }, + { text: "Introduction", link: "/intro" }, + ], + }, + ], + }, +}); diff --git a/README.md b/README.md deleted file mode 100644 index 5f49e16..0000000 --- a/README.md +++ /dev/null @@ -1,1329 +0,0 @@ -# Scratch Specification - -A detailed explanation of how Scratch 3.0 works as a programming language. - -## Contents - -* [Scratch Specification](#scratch-specification) - * [Contents](#contents) - * [Introduction](#introduction) - * [Preliminaries](#preliminaries) - * [Sources](#sources) - * [Contributing](#contributing) - * [FAQ](#faq) - * [Where to start?](#where-to-start) - * [What's the point?](#whats-the-point) - * [Why?](#why) - * [TODO](#todo) - * [TODO: Blocks](#todo-blocks) - * [Concepts](#concepts) - * [Capabilities](#capabilities) - * [Constants](#constants) - * [Stage Bounds](#stage-bounds) - * [Stage Width](#stage-width) - * [Stage Height](#stage-height) - * [Left Edge](#left-edge) - * [Right Edge](#right-edge) - * [Top Edge](#top-edge) - * [Bottom Edge](#bottom-edge) - * [Limits](#limits) - * [Max Items](#max-items) - * [Max Clones](#max-clones) - * [Ideas](#ideas) - * [Asset](#asset) - * [Costume](#costume) - * [Sound](#sound) - * [Block](#block) - * [Standard Blocks](#standard-blocks) - * [Hidden Blocks](#hidden-blocks) - * [Clone](#clone) - * [Edge](#edge) - * [Flag](#flag) - * [JavaScript](#javascript) - * [List](#list) - * [Mod](#mod) - * [Opcode](#opcode) - * [Project](#project) - * [Runtime](#runtime) - * [Script](#script) - * [Sprite](#sprite) - * [Stage](#stage) - * [Target](#target) - * [User](#user) - * [Variable](#variable) - * [Values](#values) - * [Value](#value) - * [Angle](#angle) - * [Answer](#answer) - * [Boolean](#boolean) - * [True](#true) - * [False](#false) - * [Direction](#direction) - * [Integer](#integer) - * [Item](#item) - * [Key](#key) - * [Length](#length) - * [Letter](#letter) - * [Name](#name) - * [Number](#number) - * [Infinity](#infinity) - * [-Infinity](#-infinity) - * [NaN](#nan) - * [Rotation Style](#rotation-style) - * [Rotation Style: All Around](#rotation-style-all-around) - * [Rotation Style: Left-Right](#rotation-style-left-right) - * [Rotation Style: Don't Rotate](#rotation-style-dont-rotate) - * [String](#string) - * [Empty String](#empty-string) - * [Undefined](#undefined) - * [Username](#username) - * [X Position](#x-position) - * [Y Position](#y-position) - * [Other Values](#other-values) - * [Procedures](#procedures) - * [Casting](#casting) - * [To String](#to-string) - * [To Number](#to-number) - * [To Boolean](#to-boolean) - * [Falsy](#falsy) - * [Truthy](#truthy) - * [To Direction](#to-direction) - * [Fencing](#fencing) - * [Fencing Position](#fencing-position) - * [Fencing Size](#fencing-size) - * [Palette](#palette) - * [Example block](#example-block) - * [Motion blocks](#motion-blocks) - * [Standard motion blocks](#standard-motion-blocks) - * [motion\_movesteps](#motion_movesteps) - * [Hidden motion blocks](#hidden-motion-blocks) - * [Looks blocks](#looks-blocks) - * [Standard looks blocks](#standard-looks-blocks) - * [Hidden looks blocks](#hidden-looks-blocks) - * [Sound blocks](#sound-blocks) - * [Standard sound blocks](#standard-sound-blocks) - * [Hidden sound blocks](#hidden-sound-blocks) - * [Events blocks](#events-blocks) - * [Standard events blocks](#standard-events-blocks) - * [Hidden events blocks](#hidden-events-blocks) - * [Control blocks](#control-blocks) - * [Standard control blocks](#standard-control-blocks) - * [Hidden control blocks](#hidden-control-blocks) - * [Sensing blocks](#sensing-blocks) - * [Standard sensing blocks](#standard-sensing-blocks) - * [sensing\_username](#sensing_username) - * [Hidden sensing blocks](#hidden-sensing-blocks) - * [Operators blocks](#operators-blocks) - * [Standard operators blocks](#standard-operators-blocks) - * [Hidden operators blocks](#hidden-operators-blocks) - * [Variables blocks](#variables-blocks) - * [Standard variables blocks](#standard-variables-blocks) - * [Hidden variables blocks](#hidden-variables-blocks) - * [List blocks](#list-blocks) - * [Standard list blocks](#standard-list-blocks) - * [Hidden list blocks](#hidden-list-blocks) - * [Custom blocks](#custom-blocks) - * [Standard custom blocks](#standard-custom-blocks) - * [Hidden custom blocks](#hidden-custom-blocks) - * [Special custom blocks](#special-custom-blocks) - * [Music blocks](#music-blocks) - * [Pen blocks](#pen-blocks) - * [Video Sensing blocks](#video-sensing-blocks) - * [Text to Speech blocks](#text-to-speech-blocks) - * [Translate blocks](#translate-blocks) - * [Makey Makey blocks](#makey-makey-blocks) - * [micro:bit blocks](#microbit-blocks) - * [LEGO EV3 blocks](#lego-ev3-blocks) - * [BOOST blocks](#boost-blocks) - * [WeDo 2.0 blocks](#wedo-20-blocks) - * [Force and Acceleration blocks](#force-and-acceleration-blocks) - * [CoreEx blocks](#coreex-blocks) - * [Standard CoreEx blocks](#standard-coreex-blocks) - * [Hidden CoreEx blocks](#hidden-coreex-blocks) - * [Appendices](#appendices) - * [File Format](#file-format) - * [SB3](#sb3) - * [SB2](#sb2) - * [SB](#sb) - * [Obsolete Blocks](#obsolete-blocks) - * [Nonstandard Blocks](#nonstandard-blocks) - * [Example nonstandard block](#example-nonstandard-block) - * [TurboWarp](#turbowarp) - * [TurboWarp blocks](#turbowarp-blocks) - * [Last key pressed block](#last-key-pressed-block) - * [Addon blocks](#addon-blocks) - * [PenguinMod](#penguinmod) - * [snail-ide](#snail-ide) - * [Unsandboxed](#unsandboxed) - * [Adding Platforms](#adding-platforms) - -## Introduction - -This document is a serious attempt to create a [programming language specification](https://en.wikipedia.org/wiki/Programming_language_specification) of [Scratch 3.0](https://en.scratch-wiki.info/wiki/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](https://en.wikipedia.org/wiki/Porting) of it to other platforms. This project is entirely "for fun" (note the quotation marks) and is not affilated with the [Scratch Foundation](https://www.scratchfoundation.org/) or related parties in any way whatsoever, though please [donate](https://www.scratchfoundation.org/donate) to them if you can so that they may continue to support and improve [Scratch](https://scratch.mit.edu/) 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](https://en.wikipedia.org/wiki/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](https://scratchblocks.github.io/) [syntax](https://en.scratch-wiki.info/wiki/Block_Plugin/Syntax).** This text-based format is used to represent Scratch [blocks](#block). An option to render the scratchblocks while viewing in-browser is being considered; however, the shapes and colors of the blocks are not necessarily being documented here, but rather their functionality. - -### Sources - -The information about Scratch in this specification is, of course, derived from Scratch sources, e.g. the Scratch [VM](https://github.com/scratchfoundation/scratch-vm), [Wiki](https://scratch-wiki.info/), [Website](https://scratch.mit.edu/), [Editor](https://scratch.mit.edu/projects/editor), and [Discussion Forums](https://scratch.mit.edu/discuss/). [Wikipedia](https://wikipedia.org/wiki/Wikipedia:About) and [MDN Web Docs](https://developer.mozilla.org/) are linked to as well for additional information regarding general concepts and internal behaviors. - -### Contributing - -Please [contribute on GitHub](https://github.com/OceanIsEndless/scratch-spec/pulls) (must be **13** or older, [need a GitHub account](https://github.com/signup)) or [comment on my Scratch profile](https://scratch.mit.edu/users/Endless-Ocean/#comments) (just [need a Scratch account](https://scratch.mit.edu/join)) 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 - -### FAQ - -*Questions that would be frequently asked if someone were to ask them.* - -#### Where to start? - -* If you want a **general understanding** of Scratch's inner workings for whatever reason, find whatever interests you in the [table of contents](#contents) and just gloss over whatever you don't need to know. -* If you want **formal definitions** of Scratch terms, see [concepts](#concepts). -* If you want to accurately **recreate blocks**, see the [palette](#palette). - -TODO: Threading and execution behavior will be documented soon! - -* If you want to learn about project files, see [file format](#file-format). -* If you want to recreate old blocks, see [obsolete blocks](#obsolete-blocks). -* If you want more blocks, see [nonstandard blocks](#nonstandard-blocks). - -#### 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](https://www.desmos.com/calculator) packager, or porting Scratch to the [Wii](https://en.wikipedia.org/wiki/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 help this super cool rapidly-developing [3DS port](https://github.com/NateXS/Scratch-3DS), 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](https://scratch-wiki.info/) 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](#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](https://blob.codes/scratch-is-cool/). It is [Turing-complete](https://en.wikipedia.org/wiki/Turing_completeness). Lots of languages far less significant than Scratch have [programming language specifications](https://en.wikipedia.org/wiki/Programming_language_specification). 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***](https://en.wikipedia.org/wiki/Scratch_(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](#contributing) 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. - -Various things need to be worked on to make this a good resource: - -* **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 its structure should be as well. -* ⚠️ ‼️ **Cite reliable sources.** ‼️ ⚠️ This specification should provide references to the code of Scratch itself (not just wikis) to prove its claims and hopefully be an accurate source of information about the Scratch programming language. It has not been decided how to best reference material though. (Just link them, or go wiki style?) - -### 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 checked off.) Specifying [standard](#palette) blocks is the first priority. Once they are documented, the scope of this spec can be expanded to include [hidden](#hidden-blocks), [obsolete](#obsolete-blocks), and even [nonstandard](#nonstandard-blocks) blocks as well, probably in that order. - -
- Click to view block list - -* [ ] [Motion Blocks](#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 [left-right]` - * [ ] `(x position)` - * [ ] `(y position)` - * [ ] `(direction)` - * [ ] [**Hidden**](#hidden-blocks) (**specify** what they do, even if nothing at all) - * [ ] `scroll right ()` - * [ ] `scroll up ()` - * [ ] `align scene [ v]` - * [ ] `(x scroll)` - * [ ] `(y scroll)` - * [ ] [**Obsolete**](#obsolete-blocks) (**imagine** what they *would* do if kept operational) - * [ ] `scroll right ()` - * [ ] `scroll up ()` - * [ ] `align scene [ v]` - * [ ] `(x scroll)` - * [ ] `(y scroll)` - * [ ] [**Nonstandard**](#nonstandard-blocks) (blocks that [mods](#mod) of Scratch added) - * [ ] [PenguinMod](#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](#unsandboxed) - * [ ] `(rotation style)` -* [ ] [Looks blocks](#looks-blocks) -* [ ] [Sound blocks](#sound-blocks) -* [ ] [Events blocks](#events-blocks) -* [ ] [Control blocks](#control-blocks) -* [ ] [Sensing blocks](#sensing-blocks) -* [ ] [Operators blocks](#operators-blocks) -* [ ] [Variables blocks](#variables-blocks) -* [ ] [List blocks](#list-blocks) -* [ ] [Custom blocks](#custom-blocks) -* [ ] [Addon blocks](#addon-blocks) -* [ ] *other categories of blocks* -* [ ] TODO: Write list of blocks TODO :) - -
- -## Concepts - -This section explains the various concepts and rules of Scratch. - -### Capabilities - -At its core, Scratch should be able to: - -* Run scripts dynamically; multithreading, looping, timing, etc. -* Show images on a screen; position, size, turn + draw graphics. -* Play sounds on speakers; several audio files can play at once. - -In an ideal situation, it should also be able to: - -* Apply effects to images and sounds -* Detect loudness via microphone -* Interact with linked devices -* Draw graphics dynamically -* Make requests to the web -* Know the current time -* Receive user input - -A fully functional implementation of Scratch should be capable of all these things, and if not handle it gracefully, this document detailing how to deal with everything. - -### Constants - -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. - -#### Stage Bounds - -##### Stage Width - -The horizontal size of the stage. This is an arbitrary positive [integer](#integer). - -**Standard Scratch**: `480` - -**Widescreen** (via unofficial modification): `640` - -##### Stage Height - -The vertical size of the stage. This is an arbitrary positive [integer](#integer). - -**Standard Scratch**: `360` - -##### Left Edge - -The horizontal position of the left edge. This is derived from the [stage width](#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](#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](#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](#stage-height). - -**Formula**: `stage height / -2` - -**Standard Scratch**: `-180` - -#### Limits - -##### Max Items - -The maximum [length](#length) of a [list](#list), aka the most items that one list can hold. This limit is imposed to prevent excessive memory usage by [projects](#project). This is an arbitrary positive [integer](#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](#clone) that can exist at one 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](#project). This is an arbitrary positive [integer](#integer). - -**Standard Scratch**: `300` - -**Modified Scratch**: None (many Scratch mods do not enforce this limit, though memory overflow may eventually occur) - -### Ideas - -The following ideas are referenced throughout this specification: - -#### Asset - -A [costume](#costume) or [sound](#sound). - -##### Costume - -A costume is an [image file](https://en.wikipedia.org/wiki/Digital_image) and a type of [asset](#asset) that can be graphically rendered to represent a [target](#target). It can be identified by its [name](#name) or [number](#integer). Costumes can either be [bitmap](https://en.wikipedia.org/wiki/Raster_graphics) or [vector](https://en.wikipedia.org/wiki/Vector_graphics). - -##### Sound - -A sound is an [audio file](https://en.wikipedia.org/wiki/Digital_audio) and a type of [asset](#asset) that can be audibly played to the user via [blocks](#block). It can be identified by its [name](#name). - -#### Block - -The fundamental component of Scratch as a programming language. In fact, they are similar to function calls 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](#undefined)) - -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](#script). - -##### Standard Blocks - -[Blocks](#block) that are officially supported in Scratch 3.0. They are the most commonly used blocks in [scripts](#script) by far. - -##### Hidden Blocks - -[Blocks](#block) 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](#script) may use them on occasion, but they are found less often than [standard blocks](#standard-blocks) due to their obscurity. - -#### Clone - -A copy created of a [sprite](#sprite) that has all of the original sprite's code, images, and sounds, but operates independently of it. Unlike sprites, clones cannot be directly referenced via existing blocks (e.g. you cannot [glide to](#glide-to-block) it directly without knowing its position ahead of time, as it cannot be selected in the sprite dropdown menu), and exist as their own thing. They are deleted every time the [flag](#flag) is clicked, and can also be deleted manually using the [`delete this clone` block](#delete-clone-block). - -Clones can be created with the [create clone block](#create-clone-block) so long as the [maximum number of clones](#max-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](#when-i-start-as-a-clone-block). The [stage](#stage) is the [target](#target) which cannot be cloned, whereas both sprites *and clones* can themselves be cloned. - -#### Edge - -Refers to the bounds that restrict the graphics of a [project](#project) from exceeding its designated region on the user's screen. - -#### Flag - -> The usefulness of defining "Flag" is up for debate. Feel free to offer insight! - -The button that is intended to run scripts that start a project. It is also known as the green flag in official Scratch. It is meant to make the project `Go`, as it is labelled in its title text on the Scratch website. When clicked, it runs any scripts under [when flag clicked blocks](#when-flag-clicked-block). - -#### 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](#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](#hidden-blocks), we can obtain this type of value. - -#### List - -A series of [items](#item) stored together in sequence. Each item is referenced by its numerical index (aka item #), a positive [integer](#integer) ranging from `1` to the [length](#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](#max-items) that a list can hold, aka a limit to its length. - -#### Mod - -A modification (altered version) of the Scratch 3.0 [runtime](#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 the [relevant appendix](#nonstandard-blocks). - -#### Opcode - -A [name](#name) unique to every [block](#block) in the Scratch programming language. It tells blocks what to do. For example, if the opcode of a block is [`motion_movesteps`](#motion_movesteps), it attempts to move steps. - -#### Project - -A stage and optionally some sprites packaged together to do something. They can be loaded into a [runtime](#runtime) and executed. They can also be saved as [project files](#file-format). - -#### Runtime - -The environment in which a [project](#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](#file-format). - -#### Script - -A set of [blocks](#block) put together to create code. Here is an example of a script: - -```sb -when flag clicked -ask [What's your name?] and wait -say (join [Hello, ] (join (answer) [!])) -stop [this script v] -``` - -Blocks are put together in the following ways: - -* TODO :D - -#### Sprite - -A kind of [target](#target) that can exist on its own, have [variables](#variable) only it can set, and be moved, pointed, scaled, and hidden, all of which are things that the [stage](#stage) cannot do. - -#### Stage - -A special [target](#target), with one and only one existing in every project, that is shown behind all [sprites](#sprite). It is sort of like the [global scope](https://en.wikipedia.org/wiki/Scope_(computer_science)#Global_scope) found in some programming languages, but it also exists as its own entity. - -Unlike [sprites](#sprite), 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](#variable) (aka properties or fields) that are used by contained [scripts](#script) to perform operations. - -Every target exists as its own unit independent of other targets, but they can be interconnected in some ways. There are two kinds of targets * [sprites](#sprite) and [stages](#stage). - -#### User - -The individual who is interacting with the [project](#project) and provides input. They may optionally have a [username](#username) that the project can use to identify them. - -#### Variable - -A container with a [name](#name) that can hold any one [value](#value). Every variable is attached to a [target](#target). If it is attached to a [sprite](#sprite), it can only be set by that sprite. If it is attached to the [stage](#stage), it can be set by any sprite, including the stage. - -There are two kinds of variables. Some variables are defined and named by the creator of a [project](#project) on a target-by-target basis and interacted with by [variables blocks](#variables-blocks), while all targets have variables that exist by default and can only be interacted with via their dedicated blocks (not variable blocks). Some examples of user-defined variables would be `(score)` or `(index)` (completely custom), while examples of built-in variables would be `(x position)`, `(direction)`, `(size)`, `(volume)`, and `(tempo)` (exist in every target). - -### Values - -In Scratch, the following types of values exist: - -* [String](#string) -* [Number](#number) -* * [`NaN`](#nan) - * [`Infinity`](#infinity) - * [`-Infinity`](#-infinity) -* [Boolean](#boolean) - * [`true`](#true) - * [`false`](#false) -* [`undefined`](#undefined) - -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](#string), [number](#number), [boolean](#boolean), or in rare cases [undefined](#undefined). [Variables](#variable) can hold individual values, and a [list](#list) can store many of them as [items](#item). - -#### Angle - -A [number](#number) intended to be in [degrees](https://en.wikipedia.org/wiki/Degree_(angle)). `[sin v] of ()`, `[cos v] of ()`, and `[tan v] of ()` expect angles as input. - -#### Answer - -A [string](#string) provided to the [project](#project) by the [user](#user) as input via the [ask and wait block](#ask-and-wait-block). - -#### Boolean - -A special type of [value](#value) that is used to represent the result of a logical operation. It is always either [`true`](#true) or [`false`](#false). - -##### True - -A kind of [boolean](#boolean) that is used to represent a yes or an affirmative answer as a result of a logical operation. When casted to a [string](#string), it is written as `true`. When casted to a [number](#number), it is casted to `1`. It is considered [truthy](#truthy), as it is itself the definition of truthy. - -##### False - -A kind of [boolean](#boolean) that is used to represent a no or a negative answer as a result of a logical operation. When casted to a [string](#string), it is written as `false`. When casted to a [number](#number), it is casted to `0`. It is considered [falsy](#falsy), as it is itself the definition of falsy. - -#### Direction - -An [angle](#angle) that determines the way a sprite is turned on the screen. It is always wrapped to remain in the range -179 and 181 (exclusive). An angle $a$ can be converted to a direction $d$ like so: - -$d=\operatorname{mod}\left(a+179,360\right)-179$ - -Or in scratchblocks: - -```sb -set [direction v] to ((((angle) + (179)) mod (360)) * (179)) -``` - -The way that a sprite's direction impacts how it is rendered is determined by that sprite's [rotation style](#rotation-style). - -#### Integer - -A [number](#number) that is not a fraction, aka a whole number (e.g. `42`, `-37`). Many [blocks](#block) 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 - -A [value](#value) in a [list](#list). - -#### Key - -A [name](#name) used by Scratch for referring to a key on the [user](#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](#integer) representing how many [letters](#letter) or [items](#item) there are in a [string](#string) or [list](#list), respectively. - -#### Letter - -An individual [UTF-16](https://en.wikipedia.org/wiki/UTF-16) [code unit](https://developer.mozilla.org/en-US/docs/Glossary/Code_unit). Several joined together create a [string](#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](#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](#username), or [sprite](#sprite). - -#### Number - -A [numerical](https://en.wikipedia.org/wiki/Number) [value](#value). Most numbers are [real](https://en.wikipedia.org/wiki/Real_number) and can be positive (`+`), negative (`-`), whole (`#`), or fractional (`#.#`). In [JavaScript](#javascript), these numbers are internally stored as [double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double_precision_floating-point_format) 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](#number) that is always greater than any other number. When [casted](#to-string) to a [string](#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. - -```sb -[Infinity] + (1) // Infinity -[10 ^ v] of (1000) // Infinity -[log v] of (0) // -Infinity -(1) / [Infinity] // 0 -(1) / (0) // Infinity -``` - -##### -Infinity - -A special [number](#number) that is always lower than any other number. When [casted](#to-string) to a [string](#string), it is written as `-Infinity`. It is created in the same manner as [Infinity](#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](#number) that is not a number. When [casted](#to-string) to a [string](#string), it is written as `NaN`. It is interpreted as a `0` when passed as input to other mathematical operations, unlike in [JavaScript](#javascript) where it causes most operations to report `NaN`. It can be produced by doing unknown or unrepresentable things with numbers, such as multiplying `Infinity` and zero, adding `Infinity` to `-Infinity`, or getting the square root of a negative number. - -#### Rotation Style - -A [string](#string) that determines how a [sprite](#sprite)'s [direction](#direction) impacts the way it is visibly rotated when rendered. Officially, it can be one of the following strings: `all around`, `left-right`, or `don't rotate`. - -* `all around`: The sprite faces in its direction **clockwise**. At `0`, it faces **up**; at `90`, it faces **right**; at `180`, it faces **down**; and at `-90`, it faces **left**. -* `left-right`: If the sprite's direction is less than `0`, 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*](#direction) 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) | - -##### Rotation Style: All Around - -![A demonstration of the "all around" rotation style](./img/all-around.gif) - -##### Rotation Style: Left-Right - -![A demonstration of the "left-right" rotation style](./img/left-right.gif) - -##### Rotation Style: Don't Rotate - -![A demonstration of the "don't rotate" rotation style](./img/don't-rotate.gif) - -#### String - -A type of [value](#value) consisting of a series (i.e. string) of [letters](#letter), also known as text. All strings are considered [truthy](#truthy) except for the [empty string](#empty-string). - -##### Empty String - -A [string](#string) containing no letters. It has a [length](#length) of `0` and is the only string considered [falsy](#falsy). Also known as a "null string," it can be used in place of a value where there is none, e.g. getting an [item](#item) from a [list](#list) when it does not exist, or getting the [answer](#answer) provided by a user when they have not been [asked](#ask-and-wait-block) anything yet. - -#### Undefined - -A special [value](#value) that represents nothing. When converted to a [string](#string), it is written as `undefined`. This type of value is uncommon but can be produced by [hidden reporter blocks](#hidden-blocks). In most cases, however, Scratch uses `0` or an empty string to represent nothing. - -#### Username - -A [name](#name) used to reference a [user](#user). In standard Scratch, usernames are: - -* Always 3 to 20 [letters](#letter) [long](#length) (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](https://scratch.mit.edu). 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](https://en.scratch-wiki.info/wiki/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](#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](#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 Scratch through the official 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](#runtime) directly via developer tools like web inspector. - -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 to see if it is registered with the Scratch website -* Remembering the usernames that the username block has reported (e.g. via cloud variables) and see if it encounters the same username with different casing -* Checking to see if the username is changed while the project is running (impossible without modification 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 implementation 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](#string) that identifies a user. - -#### X Position - -A horizontal position on the Scratch coordinate plane. All [sprites](#sprite) have one. (TODO: document coordinate system) - -#### Y Position - -A vertical position on the Scratch coordinate plane. All [sprites](#sprite) 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](#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](#turbowarp) that still has largely the same behaviors to see how it would behave if somehow obtained.) - * When [casted](#to-string) to a [string](#string), it is written as `null`. - * When [casted](#to-number) to a [number](#number), it is casted to `0`. - * When [casted](#to-boolean) to a [boolean](#boolean), it is [`false`](#falsy). - -### Procedures - -The following procedures are often performed by Scratch and are mentioned throughout this document: - -#### Casting - -Most blocks automatically convert [values](#value) between types through the use of very particular logic, also known as [casting](https://en.scratch-wiki.info/wiki/Casting). The logic Scratch uses is specified below. - -##### To String - -Scratch uses the following logic to convert any given [value](#value) to a [string](#string): - -* If the value is a [**string**](#string): - * **Return the value**, as it is already a string. -* If the value is a [**number**](#number): - * **Follow the [logic JavaScript does](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)** to cast a number to a string **and return it.** - * TODO: specify this better - * If the value is [**NaN**](#nan), **return the string `NaN`.** - * If the value is [**Infinity**](#infinity), **return the string `Infinity`.** - * If the value is [**-Infinity**](#infinity), **return the string `-Infinity`.** -* If the value is a [**boolean**](#boolean): - * If the value is [**true**](#boolean), **return the string `true`.** - * If the value is [**false**](#boolean), **return the string `false`.** -* If the value is [**undefined**](#undefined), **return the string `undefined`.** -* If the value is [**something else**](#other-values), **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 - -##### To Number - -Scratch uses the following logic to convert any given [value](#value) to a [number](#number): - -* If the value is [**NaN**](#nan), **return the number `0`.** -* If the value is a [**number**](#number), **return the value** as it is. -* If the value is [**undefined**](#undefined), **return the number `0`.** -* If the value is [**true**](#true), **return the number `1`.** -* If the value is [**false**](#false), **return the number `0`.** -* If the value is a [**string**](#string) or [something else](#other-values): - * **If the value can be converted to a number** according to [these rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_coercion)**, 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](#value) to a [boolean](#boolean): - -###### Falsy - -A value is **falsy**, or casted to [**false**](#false), if the value is: - -* an [**empty string**](#empty-string) (no letters, [length](#length) is `0`), -* the **[strings](#string) `0`** or **`false`** (case-insensitive), -* one of the **[numbers](#number) `0`**, **`-0`**, or [**`NaN`**](#nan), -* [**undefined**](#undefined), -* **null** (rare), -* or **false**. - -###### Truthy - -Any value that is **not** [**falsy**](#falsy) is considered **truthy** and casted to [**true**](#true). - -##### To Direction - -Scratch uses the following logic to convert any given [value](#value) to a [direction](#direction): - -1. [**Cast the value to number**](#to-number). -2. **Plug the casted value** into the following equation **as $a$ to find $d$:** - * $d=\operatorname{mod}\left(a+179,360\right)-179$ - * Here is the same equation written in blocks: - - ```sb - set [direction v] to ((((angle) + (179)) mod (360)) * (179)) - ``` - -3. **Return $d$** (`direction`)**.** - -#### Fencing - -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 :D - -##### 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. - -## Palette - -This section documents each and every block in Scratch, and its precise functionality. - -> 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 - -> 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](#sb3) [file format](#file-format). - -**Operation:** - -A brief overview of the block's function and essential info. - -**Block:** - -```sb -the block in scratchblocks with its [ARG]uments -``` - -**Arguments:** - -| Name: | [Casted](#casting) 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](#values) | 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](#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:** - -```sb -move (STEPS) steps -``` - -**Arguments**: - -| Name: | [Casted](#casting) to: | Provides the: | -|:-----:|:----------------------:|:-------------------------------------:| -|`STEPS`| [number](#to-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, whereas 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: - -$x' = x + \sin(d) \cdot S$ - -$y' = y + \cos(d) \cdot S$ - -Where $S$ is the `STEPS` to move, $d$ is the direction of the sprite, and $x$ and $y$ are the x and y positions of the sprite, respectively. - -In scratchblocks, this operation can also be replicated as: - -```sb -go to x: ((x position) + (([sin v] of (direction)) * (STEPS))) y: ((y position) + (([cos v] of (direction)) * (STEPS))) -``` - -After the sprite is moved, its position is [fenced](#fencing-position). - -#### 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](#runtime) context. - -#### Standard sensing blocks - -These sensing blocks are officially supported in Scratch 3.0: - -TODO - -##### sensing_username - -**Operation:** - -Reports the [username](#username) of the [user](#user) that has loaded the [project](#project) in the context of the Scratch website. - -**Block:** - -```sb -(username) -``` - -**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](#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](#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 appendix](#nonstandard-blocks), though it will have to be clarified that these blocks can be loaded into Scratch, they just don't do anything outside of [mods](#mod). - -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](#mod). - -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 - -## Appendices - -This section is for additional information about Scratch that is not necessarily relevant to its runtime behavior, but is good to know in addition, especially for creating highly compatible and feature-complete Scratch implementations. - -### 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](#runtime) environment, a saved project that is not properly loaded may not work as it was intended to, and could very well break! - -#### 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](https://en.wikipedia.org/wiki/ZIP_(file_format)) file that contains the following files: - -* `project.json`, a [.json](https://en.wikipedia.org/wiki/JSON) file storing info. -* Various image files used as [costumes](#costume). -* Various audio files used as [sounds](#sound). - -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](#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](#sb2) and [.sb3](#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! - -### Obsolete Blocks - -> 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 [runtime](#runtime) 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 - -> 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](https://en.wikipedia.org/wiki/Porting) of Scratch). - -This section serves to document blocks that do not exist at all in Scratch, but have been added unofficially to [modifications](#mod) of Scratch. This includes both blocks added as "custom extensions," and blocks added directly to the [palette](#palette). They are specified here in order to allow projects using these nonstandard blocks to function properly if one were to reimplement the Scratch VM with implementing these blocks in mind. - -> This is a dynamic section and may never be able to satisfy any particular standards for completeness. [You can help](#contributing) by adding [missing blocks](#todo-blocks) with reliable sources (e.g. links to source code). - -#### Example nonstandard block - -> 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:** - -```sb -the block in scratchblocks with its [ARG]uments -``` - -**Arguments:** - -| Name: | [Casted](#casting) 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](#values) | What it provides to the block. | - -**Procedure:** - -A deep dive into what the block does in fulfilling its operation. - -#### TurboWarp - -[TurboWarp](https://turbowarp.org/) 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:** - -```sb -(last key pressed) -``` - -**Arguments:** - -None - -**Procedure:** - -When the [runtime](#runtime) first starts, no [keys](#key) have been pressed. If the block is run before any keys are pressed, it reports the [empty string](#empty-string). Otherwise, the [name](#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](#special-custom-blocks) without definitions in disguise! - -#### PenguinMod - -[PenguinMod](https://penguinmod.com/) is a mod of [TurboWarp](#turbowarp). It supports most TurboWarp extensions and introduces some community-made ones of its own. - -TODO: Document PenguinMod blocks - -#### snail-ide - -[Snail IDE](https://snail-ide.js.org/) is a mod of [PenguinMod](#penguinmod). It supports most of PenguinMod's blocks and adds some of its own. - -TODO: Document Snail IDE blocks - -#### Unsandboxed - -[Unsandboxed](https://alpha.unsandboxed.org/#0) is a mod of [TurboWarp](#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](#contributing) information on it! Though if you do, please remember that this a language specification for Scratch's runtime behavior, not a [wiki](https://scratch-wiki.info/) 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](#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](#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](#turbowarp) is in the [Addon blocks](#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. - -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‍*!*](https://snap.berkeley.edu/) 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](https://snap.berkeley.edu/snap/help/SnapManual.pdf) instead. diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..32b8d0b --- /dev/null +++ b/bun.lock @@ -0,0 +1,345 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "dependencies": { + "vitepress": "^1.6.3", + }, + }, + }, + "packages": { + "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.17.7", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q=="], + + "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A=="], + + "@algolia/autocomplete-preset-algolia": ["@algolia/autocomplete-preset-algolia@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA=="], + + "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.17.7", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg=="], + + "@algolia/client-abtesting": ["@algolia/client-abtesting@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-M4zb6J7q+pg9V9Xk0k1WDgvupfCtXcxjKGTrNVYemiredLVGOmvVIPAUjg2rx4QmK7DWNApWLsieYwk7PAaOXw=="], + + "@algolia/client-analytics": ["@algolia/client-analytics@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-h18zlL+bVUlbNE92olo1d/r6HQPkxhmP7yCpA1osERwpgC6F058kWm0O0aYdrHJIHtWBcs9aRqq7IkQSkpjPJg=="], + + "@algolia/client-common": ["@algolia/client-common@5.34.1", "", {}, "sha512-otPWALs72KvmVuP0CN0DI6sqVx1jQWKi+/DgAiP8DysVMgiNlva3GDKTtAK6XVGlT08f4h32FNuL0yQODuCfKA=="], + + "@algolia/client-insights": ["@algolia/client-insights@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-SNDb5wuEpQFM6S5Shk2iytLMusvGycm9uTuYh7cGa1h3U7O65OjjjIgQ0lLY5HPybHNtmXr4Zh/EZ23pZvAJHg=="], + + "@algolia/client-personalization": ["@algolia/client-personalization@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-T8z9KqYJOup83Hw0mgICYWfJoLh//FNWbf4roFd95ZJzZ4v1cN/hvr7Eqml1qWMoCkJb4y/XQjrXsJ6Y9XnMLw=="], + + "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-YA0kC4CwO1mc1dliNgbFgToweRa7Uihjz3izEaV4cXninF1v4SaOrPkQUsiFPprAffjMzOUoT7vahQZ/HZyiKQ=="], + + "@algolia/client-search": ["@algolia/client-search@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-bt5hC9vvjaKvdvsgzfXJ42Sl3qjQqoi/FD8V7HOQgtNFhwSauZOlgLwFoUiw67sM+r7ehF7QDk5WRDgY7fAkIg=="], + + "@algolia/ingestion": ["@algolia/ingestion@1.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-QLxiBskQxFGzPqKZvBNEvNN95kgDCbBd2X29ZGfh6Sr2QOSU34US6Z9x2duiF4o9FwsB0i6eQ2c9vHfuH0lAQg=="], + + "@algolia/monitoring": ["@algolia/monitoring@1.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-NteCvWcWXXdnPGyZH8rXHslcf2pM1WGDNMGNZFXLFtOt1Gf1Tjy2t0NZLp+Mxap3JMV4mbYmactbXrvpQf/lLA=="], + + "@algolia/recommend": ["@algolia/recommend@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-UdgDSrunLIBAAAxQlYLXYLnYFN4wkzkrAYx+wMLEk/pzASWyza3BkecbUFVqoYOBIgwo7Mt4iymzVtFkzL2uCQ=="], + + "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1" } }, "sha512-567LfFTc9VOiPtuySQohoqaWMeohYWbXK71aMSin+SLMgeKX7hz5LrVmkmMQj9udwWK6/mtHEYZGPYHSuXpLQg=="], + + "@algolia/requester-fetch": ["@algolia/requester-fetch@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1" } }, "sha512-YRbygPgGBEik5U593JvyjgxFjcsyZMR25eIQxNHvSQumdAzt5A4E4Idw3yXnwhrmMdjML54ZXT7EAjnTjWy8Xw=="], + + "@algolia/requester-node-http": ["@algolia/requester-node-http@5.34.1", "", { "dependencies": { "@algolia/client-common": "5.34.1" } }, "sha512-o0mqRYbS82Rt4DE02Od7RL6pNtV7oSxScPuIw8LW4aqO2V5eCF05Pry/SnUgcI/Vb2QCYC66hytBCqzyC/toZA=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="], + + "@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="], + + "@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="], + + "@docsearch/css": ["@docsearch/css@3.8.2", "", {}, "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ=="], + + "@docsearch/js": ["@docsearch/js@3.8.2", "", { "dependencies": { "@docsearch/react": "3.8.2", "preact": "^10.0.0" } }, "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ=="], + + "@docsearch/react": ["@docsearch/react@3.8.2", "", { "dependencies": { "@algolia/autocomplete-core": "1.17.7", "@algolia/autocomplete-preset-algolia": "1.17.7", "@docsearch/css": "3.8.2", "algoliasearch": "^5.14.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", "react": ">= 16.8.0 < 19.0.0", "react-dom": ">= 16.8.0 < 19.0.0", "search-insights": ">= 1 < 3" }, "optionalPeers": ["@types/react", "react", "react-dom", "search-insights"] }, "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.44", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-CdWgSPygwDlDbKtDWjvi3NtUefnkoepXv90n3dQxJerqzD9kI+nEJOiWUBM+eOyMYQKtxBpLWFBrgeotF0IZKw=="], + + "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.4", "", {}, "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.45.1", "", { "os": "android", "cpu": "arm" }, "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.45.1", "", { "os": "android", "cpu": "arm64" }, "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.45.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.45.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.45.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.45.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.45.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.45.1", "", { "os": "linux", "cpu": "arm" }, "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.45.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.45.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog=="], + + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.45.1", "", { "os": "linux", "cpu": "none" }, "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg=="], + + "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.45.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.45.1", "", { "os": "linux", "cpu": "none" }, "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.45.1", "", { "os": "linux", "cpu": "none" }, "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.45.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.45.1", "", { "os": "linux", "cpu": "x64" }, "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.45.1", "", { "os": "linux", "cpu": "x64" }, "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.45.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.45.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.45.1", "", { "os": "win32", "cpu": "x64" }, "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA=="], + + "@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="], + + "@shikijs/langs": ["@shikijs/langs@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w=="], + + "@shikijs/themes": ["@shikijs/themes@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw=="], + + "@shikijs/transformers": ["@shikijs/transformers@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/types": "2.5.0" } }, "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg=="], + + "@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="], + + "@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "@vitejs/plugin-vue": ["@vitejs/plugin-vue@5.2.4", "", { "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA=="], + + "@vue/compiler-core": ["@vue/compiler-core@3.5.18", "", { "dependencies": { "@babel/parser": "^7.28.0", "@vue/shared": "3.5.18", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw=="], + + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.18", "", { "dependencies": { "@vue/compiler-core": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A=="], + + "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.18", "", { "dependencies": { "@babel/parser": "^7.28.0", "@vue/compiler-core": "3.5.18", "@vue/compiler-dom": "3.5.18", "@vue/compiler-ssr": "3.5.18", "@vue/shared": "3.5.18", "estree-walker": "^2.0.2", "magic-string": "^0.30.17", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-5aBjvGqsWs+MoxswZPoTB9nSDb3dhd1x30xrrltKujlCxo48j8HGDNj3QPhF4VIS0VQDUrA1xUfp2hEa+FNyXA=="], + + "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.18", "", { "dependencies": { "@vue/compiler-dom": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-xM16Ak7rSWHkM3m22NlmcdIM+K4BMyFARAfV9hYFl+SFuRzrZ3uGMNW05kA5pmeMa0X9X963Kgou7ufdbpOP9g=="], + + "@vue/devtools-api": ["@vue/devtools-api@7.7.7", "", { "dependencies": { "@vue/devtools-kit": "^7.7.7" } }, "sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg=="], + + "@vue/devtools-kit": ["@vue/devtools-kit@7.7.7", "", { "dependencies": { "@vue/devtools-shared": "^7.7.7", "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA=="], + + "@vue/devtools-shared": ["@vue/devtools-shared@7.7.7", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw=="], + + "@vue/reactivity": ["@vue/reactivity@3.5.18", "", { "dependencies": { "@vue/shared": "3.5.18" } }, "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg=="], + + "@vue/runtime-core": ["@vue/runtime-core@3.5.18", "", { "dependencies": { "@vue/reactivity": "3.5.18", "@vue/shared": "3.5.18" } }, "sha512-DUpHa1HpeOQEt6+3nheUfqVXRog2kivkXHUhoqJiKR33SO4x+a5uNOMkV487WPerQkL0vUuRvq/7JhRgLW3S+w=="], + + "@vue/runtime-dom": ["@vue/runtime-dom@3.5.18", "", { "dependencies": { "@vue/reactivity": "3.5.18", "@vue/runtime-core": "3.5.18", "@vue/shared": "3.5.18", "csstype": "^3.1.3" } }, "sha512-YwDj71iV05j4RnzZnZtGaXwPoUWeRsqinblgVJwR8XTXYZ9D5PbahHQgsbmzUvCWNF6x7siQ89HgnX5eWkr3mw=="], + + "@vue/server-renderer": ["@vue/server-renderer@3.5.18", "", { "dependencies": { "@vue/compiler-ssr": "3.5.18", "@vue/shared": "3.5.18" }, "peerDependencies": { "vue": "3.5.18" } }, "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA=="], + + "@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], + + "@vueuse/core": ["@vueuse/core@12.8.2", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" } }, "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ=="], + + "@vueuse/integrations": ["@vueuse/integrations@12.8.2", "", { "dependencies": { "@vueuse/core": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7" }, "optionalPeers": ["async-validator", "axios", "change-case", "drauu", "focus-trap", "fuse.js", "idb-keyval", "jwt-decode", "nprogress", "qrcode", "sortablejs", "universal-cookie"] }, "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g=="], + + "@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="], + + "@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="], + + "algoliasearch": ["algoliasearch@5.34.1", "", { "dependencies": { "@algolia/client-abtesting": "5.34.1", "@algolia/client-analytics": "5.34.1", "@algolia/client-common": "5.34.1", "@algolia/client-insights": "5.34.1", "@algolia/client-personalization": "5.34.1", "@algolia/client-query-suggestions": "5.34.1", "@algolia/client-search": "5.34.1", "@algolia/ingestion": "1.34.1", "@algolia/monitoring": "1.34.1", "@algolia/recommend": "5.34.1", "@algolia/requester-browser-xhr": "5.34.1", "@algolia/requester-fetch": "5.34.1", "@algolia/requester-node-http": "5.34.1" } }, "sha512-s70HlfBgswgEdmCYkUJG8i/ULYhbkk8N9+N8JsWUwszcp7eauPEr5tIX4BY0qDGeKWQ/qZvmt4mxwTusYY23sg=="], + + "birpc": ["birpc@2.5.0", "", {}, "sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ=="], + + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "copy-anything": ["copy-anything@3.0.5", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w=="], + + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], + + "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "focus-trap": ["focus-trap@7.6.5", "", { "dependencies": { "tabbable": "^6.2.0" } }, "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="], + + "magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="], + + "mark.js": ["mark.js@8.11.1", "", {}, "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "minisearch": ["minisearch@7.1.2", "", {}, "sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA=="], + + "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="], + + "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + + "preact": ["preact@10.26.9", "", {}, "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA=="], + + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + + "regex": ["regex@6.0.1", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA=="], + + "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "rollup": ["rollup@4.45.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.45.1", "@rollup/rollup-android-arm64": "4.45.1", "@rollup/rollup-darwin-arm64": "4.45.1", "@rollup/rollup-darwin-x64": "4.45.1", "@rollup/rollup-freebsd-arm64": "4.45.1", "@rollup/rollup-freebsd-x64": "4.45.1", "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", "@rollup/rollup-linux-arm-musleabihf": "4.45.1", "@rollup/rollup-linux-arm64-gnu": "4.45.1", "@rollup/rollup-linux-arm64-musl": "4.45.1", "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", "@rollup/rollup-linux-riscv64-gnu": "4.45.1", "@rollup/rollup-linux-riscv64-musl": "4.45.1", "@rollup/rollup-linux-s390x-gnu": "4.45.1", "@rollup/rollup-linux-x64-gnu": "4.45.1", "@rollup/rollup-linux-x64-musl": "4.45.1", "@rollup/rollup-win32-arm64-msvc": "4.45.1", "@rollup/rollup-win32-ia32-msvc": "4.45.1", "@rollup/rollup-win32-x64-msvc": "4.45.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw=="], + + "search-insights": ["search-insights@2.17.3", "", {}, "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ=="], + + "shiki": ["shiki@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="], + + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "superjson": ["superjson@2.2.2", "", { "dependencies": { "copy-anything": "^3.0.2" } }, "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q=="], + + "tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="], + + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw=="], + + "vite": ["vite@5.4.19", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA=="], + + "vitepress": ["vitepress@1.6.3", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw=="], + + "vue": ["vue@3.5.18", "", { "dependencies": { "@vue/compiler-dom": "3.5.18", "@vue/compiler-sfc": "3.5.18", "@vue/runtime-dom": "3.5.18", "@vue/server-renderer": "3.5.18", "@vue/shared": "3.5.18" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + } +} diff --git a/index.md b/index.md new file mode 100644 index 0000000..a5a5aff --- /dev/null +++ b/index.md @@ -0,0 +1,1696 @@ +# Scratch Specification + +A detailed explanation of how Scratch 3.0 works as a programming language. + +## Contents + +- [Scratch Specification](#scratch-specification) + - [Contents](#contents) + - [Introduction](/intro) + - [Preliminaries](/intro#preliminaries) + - [Sources](/intro#sources) + - [Contributing](/intro#contributing) + - [FAQ](/intro#faq) + - [Where to start?](/intro#where-to-start) + - [What's the point?](/intro#whats-the-point) + - [Why?](/intro#why) + - [TODO](#todo) + - [TODO: Blocks](#todo-blocks) + - [Concepts](#concepts) + - [Capabilities](#capabilities) + - [Constants](#constants) + - [Stage Bounds](#stage-bounds) + - [Stage Width](#stage-width) + - [Stage Height](#stage-height) + - [Left Edge](#left-edge) + - [Right Edge](#right-edge) + - [Top Edge](#top-edge) + - [Bottom Edge](#bottom-edge) + - [Limits](#limits) + - [Max Items](#max-items) + - [Max Clones](#max-clones) + - [Ideas](#ideas) + - [Asset](#asset) + - [Costume](#costume) + - [Sound](#sound) + - [Block](#block) + - [Standard Blocks](#standard-blocks) + - [Hidden Blocks](#hidden-blocks) + - [Clone](#clone) + - [Edge](#edge) + - [Flag](#flag) + - [JavaScript](#javascript) + - [List](#list) + - [Mod](#mod) + - [Opcode](#opcode) + - [Project](#project) + - [Runtime](#runtime) + - [Script](#script) + - [Sprite](#sprite) + - [Stage](#stage) + - [Target](#target) + - [User](#user) + - [Variable](#variable) + - [Values](#values) + - [Value](#value) + - [Angle](#angle) + - [Answer](#answer) + - [Boolean](#boolean) + - [True](#true) + - [False](#false) + - [Direction](#direction) + - [Integer](#integer) + - [Item](#item) + - [Key](#key) + - [Length](#length) + - [Letter](#letter) + - [Name](#name) + - [Number](#number) + - [Infinity](#infinity) + - [-Infinity](#-infinity) + - [NaN](#nan) + - [Rotation Style](#rotation-style) + - [Rotation Style: All Around](#rotation-style-all-around) + - [Rotation Style: Left-Right](#rotation-style-left-right) + - [Rotation Style: Don't Rotate](#rotation-style-dont-rotate) + - [String](#string) + - [Empty String](#empty-string) + - [Undefined](#undefined) + - [Username](#username) + - [X Position](#x-position) + - [Y Position](#y-position) + - [Other Values](#other-values) + - [Procedures](#procedures) + - [Casting](#casting) + - [To String](#to-string) + - [To Number](#to-number) + - [To Boolean](#to-boolean) + - [Falsy](#falsy) + - [Truthy](#truthy) + - [To Direction](#to-direction) + - [Fencing](#fencing) + - [Fencing Position](#fencing-position) + - [Fencing Size](#fencing-size) + - [Palette](#palette) + - [Example block](#example-block) + - [Motion blocks](#motion-blocks) + - [Standard motion blocks](#standard-motion-blocks) + - [motion\_movesteps](#motion_movesteps) + - [Hidden motion blocks](#hidden-motion-blocks) + - [Looks blocks](#looks-blocks) + - [Standard looks blocks](#standard-looks-blocks) + - [Hidden looks blocks](#hidden-looks-blocks) + - [Sound blocks](#sound-blocks) + - [Standard sound blocks](#standard-sound-blocks) + - [Hidden sound blocks](#hidden-sound-blocks) + - [Events blocks](#events-blocks) + - [Standard events blocks](#standard-events-blocks) + - [Hidden events blocks](#hidden-events-blocks) + - [Control blocks](#control-blocks) + - [Standard control blocks](#standard-control-blocks) + - [Hidden control blocks](#hidden-control-blocks) + - [Sensing blocks](#sensing-blocks) + - [Standard sensing blocks](#standard-sensing-blocks) + - [sensing\_username](#sensing_username) + - [Hidden sensing blocks](#hidden-sensing-blocks) + - [Operators blocks](#operators-blocks) + - [Standard operators blocks](#standard-operators-blocks) + - [Hidden operators blocks](#hidden-operators-blocks) + - [Variables blocks](#variables-blocks) + - [Standard variables blocks](#standard-variables-blocks) + - [Hidden variables blocks](#hidden-variables-blocks) + - [List blocks](#list-blocks) + - [Standard list blocks](#standard-list-blocks) + - [Hidden list blocks](#hidden-list-blocks) + - [Custom blocks](#custom-blocks) + - [Standard custom blocks](#standard-custom-blocks) + - [Hidden custom blocks](#hidden-custom-blocks) + - [Special custom blocks](#special-custom-blocks) + - [Music blocks](#music-blocks) + - [Pen blocks](#pen-blocks) + - [Video Sensing blocks](#video-sensing-blocks) + - [Text to Speech blocks](#text-to-speech-blocks) + - [Translate blocks](#translate-blocks) + - [Makey Makey blocks](#makey-makey-blocks) + - [micro:bit blocks](#microbit-blocks) + - [LEGO EV3 blocks](#lego-ev3-blocks) + - [BOOST blocks](#boost-blocks) + - [WeDo 2.0 blocks](#wedo-20-blocks) + - [Force and Acceleration blocks](#force-and-acceleration-blocks) + - [CoreEx blocks](#coreex-blocks) + - [Standard CoreEx blocks](#standard-coreex-blocks) + - [Hidden CoreEx blocks](#hidden-coreex-blocks) + - [Appendices](#appendices) + - [File Format](#file-format) + - [SB3](#sb3) + - [SB2](#sb2) + - [SB](#sb) + - [Obsolete Blocks](#obsolete-blocks) + - [Nonstandard Blocks](#nonstandard-blocks) + - [Example nonstandard block](#example-nonstandard-block) + - [TurboWarp](#turbowarp) + - [TurboWarp blocks](#turbowarp-blocks) + - [Last key pressed block](#last-key-pressed-block) + - [Addon blocks](#addon-blocks) + - [PenguinMod](#penguinmod) + - [snail-ide](#snail-ide) + - [Unsandboxed](#unsandboxed) + - [Adding Platforms](#adding-platforms) + +## TODO + +> This spec is a work in progress; it's nowhere near complete. **Please +> [contribute](#contributing) 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. + +Various things need to be worked on to make this a good resource: + +- **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 its structure should be as well. +- ⚠️ ‼️ **Cite reliable sources.** ‼️ ⚠️ This specification should provide + references to the code of Scratch itself (not just wikis) to prove its claims + and hopefully be an accurate source of information about the Scratch + programming language. It has not been decided how to best reference material + though. (Just link them, or go wiki style?) + +### 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 checked off.) Specifying [standard](#palette) blocks +is the first priority. Once they are documented, the scope of this spec can be +expanded to include [hidden](#hidden-blocks), [obsolete](#obsolete-blocks), and +even [nonstandard](#nonstandard-blocks) blocks as well, probably in that order. + +
+ Click to view block list + +- [ ] [Motion Blocks](#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 [left-right]` + - [ ] `(x position)` + - [ ] `(y position)` + - [ ] `(direction)` + - [ ] [**Hidden**](#hidden-blocks) (**specify** what they do, even if nothing + at all) + - [ ] `scroll right ()` + - [ ] `scroll up ()` + - [ ] `align scene [ v]` + - [ ] `(x scroll)` + - [ ] `(y scroll)` + - [ ] [**Obsolete**](#obsolete-blocks) (**imagine** what they _would_ do if + kept operational) + - [ ] `scroll right ()` + - [ ] `scroll up ()` + - [ ] `align scene [ v]` + - [ ] `(x scroll)` + - [ ] `(y scroll)` + - [ ] [**Nonstandard**](#nonstandard-blocks) (blocks that [mods](#mod) of + Scratch added) + - [ ] [PenguinMod](#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](#unsandboxed) + - [ ] `(rotation style)` +- [ ] [Looks blocks](#looks-blocks) +- [ ] [Sound blocks](#sound-blocks) +- [ ] [Events blocks](#events-blocks) +- [ ] [Control blocks](#control-blocks) +- [ ] [Sensing blocks](#sensing-blocks) +- [ ] [Operators blocks](#operators-blocks) +- [ ] [Variables blocks](#variables-blocks) +- [ ] [List blocks](#list-blocks) +- [ ] [Custom blocks](#custom-blocks) +- [ ] [Addon blocks](#addon-blocks) +- [ ] _other categories of blocks_ +- [ ] TODO: Write list of blocks TODO :) + +
+ +## Concepts + +This section explains the various concepts and rules of Scratch. + +### Capabilities + +At its core, Scratch should be able to: + +- Run scripts dynamically; multithreading, looping, timing, etc. +- Show images on a screen; position, size, turn + draw graphics. +- Play sounds on speakers; several audio files can play at once. + +In an ideal situation, it should also be able to: + +- Apply effects to images and sounds +- Detect loudness via microphone +- Interact with linked devices +- Draw graphics dynamically +- Make requests to the web +- Know the current time +- Receive user input + +A fully functional implementation of Scratch should be capable of all these +things, and if not handle it gracefully, this document detailing how to deal +with everything. + +### Constants + +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. + +#### Stage Bounds + +##### Stage Width + +The horizontal size of the stage. This is an arbitrary positive +[integer](#integer). + +**Standard Scratch**: `480` + +**Widescreen** (via unofficial modification): `640` + +##### Stage Height + +The vertical size of the stage. This is an arbitrary positive +[integer](#integer). + +**Standard Scratch**: `360` + +##### Left Edge + +The horizontal position of the left edge. This is derived from the +[stage width](#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](#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](#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](#stage-height). + +**Formula**: `stage height / -2` + +**Standard Scratch**: `-180` + +#### Limits + +##### Max Items + +The maximum [length](#length) of a [list](#list), aka the most items that one +list can hold. This limit is imposed to prevent excessive memory usage by +[projects](#project). This is an arbitrary positive [integer](#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](#clone) that can exist at one 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](#project). This is an +arbitrary positive [integer](#integer). + +**Standard Scratch**: `300` + +**Modified Scratch**: None (many Scratch mods do not enforce this limit, though +memory overflow may eventually occur) + +### Ideas + +The following ideas are referenced throughout this specification: + +#### Asset + +A [costume](#costume) or [sound](#sound). + +##### Costume + +A costume is an [image file](https://en.wikipedia.org/wiki/Digital_image) and a +type of [asset](#asset) that can be graphically rendered to represent a +[target](#target). It can be identified by its [name](#name) or +[number](#integer). Costumes can either be +[bitmap](https://en.wikipedia.org/wiki/Raster_graphics) or +[vector](https://en.wikipedia.org/wiki/Vector_graphics). + +##### Sound + +A sound is an [audio file](https://en.wikipedia.org/wiki/Digital_audio) and a +type of [asset](#asset) that can be audibly played to the user via +[blocks](#block). It can be identified by its [name](#name). + +#### Block + +The fundamental component of Scratch as a programming language. In fact, they +are similar to function calls 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](#undefined)) + +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](#script). + +##### Standard Blocks + +[Blocks](#block) that are officially supported in Scratch 3.0. They are the most +commonly used blocks in [scripts](#script) by far. + +##### Hidden Blocks + +[Blocks](#block) 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](#script) may use them on occasion, but they are found less +often than [standard blocks](#standard-blocks) due to their obscurity. + +#### Clone + +A copy created of a [sprite](#sprite) that has all of the original sprite's +code, images, and sounds, but operates independently of it. Unlike sprites, +clones cannot be directly referenced via existing blocks (e.g. you cannot +[glide to](#glide-to-block) it directly without knowing its position ahead of +time, as it cannot be selected in the sprite dropdown menu), and exist as their +own thing. They are deleted every time the [flag](#flag) is clicked, and can +also be deleted manually using the +[`delete this clone` block](#delete-clone-block). + +Clones can be created with the [create clone block](#create-clone-block) so long +as the [maximum number of clones](#max-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](#when-i-start-as-a-clone-block). The +[stage](#stage) is the [target](#target) which cannot be cloned, whereas both +sprites _and clones_ can themselves be cloned. + +#### Edge + +Refers to the bounds that restrict the graphics of a [project](#project) from +exceeding its designated region on the user's screen. + +#### Flag + +> The usefulness of defining "Flag" is up for debate. Feel free to offer +> insight! + +The button that is intended to run scripts that start a project. It is also +known as the green flag in official Scratch. It is meant to make the project +`Go`, as it is labelled in its title text on the Scratch website. When clicked, +it runs any scripts under [when flag clicked blocks](#when-flag-clicked-block). + +#### 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](#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](#hidden-blocks), we can obtain +this type of value. + +#### List + +A series of [items](#item) stored together in sequence. Each item is referenced +by its numerical index (aka item #), a positive [integer](#integer) ranging from +`1` to the [length](#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](#max-items) that a list can hold, aka a limit to its +length. + +#### Mod + +A modification (altered version) of the Scratch 3.0 [runtime](#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 the +[relevant appendix](#nonstandard-blocks). + +#### Opcode + +A [name](#name) unique to every [block](#block) in the Scratch programming +language. It tells blocks what to do. For example, if the opcode of a block is +[`motion_movesteps`](#motion_movesteps), it attempts to move steps. + +#### Project + +A stage and optionally some sprites packaged together to do something. They can +be loaded into a [runtime](#runtime) and executed. They can also be saved as +[project files](#file-format). + +#### Runtime + +The environment in which a [project](#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](#file-format). + +#### Script + +A set of [blocks](#block) put together to create code. Here is an example of a +script: + +```sb +when flag clicked +ask [What's your name?] and wait +say (join [Hello, ] (join (answer) [!])) +stop [this script v] +``` + +Blocks are put together in the following ways: + +- TODO :D + +#### Sprite + +A kind of [target](#target) that can exist on its own, have +[variables](#variable) only it can set, and be moved, pointed, scaled, and +hidden, all of which are things that the [stage](#stage) cannot do. + +#### Stage + +A special [target](#target), with one and only one existing in every project, +that is shown behind all [sprites](#sprite). It is sort of like the +[global scope](https://en.wikipedia.org/wiki/Scope_(computer_science)#Global_scope) +found in some programming languages, but it also exists as its own entity. + +Unlike [sprites](#sprite), 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](#variable) (aka properties or fields) that are used by contained +[scripts](#script) to perform operations. + +Every target exists as its own unit independent of other targets, but they can +be interconnected in some ways. There are two kinds of targets * +[sprites](#sprite) and [stages](#stage). + +#### User + +The individual who is interacting with the [project](#project) and provides +input. They may optionally have a [username](#username) that the project can use +to identify them. + +#### Variable + +A container with a [name](#name) that can hold any one [value](#value). Every +variable is attached to a [target](#target). If it is attached to a +[sprite](#sprite), it can only be set by that sprite. If it is attached to the +[stage](#stage), it can be set by any sprite, including the stage. + +There are two kinds of variables. Some variables are defined and named by the +creator of a [project](#project) on a target-by-target basis and interacted with +by [variables blocks](#variables-blocks), while all targets have variables that +exist by default and can only be interacted with via their dedicated blocks (not +variable blocks). Some examples of user-defined variables would be `(score)` or +`(index)` (completely custom), while examples of built-in variables would be +`(x position)`, `(direction)`, `(size)`, `(volume)`, and `(tempo)` (exist in +every target). + +### Values + +In Scratch, the following types of values exist: + +- [String](#string) +- [Number](#number) +- + - [`NaN`](#nan) + - [`Infinity`](#infinity) + - [`-Infinity`](#-infinity) +- [Boolean](#boolean) + - [`true`](#true) + - [`false`](#false) +- [`undefined`](#undefined) + +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](#string), [number](#number), +[boolean](#boolean), or in rare cases [undefined](#undefined). +[Variables](#variable) can hold individual values, and a [list](#list) can store +many of them as [items](#item). + +#### Angle + +A [number](#number) intended to be in +[degrees](https://en.wikipedia.org/wiki/Degree_(angle)). `[sin v] of ()`, +`[cos v] of ()`, and `[tan v] of ()` expect angles as input. + +#### Answer + +A [string](#string) provided to the [project](#project) by the [user](#user) as +input via the [ask and wait block](#ask-and-wait-block). + +#### Boolean + +A special type of [value](#value) that is used to represent the result of a +logical operation. It is always either [`true`](#true) or [`false`](#false). + +##### True + +A kind of [boolean](#boolean) that is used to represent a yes or an affirmative +answer as a result of a logical operation. When casted to a [string](#string), +it is written as `true`. When casted to a [number](#number), it is casted to +`1`. It is considered [truthy](#truthy), as it is itself the definition of +truthy. + +##### False + +A kind of [boolean](#boolean) that is used to represent a no or a negative +answer as a result of a logical operation. When casted to a [string](#string), +it is written as `false`. When casted to a [number](#number), it is casted to +`0`. It is considered [falsy](#falsy), as it is itself the definition of falsy. + +#### Direction + +An [angle](#angle) that determines the way a sprite is turned on the screen. It +is always wrapped to remain in the range -179 and 181 (exclusive). An angle $a$ +can be converted to a direction $d$ like so: + +$d=\operatorname{mod}\left(a+179,360\right)-179$ + +Or in scratchblocks: + +```sb +set [direction v] to ((((angle) + (179)) mod (360)) * (179)) +``` + +The way that a sprite's direction impacts how it is rendered is determined by +that sprite's [rotation style](#rotation-style). + +#### Integer + +A [number](#number) that is not a fraction, aka a whole number (e.g. `42`, +`-37`). Many [blocks](#block) 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 + +A [value](#value) in a [list](#list). + +#### Key + +A [name](#name) used by Scratch for referring to a key on the [user](#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](#integer) representing how many [letters](#letter) or +[items](#item) there are in a [string](#string) or [list](#list), respectively. + +#### Letter + +An individual [UTF-16](https://en.wikipedia.org/wiki/UTF-16) +[code unit](https://developer.mozilla.org/en-US/docs/Glossary/Code_unit). +Several joined together create a [string](#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](#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](#username), or [sprite](#sprite). + +#### Number + +A [numerical](https://en.wikipedia.org/wiki/Number) [value](#value). Most +numbers are [real](https://en.wikipedia.org/wiki/Real_number) and can be +positive (`+`), negative (`-`), whole (`#`), or fractional (`#.#`). In +[JavaScript](#javascript), these numbers are internally stored as +[double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double_precision_floating-point_format) +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](#number) that is always greater than any other number. When +[casted](#to-string) to a [string](#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. + +```sb +[Infinity] + (1) // Infinity +[10 ^ v] of (1000) // Infinity +[log v] of (0) // -Infinity +(1) / [Infinity] // 0 +(1) / (0) // Infinity +``` + +##### -Infinity + +A special [number](#number) that is always lower than any other number. When +[casted](#to-string) to a [string](#string), it is written as `-Infinity`. It is +created in the same manner as [Infinity](#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](#number) that is not a number. When [casted](#to-string) to a +[string](#string), it is written as `NaN`. It is interpreted as a `0` when +passed as input to other mathematical operations, unlike in +[JavaScript](#javascript) where it causes most operations to report `NaN`. It +can be produced by doing unknown or unrepresentable things with numbers, such as +multiplying `Infinity` and zero, adding `Infinity` to `-Infinity`, or getting +the square root of a negative number. + +#### Rotation Style + +A [string](#string) that determines how a [sprite](#sprite)'s +[direction](#direction) impacts the way it is visibly rotated when rendered. +Officially, it can be one of the following strings: `all around`, `left-right`, +or `don't rotate`. + +- `all around`: The sprite faces in its direction **clockwise**. At `0`, it + faces **up**; at `90`, it faces **right**; at `180`, it faces **down**; and at + `-90`, it faces **left**. +- `left-right`: If the sprite's direction is less than `0`, 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_](#direction) 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) | + +##### Rotation Style: All Around + +![A demonstration of the "all around" rotation style](./img/all-around.gif) + +##### Rotation Style: Left-Right + +![A demonstration of the "left-right" rotation style](./img/left-right.gif) + +##### Rotation Style: Don't Rotate + +![A demonstration of the "don't rotate" rotation style](./img/don't-rotate.gif) + +#### String + +A type of [value](#value) consisting of a series (i.e. string) of +[letters](#letter), also known as text. All strings are considered +[truthy](#truthy) except for the [empty string](#empty-string). + +##### Empty String + +A [string](#string) containing no letters. It has a [length](#length) of `0` and +is the only string considered [falsy](#falsy). Also known as a "null string," it +can be used in place of a value where there is none, e.g. getting an +[item](#item) from a [list](#list) when it does not exist, or getting the +[answer](#answer) provided by a user when they have not been +[asked](#ask-and-wait-block) anything yet. + +#### Undefined + +A special [value](#value) that represents nothing. When converted to a +[string](#string), it is written as `undefined`. This type of value is uncommon +but can be produced by [hidden reporter blocks](#hidden-blocks). In most cases, +however, Scratch uses `0` or an empty string to represent nothing. + +#### Username + +A [name](#name) used to reference a [user](#user). In standard Scratch, +usernames are: + +- Always 3 to 20 [letters](#letter) [long](#length) (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](https://scratch.mit.edu). 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](https://en.scratch-wiki.info/wiki/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](#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](#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 Scratch through the official 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](#runtime) directly via developer tools like +> web inspector. + +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 to see if it is registered + with the Scratch website +- Remembering the usernames that the username block has reported (e.g. via cloud + variables) and see if it encounters the same username with different casing +- Checking to see if the username is changed while the project is running + (impossible without modification 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 +implementation 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](#string) that identifies a user. + +#### X Position + +A horizontal position on the Scratch coordinate plane. All [sprites](#sprite) +have one. (TODO: document coordinate system) + +#### Y Position + +A vertical position on the Scratch coordinate plane. All [sprites](#sprite) 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](#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](#turbowarp) that still + has largely the same behaviors to see how it would behave if somehow + obtained.) + - When [casted](#to-string) to a [string](#string), it is written as `null`. + - When [casted](#to-number) to a [number](#number), it is casted to `0`. + - When [casted](#to-boolean) to a [boolean](#boolean), it is + [`false`](#falsy). + +### Procedures + +The following procedures are often performed by Scratch and are mentioned +throughout this document: + +#### Casting + +Most blocks automatically convert [values](#value) between types through the use +of very particular logic, also known as +[casting](https://en.scratch-wiki.info/wiki/Casting). The logic Scratch uses is +specified below. + +##### To String + +Scratch uses the following logic to convert any given [value](#value) to a +[string](#string): + +- If the value is a [**string**](#string): + - **Return the value**, as it is already a string. +- If the value is a [**number**](#number): + - **Follow the + [logic JavaScript does](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)** + to cast a number to a string **and return it.** + - TODO: specify this better + - If the value is [**NaN**](#nan), **return the string `NaN`.** + - If the value is [**Infinity**](#infinity), **return the string `Infinity`.** + - If the value is [**-Infinity**](#infinity), **return the string + `-Infinity`.** +- If the value is a [**boolean**](#boolean): + - If the value is [**true**](#boolean), **return the string `true`.** + - If the value is [**false**](#boolean), **return the string `false`.** +- If the value is [**undefined**](#undefined), **return the string + `undefined`.** +- If the value is [**something else**](#other-values), **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 + +##### To Number + +Scratch uses the following logic to convert any given [value](#value) to a +[number](#number): + +- If the value is [**NaN**](#nan), **return the number `0`.** +- If the value is a [**number**](#number), **return the value** as it is. +- If the value is [**undefined**](#undefined), **return the number `0`.** +- If the value is [**true**](#true), **return the number `1`.** +- If the value is [**false**](#false), **return the number `0`.** +- If the value is a [**string**](#string) or [something else](#other-values): + - **If the value can be converted to a number** according to + [these rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_coercion) + **, 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](#value) to a +[boolean](#boolean): + +###### Falsy + +A value is **falsy**, or casted to [**false**](#false), if the value is: + +- an [**empty string**](#empty-string) (no letters, [length](#length) is `0`), +- the **[strings](#string) `0`** or **`false`** (case-insensitive), +- one of the **[numbers](#number) `0`**, **`-0`**, or [**`NaN`**](#nan), +- [**undefined**](#undefined), +- **null** (rare), +- or **false**. + +###### Truthy + +Any value that is **not** [**falsy**](#falsy) is considered **truthy** and +casted to [**true**](#true). + +##### To Direction + +Scratch uses the following logic to convert any given [value](#value) to a +[direction](#direction): + +1. [**Cast the value to number**](#to-number). +2. **Plug the casted value** into the following equation **as $a$ to find $d$:** + - $d=\operatorname{mod}\left(a+179,360\right)-179$ + - Here is the same equation written in blocks: + + ```sb + set [direction v] to ((((angle) + (179)) mod (360)) * (179)) + ``` + +3. **Return $d$** (`direction`)**.** + +#### Fencing + +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 :D + +##### 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. + +## Palette + +This section documents each and every block in Scratch, and its precise +functionality. + +> 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 + +> 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](#sb3) [file format](#file-format). + +**Operation:** + +A brief overview of the block's function and essential info. + +**Block:** + +```sb +the block in scratchblocks with its [ARG]uments +``` + +**Arguments:** + +| Name: | [Casted](#casting) 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](#values) | 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](#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:** + +```sb +move (STEPS) steps +``` + +**Arguments**: + +| Name: | [Casted](#casting) to: | Provides the: | +| :-----: | :--------------------: | :-----------------------------------: | +| `STEPS` | [number](#to-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, whereas 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: + +$x' = x + \sin(d) \cdot S$ + +$y' = y + \cos(d) \cdot S$ + +Where $S$ is the `STEPS` to move, $d$ is the direction of the sprite, and $x$ +and $y$ are the x and y positions of the sprite, respectively. + +In scratchblocks, this operation can also be replicated as: + +```sb +go to x: ((x position) + (([sin v] of (direction)) * (STEPS))) y: ((y position) + (([cos v] of (direction)) * (STEPS))) +``` + +After the sprite is moved, its position is [fenced](#fencing-position). + +#### 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](#runtime) context. + +#### Standard sensing blocks + +These sensing blocks are officially supported in Scratch 3.0: + +TODO + +##### sensing_username + +**Operation:** + +Reports the [username](#username) of the [user](#user) that has loaded the +[project](#project) in the context of the Scratch website. + +**Block:** + +```sb +(username) +``` + +**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](#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](#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 appendix](#nonstandard-blocks), +> though it will have to be clarified that these blocks can be loaded into +> Scratch, they just don't do anything outside of [mods](#mod). + +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](#mod). + +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 + +## Appendices + +This section is for additional information about Scratch that is not necessarily +relevant to its runtime behavior, but is good to know in addition, especially +for creating highly compatible and feature-complete Scratch implementations. + +### 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](#runtime) +environment, a saved project that is not properly loaded may not work as it was +intended to, and could very well break! + +#### 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](https://en.wikipedia.org/wiki/ZIP_(file_format)) file +that contains the following files: + +- `project.json`, a [.json](https://en.wikipedia.org/wiki/JSON) file storing + info. +- Various image files used as [costumes](#costume). +- Various audio files used as [sounds](#sound). + +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](#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](#sb2) and [.sb3](#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! + +### Obsolete Blocks + +> 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 [runtime](#runtime) 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 + +> 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](https://en.wikipedia.org/wiki/Porting) of +> Scratch). + +This section serves to document blocks that do not exist at all in Scratch, but +have been added unofficially to [modifications](#mod) of Scratch. This includes +both blocks added as "custom extensions," and blocks added directly to the +[palette](#palette). They are specified here in order to allow projects using +these nonstandard blocks to function properly if one were to reimplement the +Scratch VM with implementing these blocks in mind. + +> This is a dynamic section and may never be able to satisfy any particular +> standards for completeness. [You can help](#contributing) by adding +> [missing blocks](#todo-blocks) with reliable sources (e.g. links to source +> code). + +#### Example nonstandard block + +> 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:** + +```sb +the block in scratchblocks with its [ARG]uments +``` + +**Arguments:** + +| Name: | [Casted](#casting) 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](#values) | What it provides to the block. | + +**Procedure:** + +A deep dive into what the block does in fulfilling its operation. + +#### TurboWarp + +[TurboWarp](https://turbowarp.org/) 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:** + +```sb +(last key pressed) +``` + +**Arguments:** + +None + +**Procedure:** + +When the [runtime](#runtime) first starts, no [keys](#key) have been pressed. If +the block is run before any keys are pressed, it reports the +[empty string](#empty-string). Otherwise, the [name](#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](#special-custom-blocks) without definitions +in disguise! + +#### PenguinMod + +[PenguinMod](https://penguinmod.com/) is a mod of [TurboWarp](#turbowarp). It +supports most TurboWarp extensions and introduces some community-made ones of +its own. + +TODO: Document PenguinMod blocks + +#### snail-ide + +[Snail IDE](https://snail-ide.js.org/) is a mod of [PenguinMod](#penguinmod). It +supports most of PenguinMod's blocks and adds some of its own. + +TODO: Document Snail IDE blocks + +#### Unsandboxed + +[Unsandboxed](https://alpha.unsandboxed.org/#0) is a mod of +[TurboWarp](#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](#contributing) information on it! Though if you do, please remember +that this a language specification for Scratch's runtime behavior, not a +[wiki](https://scratch-wiki.info/) 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](#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](#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](#turbowarp) is in + the [Addon blocks](#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. + +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‍_!_](https://snap.berkeley.edu/) 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](https://snap.berkeley.edu/snap/help/SnapManual.pdf) instead. diff --git a/intro.md b/intro.md new file mode 100644 index 0000000..aee148e --- /dev/null +++ b/intro.md @@ -0,0 +1,69 @@ +# Introduction + +This document is a serious attempt to create a [programming language specification](https://en.wikipedia.org/wiki/Programming_language_specification) of [Scratch 3.0](https://en.scratch-wiki.info/wiki/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](https://en.wikipedia.org/wiki/Porting) of it to other platforms. This project is entirely "for fun" (note the quotation marks) and is not affilated with the [Scratch Foundation](https://www.scratchfoundation.org/) or related parties in any way whatsoever, though please [donate](https://www.scratchfoundation.org/donate) to them if you can so that they may continue to support and improve [Scratch](https://scratch.mit.edu/) 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](https://en.wikipedia.org/wiki/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](https://scratchblocks.github.io/) [syntax](https://en.scratch-wiki.info/wiki/Block_Plugin/Syntax).** This text-based format is used to represent Scratch [blocks](#block). An option to render the scratchblocks while viewing in-browser is being considered; however, the shapes and colors of the blocks are not necessarily being documented here, but rather their functionality. + +## Sources + +The information about Scratch in this specification is, of course, derived from Scratch sources, e.g. the Scratch [VM](https://github.com/scratchfoundation/scratch-vm), [Wiki](https://scratch-wiki.info/), [Website](https://scratch.mit.edu/), [Editor](https://scratch.mit.edu/projects/editor), and [Discussion Forums](https://scratch.mit.edu/discuss/). [Wikipedia](https://wikipedia.org/wiki/Wikipedia:About) and [MDN Web Docs](https://developer.mozilla.org/) are linked to as well for additional information regarding general concepts and internal behaviors. + +## Contributing + +Please [contribute on GitHub](https://github.com/OceanIsEndless/scratch-spec/pulls) (must be **13** or older, [need a GitHub account](https://github.com/signup)) or [comment on my Scratch profile](https://scratch.mit.edu/users/Endless-Ocean/#comments) (just [need a Scratch account](https://scratch.mit.edu/join)) 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 + +## FAQ + +*Questions that would be frequently asked if someone were to ask them.* + +### Where to start? + +* If you want a **general understanding** of Scratch's inner workings for whatever reason, find whatever interests you in the [table of contents](#contents) and just gloss over whatever you don't need to know. +* If you want **formal definitions** of Scratch terms, see [concepts](#concepts). +* If you want to accurately **recreate blocks**, see the [palette](#palette). + +TODO: Threading and execution behavior will be documented soon! + +* If you want to learn about project files, see [file format](#file-format). +* If you want to recreate old blocks, see [obsolete blocks](#obsolete-blocks). +* If you want more blocks, see [nonstandard blocks](#nonstandard-blocks). + +### 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](https://www.desmos.com/calculator) packager, or porting Scratch to the [Wii](https://en.wikipedia.org/wiki/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 help this super cool rapidly-developing [3DS port](https://github.com/NateXS/Scratch-3DS), 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](https://scratch-wiki.info/) 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](#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](https://blob.codes/scratch-is-cool/). It is [Turing-complete](https://en.wikipedia.org/wiki/Turing_completeness). Lots of languages far less significant than Scratch have [programming language specifications](https://en.wikipedia.org/wiki/Programming_language_specification). 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***](https://en.wikipedia.org/wiki/Scratch_(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? diff --git a/package.json b/package.json new file mode 100644 index 0000000..462a190 --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "scripts": { + "docs:dev": "vitepress dev", + "docs:build": "vitepress build", + "docs:preview": "vitepress preview" + }, + "dependencies": { + "vitepress": "^1.6.3" + } +} \ No newline at end of file From 703bf819040ed09ece4c6879ef2815587777a387 Mon Sep 17 00:00:00 2001 From: Grady Link Date: Mon, 28 Jul 2025 13:10:39 -0700 Subject: [PATCH 2/4] feat: did some more stuff --- .vitepress/config.mts | 9 + concepts/capabilities.md | 19 + concepts/constants.md | 69 ++ faq.md | 42 ++ index.md | 1471 +++++++++++--------------------------- intro.md | 43 -- todo.md | 76 ++ 7 files changed, 647 insertions(+), 1082 deletions(-) create mode 100644 concepts/capabilities.md create mode 100644 concepts/constants.md create mode 100644 faq.md create mode 100644 todo.md diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 6273922..256c256 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -10,6 +10,15 @@ export default defineConfig({ items: [ { text: "Contents", link: "/" }, { text: "Introduction", link: "/intro" }, + { text: "FAQ", link: "faq" }, + { text: "TODO", link: "/todo" }, + ], + }, + { + text: "Concepts", + items: [ + { text: "Capabilities", link: "/concepts/capabilities" }, + { text: "Constants", link: "/concepts/constants" }, ], }, ], diff --git a/concepts/capabilities.md b/concepts/capabilities.md new file mode 100644 index 0000000..6cfc215 --- /dev/null +++ b/concepts/capabilities.md @@ -0,0 +1,19 @@ +# Capabilities + +At its core, Scratch should be able to: + +* Run scripts dynamically; multithreading, looping, timing, etc. +* Show images on a screen; position, size, turn + draw graphics. +* Play sounds on speakers; several audio files can play at once. + +In an ideal situation, it should also be able to: + +* Apply effects to images and sounds +* Detect loudness via microphone +* Interact with linked devices +* Draw graphics dynamically +* Make requests to the web +* Know the current time +* Receive user input + +A fully functional implementation of Scratch should be capable of all these things, and if not handle it gracefully, this document detailing how to deal with everything. diff --git a/concepts/constants.md b/concepts/constants.md new file mode 100644 index 0000000..8ff9f9e --- /dev/null +++ b/concepts/constants.md @@ -0,0 +1,69 @@ +# Constants + +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. + +## Stage Bounds + +### Stage Width + +The horizontal size of the stage. This is an arbitrary positive [integer](#integer). + +**Standard Scratch**: `480` + +**Widescreen** (via unofficial modification): `640` + +### Stage Height + +The vertical size of the stage. This is an arbitrary positive [integer](#integer). + +**Standard Scratch**: `360` + +### Left Edge + +The horizontal position of the left edge. This is derived from the [stage width](#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](#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](#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](#stage-height). + +**Formula**: `stage height / -2` + +**Standard Scratch**: `-180` + +## Limits + +### Max Items + +The maximum [length](#length) of a [list](#list), aka the most items that one list can hold. This limit is imposed to prevent excessive memory usage by [projects](#project). This is an arbitrary positive [integer](#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](#clone) that can exist at one 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](#project). This is an arbitrary positive [integer](#integer). + +**Standard Scratch**: `300` + +**Modified Scratch**: None (many Scratch mods do not enforce this limit, though memory overflow may eventually occur) diff --git a/faq.md b/faq.md new file mode 100644 index 0000000..503c06e --- /dev/null +++ b/faq.md @@ -0,0 +1,42 @@ +# FAQ + +*Questions that would be frequently asked if someone were to ask them.* + +## Where to start? + +* If you want a **general understanding** of Scratch's inner workings for whatever reason, find whatever interests you in the [table of contents](#contents) and just gloss over whatever you don't need to know. +* If you want **formal definitions** of Scratch terms, see [concepts](#concepts). +* If you want to accurately **recreate blocks**, see the [palette](#palette). + +TODO: Threading and execution behavior will be documented soon! + +* If you want to learn about project files, see [file format](#file-format). +* If you want to recreate old blocks, see [obsolete blocks](#obsolete-blocks). +* If you want more blocks, see [nonstandard blocks](#nonstandard-blocks). + +## 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](https://www.desmos.com/calculator) packager, or porting Scratch to the [Wii](https://en.wikipedia.org/wiki/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 help this super cool rapidly-developing [3DS port](https://github.com/NateXS/Scratch-3DS), 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](https://scratch-wiki.info/) 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](#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](https://blob.codes/scratch-is-cool/). It is [Turing-complete](https://en.wikipedia.org/wiki/Turing_completeness). Lots of languages far less significant than Scratch have [programming language specifications](https://en.wikipedia.org/wiki/Programming_language_specification). 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***](https://en.wikipedia.org/wiki/Scratch_(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? diff --git a/index.md b/index.md index a5a5aff..ccb368d 100644 --- a/index.md +++ b/index.md @@ -4,365 +4,158 @@ A detailed explanation of how Scratch 3.0 works as a programming language. ## Contents -- [Scratch Specification](#scratch-specification) - - [Contents](#contents) - - [Introduction](/intro) - - [Preliminaries](/intro#preliminaries) - - [Sources](/intro#sources) - - [Contributing](/intro#contributing) - - [FAQ](/intro#faq) - - [Where to start?](/intro#where-to-start) - - [What's the point?](/intro#whats-the-point) - - [Why?](/intro#why) - - [TODO](#todo) - - [TODO: Blocks](#todo-blocks) - - [Concepts](#concepts) - - [Capabilities](#capabilities) - - [Constants](#constants) - - [Stage Bounds](#stage-bounds) - - [Stage Width](#stage-width) - - [Stage Height](#stage-height) - - [Left Edge](#left-edge) - - [Right Edge](#right-edge) - - [Top Edge](#top-edge) - - [Bottom Edge](#bottom-edge) - - [Limits](#limits) - - [Max Items](#max-items) - - [Max Clones](#max-clones) - - [Ideas](#ideas) - - [Asset](#asset) - - [Costume](#costume) - - [Sound](#sound) - - [Block](#block) - - [Standard Blocks](#standard-blocks) - - [Hidden Blocks](#hidden-blocks) - - [Clone](#clone) - - [Edge](#edge) - - [Flag](#flag) - - [JavaScript](#javascript) - - [List](#list) - - [Mod](#mod) - - [Opcode](#opcode) - - [Project](#project) - - [Runtime](#runtime) - - [Script](#script) - - [Sprite](#sprite) - - [Stage](#stage) - - [Target](#target) - - [User](#user) - - [Variable](#variable) - - [Values](#values) - - [Value](#value) - - [Angle](#angle) - - [Answer](#answer) - - [Boolean](#boolean) - - [True](#true) - - [False](#false) - - [Direction](#direction) - - [Integer](#integer) - - [Item](#item) - - [Key](#key) - - [Length](#length) - - [Letter](#letter) - - [Name](#name) - - [Number](#number) - - [Infinity](#infinity) - - [-Infinity](#-infinity) - - [NaN](#nan) - - [Rotation Style](#rotation-style) - - [Rotation Style: All Around](#rotation-style-all-around) - - [Rotation Style: Left-Right](#rotation-style-left-right) - - [Rotation Style: Don't Rotate](#rotation-style-dont-rotate) - - [String](#string) - - [Empty String](#empty-string) - - [Undefined](#undefined) - - [Username](#username) - - [X Position](#x-position) - - [Y Position](#y-position) - - [Other Values](#other-values) - - [Procedures](#procedures) - - [Casting](#casting) - - [To String](#to-string) - - [To Number](#to-number) - - [To Boolean](#to-boolean) - - [Falsy](#falsy) - - [Truthy](#truthy) - - [To Direction](#to-direction) - - [Fencing](#fencing) - - [Fencing Position](#fencing-position) - - [Fencing Size](#fencing-size) - - [Palette](#palette) - - [Example block](#example-block) - - [Motion blocks](#motion-blocks) - - [Standard motion blocks](#standard-motion-blocks) - - [motion\_movesteps](#motion_movesteps) - - [Hidden motion blocks](#hidden-motion-blocks) - - [Looks blocks](#looks-blocks) - - [Standard looks blocks](#standard-looks-blocks) - - [Hidden looks blocks](#hidden-looks-blocks) - - [Sound blocks](#sound-blocks) - - [Standard sound blocks](#standard-sound-blocks) - - [Hidden sound blocks](#hidden-sound-blocks) - - [Events blocks](#events-blocks) - - [Standard events blocks](#standard-events-blocks) - - [Hidden events blocks](#hidden-events-blocks) - - [Control blocks](#control-blocks) - - [Standard control blocks](#standard-control-blocks) - - [Hidden control blocks](#hidden-control-blocks) - - [Sensing blocks](#sensing-blocks) - - [Standard sensing blocks](#standard-sensing-blocks) - - [sensing\_username](#sensing_username) - - [Hidden sensing blocks](#hidden-sensing-blocks) - - [Operators blocks](#operators-blocks) - - [Standard operators blocks](#standard-operators-blocks) - - [Hidden operators blocks](#hidden-operators-blocks) - - [Variables blocks](#variables-blocks) - - [Standard variables blocks](#standard-variables-blocks) - - [Hidden variables blocks](#hidden-variables-blocks) - - [List blocks](#list-blocks) - - [Standard list blocks](#standard-list-blocks) - - [Hidden list blocks](#hidden-list-blocks) - - [Custom blocks](#custom-blocks) - - [Standard custom blocks](#standard-custom-blocks) - - [Hidden custom blocks](#hidden-custom-blocks) - - [Special custom blocks](#special-custom-blocks) - - [Music blocks](#music-blocks) - - [Pen blocks](#pen-blocks) - - [Video Sensing blocks](#video-sensing-blocks) - - [Text to Speech blocks](#text-to-speech-blocks) - - [Translate blocks](#translate-blocks) - - [Makey Makey blocks](#makey-makey-blocks) - - [micro:bit blocks](#microbit-blocks) - - [LEGO EV3 blocks](#lego-ev3-blocks) - - [BOOST blocks](#boost-blocks) - - [WeDo 2.0 blocks](#wedo-20-blocks) - - [Force and Acceleration blocks](#force-and-acceleration-blocks) - - [CoreEx blocks](#coreex-blocks) - - [Standard CoreEx blocks](#standard-coreex-blocks) - - [Hidden CoreEx blocks](#hidden-coreex-blocks) - - [Appendices](#appendices) - - [File Format](#file-format) - - [SB3](#sb3) - - [SB2](#sb2) - - [SB](#sb) - - [Obsolete Blocks](#obsolete-blocks) - - [Nonstandard Blocks](#nonstandard-blocks) - - [Example nonstandard block](#example-nonstandard-block) - - [TurboWarp](#turbowarp) - - [TurboWarp blocks](#turbowarp-blocks) - - [Last key pressed block](#last-key-pressed-block) - - [Addon blocks](#addon-blocks) - - [PenguinMod](#penguinmod) - - [snail-ide](#snail-ide) - - [Unsandboxed](#unsandboxed) - - [Adding Platforms](#adding-platforms) - -## TODO - -> This spec is a work in progress; it's nowhere near complete. **Please -> [contribute](#contributing) 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. - -Various things need to be worked on to make this a good resource: - -- **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 its structure should be as well. -- ⚠️ ‼️ **Cite reliable sources.** ‼️ ⚠️ This specification should provide - references to the code of Scratch itself (not just wikis) to prove its claims - and hopefully be an accurate source of information about the Scratch - programming language. It has not been decided how to best reference material - though. (Just link them, or go wiki style?) - -### 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 checked off.) Specifying [standard](#palette) blocks -is the first priority. Once they are documented, the scope of this spec can be -expanded to include [hidden](#hidden-blocks), [obsolete](#obsolete-blocks), and -even [nonstandard](#nonstandard-blocks) blocks as well, probably in that order. - -
- Click to view block list - -- [ ] [Motion Blocks](#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 [left-right]` - - [ ] `(x position)` - - [ ] `(y position)` - - [ ] `(direction)` - - [ ] [**Hidden**](#hidden-blocks) (**specify** what they do, even if nothing - at all) - - [ ] `scroll right ()` - - [ ] `scroll up ()` - - [ ] `align scene [ v]` - - [ ] `(x scroll)` - - [ ] `(y scroll)` - - [ ] [**Obsolete**](#obsolete-blocks) (**imagine** what they _would_ do if - kept operational) - - [ ] `scroll right ()` - - [ ] `scroll up ()` - - [ ] `align scene [ v]` - - [ ] `(x scroll)` - - [ ] `(y scroll)` - - [ ] [**Nonstandard**](#nonstandard-blocks) (blocks that [mods](#mod) of - Scratch added) - - [ ] [PenguinMod](#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](#unsandboxed) - - [ ] `(rotation style)` -- [ ] [Looks blocks](#looks-blocks) -- [ ] [Sound blocks](#sound-blocks) -- [ ] [Events blocks](#events-blocks) -- [ ] [Control blocks](#control-blocks) -- [ ] [Sensing blocks](#sensing-blocks) -- [ ] [Operators blocks](#operators-blocks) -- [ ] [Variables blocks](#variables-blocks) -- [ ] [List blocks](#list-blocks) -- [ ] [Custom blocks](#custom-blocks) -- [ ] [Addon blocks](#addon-blocks) -- [ ] _other categories of blocks_ -- [ ] TODO: Write list of blocks TODO :) - -
- -## Concepts - -This section explains the various concepts and rules of Scratch. - -### Capabilities - -At its core, Scratch should be able to: - -- Run scripts dynamically; multithreading, looping, timing, etc. -- Show images on a screen; position, size, turn + draw graphics. -- Play sounds on speakers; several audio files can play at once. - -In an ideal situation, it should also be able to: - -- Apply effects to images and sounds -- Detect loudness via microphone -- Interact with linked devices -- Draw graphics dynamically -- Make requests to the web -- Know the current time -- Receive user input - -A fully functional implementation of Scratch should be capable of all these -things, and if not handle it gracefully, this document detailing how to deal -with everything. - -### Constants - -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. - -#### Stage Bounds - -##### Stage Width - -The horizontal size of the stage. This is an arbitrary positive -[integer](#integer). - -**Standard Scratch**: `480` - -**Widescreen** (via unofficial modification): `640` - -##### Stage Height - -The vertical size of the stage. This is an arbitrary positive -[integer](#integer). - -**Standard Scratch**: `360` - -##### Left Edge - -The horizontal position of the left edge. This is derived from the -[stage width](#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](#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](#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](#stage-height). - -**Formula**: `stage height / -2` - -**Standard Scratch**: `-180` - -#### Limits - -##### Max Items - -The maximum [length](#length) of a [list](#list), aka the most items that one -list can hold. This limit is imposed to prevent excessive memory usage by -[projects](#project). This is an arbitrary positive [integer](#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](#clone) that can exist at one 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](#project). This is an -arbitrary positive [integer](#integer). - -**Standard Scratch**: `300` - -**Modified Scratch**: None (many Scratch mods do not enforce this limit, though -memory overflow may eventually occur) +* [Scratch Specification](#scratch-specification) + * [Contents](#contents) + * [Introduction](/intro) + * [Preliminaries](/intro#preliminaries) + * [Sources](/intro#sources) + * [Contributing](/intro#contributing) + * [FAQ](/faq) + * [Where to start?](/faq#where-to-start) + * [What's the point?](/faq#whats-the-point) + * [Why?](/faq#why) + * [TODO](todo) + * [TODO: Blocks](/todo#todo-blocks) + * Concepts + * [Capabilities](/concepts/capabilities) + * [Constants](/constants) + * [Stage Bounds](/constants#stage-bounds) + * [Stage Width](/constants#stage-width) + * [Stage Height](/constants#stage-height) + * [Left Edge](/constants#left-edge) + * [Right Edge](/constants#right-edge) + * [Top Edge](/constants#top-edge) + * [Bottom Edge](/constants#bottom-edge) + * [Limits](/constants#limits) + * [Max Items](/constants#max-items) + * [Max Clones](/constants#max-clones) + * [Ideas](#ideas) + * [Asset](#asset) + * [Costume](#costume) + * [Sound](#sound) + * [Block](#block) + * [Standard Blocks](#standard-blocks) + * [Hidden Blocks](#hidden-blocks) + * [Clone](#clone) + * [Edge](#edge) + * [Flag](#flag) + * [JavaScript](#javascript) + * [List](#list) + * [Mod](#mod) + * [Opcode](#opcode) + * [Project](#project) + * [Runtime](#runtime) + * [Script](#script) + * [Sprite](#sprite) + * [Stage](#stage) + * [Target](#target) + * [User](#user) + * [Variable](#variable) + * [Values](#values) + * [Value](#value) + * [Angle](#angle) + * [Answer](#answer) + * [Boolean](#boolean) + * [True](#true) + * [False](#false) + * [Direction](#direction) + * [Integer](#integer) + * [Item](#item) + * [Key](#key) + * [Length](#length) + * [Letter](#letter) + * [Name](#name) + * [Number](#number) + * [Infinity](#infinity) + * [-Infinity](#-infinity) + * [NaN](#nan) + * [Rotation Style](#rotation-style) + * [Rotation Style: All Around](#rotation-style-all-around) + * [Rotation Style: Left-Right](#rotation-style-left-right) + * [Rotation Style: Don't Rotate](#rotation-style-dont-rotate) + * [String](#string) + * [Empty String](#empty-string) + * [Undefined](#undefined) + * [Username](#username) + * [X Position](#x-position) + * [Y Position](#y-position) + * [Other Values](#other-values) + * [Procedures](#procedures) + * [Casting](#casting) + * [To String](#to-string) + * [To Number](#to-number) + * [To Boolean](#to-boolean) + * [Falsy](#falsy) + * [Truthy](#truthy) + * [To Direction](#to-direction) + * [Fencing](#fencing) + * [Fencing Position](#fencing-position) + * [Fencing Size](#fencing-size) + * [Palette](#palette) + * [Example block](#example-block) + * [Motion blocks](#motion-blocks) + * [Standard motion blocks](#standard-motion-blocks) + * [motion\_movesteps](#motion_movesteps) + * [Hidden motion blocks](#hidden-motion-blocks) + * [Looks blocks](#looks-blocks) + * [Standard looks blocks](#standard-looks-blocks) + * [Hidden looks blocks](#hidden-looks-blocks) + * [Sound blocks](#sound-blocks) + * [Standard sound blocks](#standard-sound-blocks) + * [Hidden sound blocks](#hidden-sound-blocks) + * [Events blocks](#events-blocks) + * [Standard events blocks](#standard-events-blocks) + * [Hidden events blocks](#hidden-events-blocks) + * [Control blocks](#control-blocks) + * [Standard control blocks](#standard-control-blocks) + * [Hidden control blocks](#hidden-control-blocks) + * [Sensing blocks](#sensing-blocks) + * [Standard sensing blocks](#standard-sensing-blocks) + * [sensing\_username](#sensing_username) + * [Hidden sensing blocks](#hidden-sensing-blocks) + * [Operators blocks](#operators-blocks) + * [Standard operators blocks](#standard-operators-blocks) + * [Hidden operators blocks](#hidden-operators-blocks) + * [Variables blocks](#variables-blocks) + * [Standard variables blocks](#standard-variables-blocks) + * [Hidden variables blocks](#hidden-variables-blocks) + * [List blocks](#list-blocks) + * [Standard list blocks](#standard-list-blocks) + * [Hidden list blocks](#hidden-list-blocks) + * [Custom blocks](#custom-blocks) + * [Standard custom blocks](#standard-custom-blocks) + * [Hidden custom blocks](#hidden-custom-blocks) + * [Special custom blocks](#special-custom-blocks) + * [Music blocks](#music-blocks) + * [Pen blocks](#pen-blocks) + * [Video Sensing blocks](#video-sensing-blocks) + * [Text to Speech blocks](#text-to-speech-blocks) + * [Translate blocks](#translate-blocks) + * [Makey Makey blocks](#makey-makey-blocks) + * [micro:bit blocks](#microbit-blocks) + * [LEGO EV3 blocks](#lego-ev3-blocks) + * [BOOST blocks](#boost-blocks) + * [WeDo 2.0 blocks](#wedo-20-blocks) + * [Force and Acceleration blocks](#force-and-acceleration-blocks) + * [CoreEx blocks](#coreex-blocks) + * [Standard CoreEx blocks](#standard-coreex-blocks) + * [Hidden CoreEx blocks](#hidden-coreex-blocks) + * [Appendices](#appendices) + * [File Format](#file-format) + * [SB3](#sb3) + * [SB2](#sb2) + * [SB](#sb) + * [Obsolete Blocks](#obsolete-blocks) + * [Nonstandard Blocks](#nonstandard-blocks) + * [Example nonstandard block](#example-nonstandard-block) + * [TurboWarp](#turbowarp) + * [TurboWarp blocks](#turbowarp-blocks) + * [Last key pressed block](#last-key-pressed-block) + * [Addon blocks](#addon-blocks) + * [PenguinMod](#penguinmod) + * [snail-ide](#snail-ide) + * [Unsandboxed](#unsandboxed) + * [Adding Platforms](#adding-platforms) ### Ideas @@ -374,132 +167,75 @@ A [costume](#costume) or [sound](#sound). ##### Costume -A costume is an [image file](https://en.wikipedia.org/wiki/Digital_image) and a -type of [asset](#asset) that can be graphically rendered to represent a -[target](#target). It can be identified by its [name](#name) or -[number](#integer). Costumes can either be -[bitmap](https://en.wikipedia.org/wiki/Raster_graphics) or -[vector](https://en.wikipedia.org/wiki/Vector_graphics). +A costume is an [image file](https://en.wikipedia.org/wiki/Digital_image) and a type of [asset](#asset) that can be graphically rendered to represent a [target](#target). It can be identified by its [name](#name) or [number](#integer). Costumes can either be [bitmap](https://en.wikipedia.org/wiki/Raster_graphics) or [vector](https://en.wikipedia.org/wiki/Vector_graphics). ##### Sound -A sound is an [audio file](https://en.wikipedia.org/wiki/Digital_audio) and a -type of [asset](#asset) that can be audibly played to the user via -[blocks](#block). It can be identified by its [name](#name). +A sound is an [audio file](https://en.wikipedia.org/wiki/Digital_audio) and a type of [asset](#asset) that can be audibly played to the user via [blocks](#block). It can be identified by its [name](#name). #### Block -The fundamental component of Scratch as a programming language. In fact, they -are similar to function calls in other programming languages. Every block: +The fundamental component of Scratch as a programming language. In fact, they are similar to function calls 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](#undefined)) +* 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](#undefined)) -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](#script). +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](#script). ##### Standard Blocks -[Blocks](#block) that are officially supported in Scratch 3.0. They are the most -commonly used blocks in [scripts](#script) by far. +[Blocks](#block) that are officially supported in Scratch 3.0. They are the most commonly used blocks in [scripts](#script) by far. ##### Hidden Blocks -[Blocks](#block) 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](#script) may use them on occasion, but they are found less -often than [standard blocks](#standard-blocks) due to their obscurity. +[Blocks](#block) 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](#script) may use them on occasion, but they are found less often than [standard blocks](#standard-blocks) due to their obscurity. #### Clone -A copy created of a [sprite](#sprite) that has all of the original sprite's -code, images, and sounds, but operates independently of it. Unlike sprites, -clones cannot be directly referenced via existing blocks (e.g. you cannot -[glide to](#glide-to-block) it directly without knowing its position ahead of -time, as it cannot be selected in the sprite dropdown menu), and exist as their -own thing. They are deleted every time the [flag](#flag) is clicked, and can -also be deleted manually using the -[`delete this clone` block](#delete-clone-block). - -Clones can be created with the [create clone block](#create-clone-block) so long -as the [maximum number of clones](#max-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](#when-i-start-as-a-clone-block). The -[stage](#stage) is the [target](#target) which cannot be cloned, whereas both -sprites _and clones_ can themselves be cloned. +A copy created of a [sprite](#sprite) that has all of the original sprite's code, images, and sounds, but operates independently of it. Unlike sprites, clones cannot be directly referenced via existing blocks (e.g. you cannot [glide to](#glide-to-block) it directly without knowing its position ahead of time, as it cannot be selected in the sprite dropdown menu), and exist as their own thing. They are deleted every time the [flag](#flag) is clicked, and can also be deleted manually using the [`delete this clone` block](#delete-clone-block). + +Clones can be created with the [create clone block](#create-clone-block) so long as the [maximum number of clones](#max-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](#when-i-start-as-a-clone-block). The [stage](#stage) is the [target](#target) which cannot be cloned, whereas both sprites *and clones* can themselves be cloned. #### Edge -Refers to the bounds that restrict the graphics of a [project](#project) from -exceeding its designated region on the user's screen. +Refers to the bounds that restrict the graphics of a [project](#project) from exceeding its designated region on the user's screen. #### Flag -> The usefulness of defining "Flag" is up for debate. Feel free to offer -> insight! +> The usefulness of defining "Flag" is up for debate. Feel free to offer insight! -The button that is intended to run scripts that start a project. It is also -known as the green flag in official Scratch. It is meant to make the project -`Go`, as it is labelled in its title text on the Scratch website. When clicked, -it runs any scripts under [when flag clicked blocks](#when-flag-clicked-block). +The button that is intended to run scripts that start a project. It is also known as the green flag in official Scratch. It is meant to make the project `Go`, as it is labelled in its title text on the Scratch website. When clicked, it runs any scripts under [when flag clicked blocks](#when-flag-clicked-block). #### 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! +> 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](#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](#hidden-blocks), we can obtain -this type of value. +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](#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](#hidden-blocks), we can obtain this type of value. #### List -A series of [items](#item) stored together in sequence. Each item is referenced -by its numerical index (aka item #), a positive [integer](#integer) ranging from -`1` to the [length](#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](#max-items) that a list can hold, aka a limit to its -length. +A series of [items](#item) stored together in sequence. Each item is referenced by its numerical index (aka item #), a positive [integer](#integer) ranging from `1` to the [length](#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](#max-items) that a list can hold, aka a limit to its length. #### Mod -A modification (altered version) of the Scratch 3.0 [runtime](#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 the -[relevant appendix](#nonstandard-blocks). +A modification (altered version) of the Scratch 3.0 [runtime](#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 the [relevant appendix](#nonstandard-blocks). #### Opcode -A [name](#name) unique to every [block](#block) in the Scratch programming -language. It tells blocks what to do. For example, if the opcode of a block is -[`motion_movesteps`](#motion_movesteps), it attempts to move steps. +A [name](#name) unique to every [block](#block) in the Scratch programming language. It tells blocks what to do. For example, if the opcode of a block is [`motion_movesteps`](#motion_movesteps), it attempts to move steps. #### Project -A stage and optionally some sprites packaged together to do something. They can -be loaded into a [runtime](#runtime) and executed. They can also be saved as -[project files](#file-format). +A stage and optionally some sprites packaged together to do something. They can be loaded into a [runtime](#runtime) and executed. They can also be saved as [project files](#file-format). #### Runtime -The environment in which a [project](#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](#file-format). +The environment in which a [project](#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](#file-format). #### Script -A set of [blocks](#block) put together to create code. Here is an example of a -script: +A set of [blocks](#block) put together to create code. Here is an example of a script: ```sb when flag clicked @@ -510,118 +246,77 @@ stop [this script v] Blocks are put together in the following ways: -- TODO :D +* TODO :D #### Sprite -A kind of [target](#target) that can exist on its own, have -[variables](#variable) only it can set, and be moved, pointed, scaled, and -hidden, all of which are things that the [stage](#stage) cannot do. +A kind of [target](#target) that can exist on its own, have [variables](#variable) only it can set, and be moved, pointed, scaled, and hidden, all of which are things that the [stage](#stage) cannot do. #### Stage -A special [target](#target), with one and only one existing in every project, -that is shown behind all [sprites](#sprite). It is sort of like the -[global scope](https://en.wikipedia.org/wiki/Scope_(computer_science)#Global_scope) -found in some programming languages, but it also exists as its own entity. +A special [target](#target), with one and only one existing in every project, that is shown behind all [sprites](#sprite). It is sort of like the [global scope](https://en.wikipedia.org/wiki/Scope_(computer_science)#Global_scope) found in some programming languages, but it also exists as its own entity. -Unlike [sprites](#sprite), it cannot be moved, pointed, scaled, hidden, or have -variables that only it can set. However, it can do everything else a sprite can. +Unlike [sprites](#sprite), 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](#variable) (aka properties or fields) that are used by contained -[scripts](#script) to perform operations. +An object that runs blocks, shows images, and plays sounds. It has its own [variables](#variable) (aka properties or fields) that are used by contained [scripts](#script) to perform operations. -Every target exists as its own unit independent of other targets, but they can -be interconnected in some ways. There are two kinds of targets * -[sprites](#sprite) and [stages](#stage). +Every target exists as its own unit independent of other targets, but they can be interconnected in some ways. There are two kinds of targets * [sprites](#sprite) and [stages](#stage). #### User -The individual who is interacting with the [project](#project) and provides -input. They may optionally have a [username](#username) that the project can use -to identify them. +The individual who is interacting with the [project](#project) and provides input. They may optionally have a [username](#username) that the project can use to identify them. #### Variable -A container with a [name](#name) that can hold any one [value](#value). Every -variable is attached to a [target](#target). If it is attached to a -[sprite](#sprite), it can only be set by that sprite. If it is attached to the -[stage](#stage), it can be set by any sprite, including the stage. +A container with a [name](#name) that can hold any one [value](#value). Every variable is attached to a [target](#target). If it is attached to a [sprite](#sprite), it can only be set by that sprite. If it is attached to the [stage](#stage), it can be set by any sprite, including the stage. -There are two kinds of variables. Some variables are defined and named by the -creator of a [project](#project) on a target-by-target basis and interacted with -by [variables blocks](#variables-blocks), while all targets have variables that -exist by default and can only be interacted with via their dedicated blocks (not -variable blocks). Some examples of user-defined variables would be `(score)` or -`(index)` (completely custom), while examples of built-in variables would be -`(x position)`, `(direction)`, `(size)`, `(volume)`, and `(tempo)` (exist in -every target). +There are two kinds of variables. Some variables are defined and named by the creator of a [project](#project) on a target-by-target basis and interacted with by [variables blocks](#variables-blocks), while all targets have variables that exist by default and can only be interacted with via their dedicated blocks (not variable blocks). Some examples of user-defined variables would be `(score)` or `(index)` (completely custom), while examples of built-in variables would be `(x position)`, `(direction)`, `(size)`, `(volume)`, and `(tempo)` (exist in every target). ### Values In Scratch, the following types of values exist: -- [String](#string) -- [Number](#number) -- - - [`NaN`](#nan) - - [`Infinity`](#infinity) - - [`-Infinity`](#-infinity) -- [Boolean](#boolean) - - [`true`](#true) - - [`false`](#false) -- [`undefined`](#undefined) - -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: +* [String](#string) +* [Number](#number) +* * [`NaN`](#nan) + * [`Infinity`](#infinity) + * [`-Infinity`](#-infinity) +* [Boolean](#boolean) + * [`true`](#true) + * [`false`](#false) +* [`undefined`](#undefined) + +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](#string), [number](#number), -[boolean](#boolean), or in rare cases [undefined](#undefined). -[Variables](#variable) can hold individual values, and a [list](#list) can store -many of them as [items](#item). +A general value. This can be a [string](#string), [number](#number), [boolean](#boolean), or in rare cases [undefined](#undefined). [Variables](#variable) can hold individual values, and a [list](#list) can store many of them as [items](#item). #### Angle -A [number](#number) intended to be in -[degrees](https://en.wikipedia.org/wiki/Degree_(angle)). `[sin v] of ()`, -`[cos v] of ()`, and `[tan v] of ()` expect angles as input. +A [number](#number) intended to be in [degrees](https://en.wikipedia.org/wiki/Degree_(angle)). `[sin v] of ()`, `[cos v] of ()`, and `[tan v] of ()` expect angles as input. #### Answer -A [string](#string) provided to the [project](#project) by the [user](#user) as -input via the [ask and wait block](#ask-and-wait-block). +A [string](#string) provided to the [project](#project) by the [user](#user) as input via the [ask and wait block](#ask-and-wait-block). #### Boolean -A special type of [value](#value) that is used to represent the result of a -logical operation. It is always either [`true`](#true) or [`false`](#false). +A special type of [value](#value) that is used to represent the result of a logical operation. It is always either [`true`](#true) or [`false`](#false). ##### True -A kind of [boolean](#boolean) that is used to represent a yes or an affirmative -answer as a result of a logical operation. When casted to a [string](#string), -it is written as `true`. When casted to a [number](#number), it is casted to -`1`. It is considered [truthy](#truthy), as it is itself the definition of -truthy. +A kind of [boolean](#boolean) that is used to represent a yes or an affirmative answer as a result of a logical operation. When casted to a [string](#string), it is written as `true`. When casted to a [number](#number), it is casted to `1`. It is considered [truthy](#truthy), as it is itself the definition of truthy. ##### False -A kind of [boolean](#boolean) that is used to represent a no or a negative -answer as a result of a logical operation. When casted to a [string](#string), -it is written as `false`. When casted to a [number](#number), it is casted to -`0`. It is considered [falsy](#falsy), as it is itself the definition of falsy. +A kind of [boolean](#boolean) that is used to represent a no or a negative answer as a result of a logical operation. When casted to a [string](#string), it is written as `false`. When casted to a [number](#number), it is casted to `0`. It is considered [falsy](#falsy), as it is itself the definition of falsy. #### Direction -An [angle](#angle) that determines the way a sprite is turned on the screen. It -is always wrapped to remain in the range -179 and 181 (exclusive). An angle $a$ -can be converted to a direction $d$ like so: +An [angle](#angle) that determines the way a sprite is turned on the screen. It is always wrapped to remain in the range -179 and 181 (exclusive). An angle $a$ can be converted to a direction $d$ like so: $d=\operatorname{mod}\left(a+179,360\right)-179$ @@ -631,15 +326,11 @@ Or in scratchblocks: set [direction v] to ((((angle) + (179)) mod (360)) * (179)) ``` -The way that a sprite's direction impacts how it is rendered is determined by -that sprite's [rotation style](#rotation-style). +The way that a sprite's direction impacts how it is rendered is determined by that sprite's [rotation style](#rotation-style). #### Integer -A [number](#number) that is not a fraction, aka a whole number (e.g. `42`, -`-37`). Many [blocks](#block) 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. +A [number](#number) that is not a fraction, aka a whole number (e.g. `42`, `-37`). Many [blocks](#block) 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 @@ -647,68 +338,44 @@ A [value](#value) in a [list](#list). #### Key -A [name](#name) used by Scratch for referring to a key on the [user](#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) +A [name](#name) used by Scratch for referring to a key on the [user](#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](#integer) representing how many [letters](#letter) or -[items](#item) there are in a [string](#string) or [list](#list), respectively. +A positive [integer](#integer) representing how many [letters](#letter) or [items](#item) there are in a [string](#string) or [list](#list), respectively. #### Letter -An individual [UTF-16](https://en.wikipedia.org/wiki/UTF-16) -[code unit](https://developer.mozilla.org/en-US/docs/Glossary/Code_unit). -Several joined together create a [string](#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. +An individual [UTF-16](https://en.wikipedia.org/wiki/UTF-16) [code unit](https://developer.mozilla.org/en-US/docs/Glossary/Code_unit). Several joined together create a [string](#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](#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](#username), or [sprite](#sprite). +A [string](#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](#username), or [sprite](#sprite). #### Number -A [numerical](https://en.wikipedia.org/wiki/Number) [value](#value). Most -numbers are [real](https://en.wikipedia.org/wiki/Real_number) and can be -positive (`+`), negative (`-`), whole (`#`), or fractional (`#.#`). In -[JavaScript](#javascript), these numbers are internally stored as -[double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double_precision_floating-point_format) -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. +A [numerical](https://en.wikipedia.org/wiki/Number) [value](#value). Most numbers are [real](https://en.wikipedia.org/wiki/Real_number) and can be positive (`+`), negative (`-`), whole (`#`), or fractional (`#.#`). In [JavaScript](#javascript), these numbers are internally stored as [double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double_precision_floating-point_format) 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](#number) that is always greater than any other number. When -[casted](#to-string) to a [string](#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. +A special [number](#number) that is always greater than any other number. When [casted](#to-string) to a [string](#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. ```sb [Infinity] + (1) // Infinity @@ -720,54 +387,34 @@ represented as a real number. ##### -Infinity -A special [number](#number) that is always lower than any other number. When -[casted](#to-string) to a [string](#string), it is written as `-Infinity`. It is -created in the same manner as [Infinity](#infinity). +A special [number](#number) that is always lower than any other number. When [casted](#to-string) to a [string](#string), it is written as `-Infinity`. It is created in the same manner as [Infinity](#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. +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](#number) that is not a number. When [casted](#to-string) to a -[string](#string), it is written as `NaN`. It is interpreted as a `0` when -passed as input to other mathematical operations, unlike in -[JavaScript](#javascript) where it causes most operations to report `NaN`. It -can be produced by doing unknown or unrepresentable things with numbers, such as -multiplying `Infinity` and zero, adding `Infinity` to `-Infinity`, or getting -the square root of a negative number. +A special [number](#number) that is not a number. When [casted](#to-string) to a [string](#string), it is written as `NaN`. It is interpreted as a `0` when passed as input to other mathematical operations, unlike in [JavaScript](#javascript) where it causes most operations to report `NaN`. It can be produced by doing unknown or unrepresentable things with numbers, such as multiplying `Infinity` and zero, adding `Infinity` to `-Infinity`, or getting the square root of a negative number. #### Rotation Style -A [string](#string) that determines how a [sprite](#sprite)'s -[direction](#direction) impacts the way it is visibly rotated when rendered. -Officially, it can be one of the following strings: `all around`, `left-right`, -or `don't rotate`. - -- `all around`: The sprite faces in its direction **clockwise**. At `0`, it - faces **up**; at `90`, it faces **right**; at `180`, it faces **down**; and at - `-90`, it faces **left**. -- `left-right`: If the sprite's direction is less than `0`, 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_](#direction) 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) | +A [string](#string) that determines how a [sprite](#sprite)'s [direction](#direction) impacts the way it is visibly rotated when rendered. Officially, it can be one of the following strings: `all around`, `left-right`, or `don't rotate`. + +* `all around`: The sprite faces in its direction **clockwise**. At `0`, it faces **up**; at `90`, it faces **right**; at `180`, it faces **down**; and at `-90`, it faces **left**. +* `left-right`: If the sprite's direction is less than `0`, 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*](#direction) 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) | ##### Rotation Style: All Around @@ -783,292 +430,184 @@ the same; only the way it **looks like** it's pointed changes.) #### String -A type of [value](#value) consisting of a series (i.e. string) of -[letters](#letter), also known as text. All strings are considered -[truthy](#truthy) except for the [empty string](#empty-string). +A type of [value](#value) consisting of a series (i.e. string) of [letters](#letter), also known as text. All strings are considered [truthy](#truthy) except for the [empty string](#empty-string). ##### Empty String -A [string](#string) containing no letters. It has a [length](#length) of `0` and -is the only string considered [falsy](#falsy). Also known as a "null string," it -can be used in place of a value where there is none, e.g. getting an -[item](#item) from a [list](#list) when it does not exist, or getting the -[answer](#answer) provided by a user when they have not been -[asked](#ask-and-wait-block) anything yet. +A [string](#string) containing no letters. It has a [length](#length) of `0` and is the only string considered [falsy](#falsy). Also known as a "null string," it can be used in place of a value where there is none, e.g. getting an [item](#item) from a [list](#list) when it does not exist, or getting the [answer](#answer) provided by a user when they have not been [asked](#ask-and-wait-block) anything yet. #### Undefined -A special [value](#value) that represents nothing. When converted to a -[string](#string), it is written as `undefined`. This type of value is uncommon -but can be produced by [hidden reporter blocks](#hidden-blocks). In most cases, -however, Scratch uses `0` or an empty string to represent nothing. +A special [value](#value) that represents nothing. When converted to a [string](#string), it is written as `undefined`. This type of value is uncommon but can be produced by [hidden reporter blocks](#hidden-blocks). In most cases, however, Scratch uses `0` or an empty string to represent nothing. #### Username -A [name](#name) used to reference a [user](#user). In standard Scratch, -usernames are: - -- Always 3 to 20 [letters](#letter) [long](#length) (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](https://scratch.mit.edu). 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](https://en.scratch-wiki.info/wiki/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](#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](#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: +A [name](#name) used to reference a [user](#user). In standard Scratch, usernames are: + +* Always 3 to 20 [letters](#letter) [long](#length) (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](https://scratch.mit.edu). 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](https://en.scratch-wiki.info/wiki/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](#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](#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 Scratch through the official 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 +> * Uses Scratch through the official 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](#runtime) directly via developer tools like -> web inspector. - -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 to see if it is registered - with the Scratch website -- Remembering the usernames that the username block has reported (e.g. via cloud - variables) and see if it encounters the same username with different casing -- Checking to see if the username is changed while the project is running - (impossible without modification 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 -implementation 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](#string) that identifies a user. +> 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](#runtime) directly via developer tools like web inspector. + +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 to see if it is registered with the Scratch website +* Remembering the usernames that the username block has reported (e.g. via cloud variables) and see if it encounters the same username with different casing +* Checking to see if the username is changed while the project is running (impossible without modification 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 implementation 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](#string) that identifies a user. #### X Position -A horizontal position on the Scratch coordinate plane. All [sprites](#sprite) -have one. (TODO: document coordinate system) +A horizontal position on the Scratch coordinate plane. All [sprites](#sprite) have one. (TODO: document coordinate system) #### Y Position -A vertical position on the Scratch coordinate plane. All [sprites](#sprite) have -one. (TODO: document coordinate system) +A vertical position on the Scratch coordinate plane. All [sprites](#sprite) 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](#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](#turbowarp) that still - has largely the same behaviors to see how it would behave if somehow - obtained.) - - When [casted](#to-string) to a [string](#string), it is written as `null`. - - When [casted](#to-number) to a [number](#number), it is casted to `0`. - - When [casted](#to-boolean) to a [boolean](#boolean), it is - [`false`](#falsy). +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](#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](#turbowarp) that still has largely the same behaviors to see how it would behave if somehow obtained.) + * When [casted](#to-string) to a [string](#string), it is written as `null`. + * When [casted](#to-number) to a [number](#number), it is casted to `0`. + * When [casted](#to-boolean) to a [boolean](#boolean), it is [`false`](#falsy). ### Procedures -The following procedures are often performed by Scratch and are mentioned -throughout this document: +The following procedures are often performed by Scratch and are mentioned throughout this document: #### Casting -Most blocks automatically convert [values](#value) between types through the use -of very particular logic, also known as -[casting](https://en.scratch-wiki.info/wiki/Casting). The logic Scratch uses is -specified below. +Most blocks automatically convert [values](#value) between types through the use of very particular logic, also known as [casting](https://en.scratch-wiki.info/wiki/Casting). The logic Scratch uses is specified below. ##### To String -Scratch uses the following logic to convert any given [value](#value) to a -[string](#string): - -- If the value is a [**string**](#string): - - **Return the value**, as it is already a string. -- If the value is a [**number**](#number): - - **Follow the - [logic JavaScript does](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)** - to cast a number to a string **and return it.** - - TODO: specify this better - - If the value is [**NaN**](#nan), **return the string `NaN`.** - - If the value is [**Infinity**](#infinity), **return the string `Infinity`.** - - If the value is [**-Infinity**](#infinity), **return the string - `-Infinity`.** -- If the value is a [**boolean**](#boolean): - - If the value is [**true**](#boolean), **return the string `true`.** - - If the value is [**false**](#boolean), **return the string `false`.** -- If the value is [**undefined**](#undefined), **return the string - `undefined`.** -- If the value is [**something else**](#other-values), **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 +Scratch uses the following logic to convert any given [value](#value) to a [string](#string): + +* If the value is a [**string**](#string): + * **Return the value**, as it is already a string. +* If the value is a [**number**](#number): + * **Follow the [logic JavaScript does](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString)** to cast a number to a string **and return it.** + * TODO: specify this better + * If the value is [**NaN**](#nan), **return the string `NaN`.** + * If the value is [**Infinity**](#infinity), **return the string `Infinity`.** + * If the value is [**-Infinity**](#infinity), **return the string `-Infinity`.** +* If the value is a [**boolean**](#boolean): + * If the value is [**true**](#boolean), **return the string `true`.** + * If the value is [**false**](#boolean), **return the string `false`.** +* If the value is [**undefined**](#undefined), **return the string `undefined`.** +* If the value is [**something else**](#other-values), **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 ##### To Number -Scratch uses the following logic to convert any given [value](#value) to a -[number](#number): - -- If the value is [**NaN**](#nan), **return the number `0`.** -- If the value is a [**number**](#number), **return the value** as it is. -- If the value is [**undefined**](#undefined), **return the number `0`.** -- If the value is [**true**](#true), **return the number `1`.** -- If the value is [**false**](#false), **return the number `0`.** -- If the value is a [**string**](#string) or [something else](#other-values): - - **If the value can be converted to a number** according to - [these rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_coercion) - **, return it.** - - **Otherwise, return the number `0`.** - - TODO: specify string -> number coercion better b/c JavaScript logic +Scratch uses the following logic to convert any given [value](#value) to a [number](#number): + +* If the value is [**NaN**](#nan), **return the number `0`.** +* If the value is a [**number**](#number), **return the value** as it is. +* If the value is [**undefined**](#undefined), **return the number `0`.** +* If the value is [**true**](#true), **return the number `1`.** +* If the value is [**false**](#false), **return the number `0`.** +* If the value is a [**string**](#string) or [something else](#other-values): + * **If the value can be converted to a number** according to [these rules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_coercion)**, 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](#value) to a -[boolean](#boolean): +Scratch uses the following logic to convert any given [value](#value) to a [boolean](#boolean): ###### Falsy A value is **falsy**, or casted to [**false**](#false), if the value is: -- an [**empty string**](#empty-string) (no letters, [length](#length) is `0`), -- the **[strings](#string) `0`** or **`false`** (case-insensitive), -- one of the **[numbers](#number) `0`**, **`-0`**, or [**`NaN`**](#nan), -- [**undefined**](#undefined), -- **null** (rare), -- or **false**. +* an [**empty string**](#empty-string) (no letters, [length](#length) is `0`), +* the **[strings](#string) `0`** or **`false`** (case-insensitive), +* one of the **[numbers](#number) `0`**, **`-0`**, or [**`NaN`**](#nan), +* [**undefined**](#undefined), +* **null** (rare), +* or **false**. ###### Truthy -Any value that is **not** [**falsy**](#falsy) is considered **truthy** and -casted to [**true**](#true). +Any value that is **not** [**falsy**](#falsy) is considered **truthy** and casted to [**true**](#true). ##### To Direction -Scratch uses the following logic to convert any given [value](#value) to a -[direction](#direction): +Scratch uses the following logic to convert any given [value](#value) to a [direction](#direction): 1. [**Cast the value to number**](#to-number). 2. **Plug the casted value** into the following equation **as $a$ to find $d$:** - - $d=\operatorname{mod}\left(a+179,360\right)-179$ - - Here is the same equation written in blocks: + * $d=\operatorname{mod}\left(a+179,360\right)-179$ + * Here is the same equation written in blocks: - ```sb - set [direction v] to ((((angle) + (179)) mod (360)) * (179)) - ``` + ```sb + set [direction v] to ((((angle) + (179)) mod (360)) * (179)) + ``` 3. **Return $d$** (`direction`)**.** #### Fencing -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. +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. +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 :D +* TODO :D ##### Fencing Size -- TODO ;D +* 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. +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. ## Palette -This section documents each and every block in Scratch, and its precise -functionality. +This section documents each and every block in Scratch, and its precise functionality. -> 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! +> 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 -> This is an **_example_ section** about a block. It does not exist in Scratch. +> 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](#sb3) [file format](#file-format). +The heading for a section about a block should be its opcode, as used in the [SB3](#sb3) [file format](#file-format). **Operation:** @@ -1082,8 +621,8 @@ the block in scratchblocks with its [ARG]uments **Arguments:** -| Name: | [Casted](#casting) to: | Provides the: | -| :---: | :-----------------------------------------------------------------------------------------------------------------------: | :----------------------------: | +| Name: | [Casted](#casting) 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](#values) | What it provides to the block. | **Procedure:** @@ -1092,10 +631,7 @@ 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](#stage). +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](#stage). #### Standard motion blocks @@ -1105,8 +641,7 @@ These motion blocks are officially supported in Scratch 3.0: **Operation:** -Moves the sprite forward the given number of pixels in the direction that it is -facing. Negative numbers move the sprite backwards. +Moves the sprite forward the given number of pixels in the direction that it is facing. Negative numbers move the sprite backwards. **Block:** @@ -1116,16 +651,13 @@ move (STEPS) steps **Arguments**: -| Name: | [Casted](#casting) to: | Provides the: | -| :-----: | :--------------------: | :-----------------------------------: | -| `STEPS` | [number](#to-number) | Number of steps (aka pixels) to move. | +| Name: | [Casted](#casting) to: | Provides the: | +|:-----:|:----------------------:|:-------------------------------------:| +|`STEPS`| [number](#to-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, whereas the y position of -the sprite is changed by the **cosine of the sprite's direction** multiplied by -the number of steps to move. +The x position of the sprite is changed by the **sine of the sprite's direction** multiplied by the number of steps to move, whereas 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: @@ -1133,8 +665,7 @@ $x' = x + \sin(d) \cdot S$ $y' = y + \cos(d) \cdot S$ -Where $S$ is the `STEPS` to move, $d$ is the direction of the sprite, and $x$ -and $y$ are the x and y positions of the sprite, respectively. +Where $S$ is the `STEPS` to move, $d$ is the direction of the sprite, and $x$ and $y$ are the x and y positions of the sprite, respectively. In scratchblocks, this operation can also be replicated as: @@ -1146,17 +677,13 @@ After the sprite is moved, its position is [fenced](#fencing-position). #### 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: +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. +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 @@ -1166,17 +693,13 @@ 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: +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. +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 @@ -1188,16 +711,13 @@ 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: +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. +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 @@ -1207,17 +727,13 @@ 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: +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. +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 @@ -1227,17 +743,13 @@ 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: +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](#runtime) context. +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](#runtime) context. #### Standard sensing blocks @@ -1249,8 +761,7 @@ TODO **Operation:** -Reports the [username](#username) of the [user](#user) that has loaded the -[project](#project) in the context of the Scratch website. +Reports the [username](#username) of the [user](#user) that has loaded the [project](#project) in the context of the Scratch website. **Block:** @@ -1264,25 +775,18 @@ 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](#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](#empty-string).** +* 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](#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](#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. +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: +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 @@ -1298,9 +802,7 @@ 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: +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 @@ -1316,9 +818,7 @@ 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: +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 @@ -1334,9 +834,7 @@ 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: +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 @@ -1352,30 +850,17 @@ 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: +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 appendix](#nonstandard-blocks), -> though it will have to be clarified that these blocks can be loaded into -> Scratch, they just don't do anything outside of [mods](#mod). +> This section may be moved to a [relevant appendix](#nonstandard-blocks), though it will have to be clarified that these blocks can be loaded into Scratch, they just don't do anything outside of [mods](#mod). -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](#mod). +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](#mod). -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: +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!!! @@ -1447,126 +932,75 @@ 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. +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. +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: +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 ## Appendices -This section is for additional information about Scratch that is not necessarily -relevant to its runtime behavior, but is good to know in addition, especially -for creating highly compatible and feature-complete Scratch implementations. +This section is for additional information about Scratch that is not necessarily relevant to its runtime behavior, but is good to know in addition, especially for creating highly compatible and feature-complete Scratch implementations. ### File Format -> This section will be expanded once other stuff gets documented. For now, -> runtime behavior is more pressing than file formatting. +> 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](#runtime) -environment, a saved project that is not properly loaded may not work as it was -intended to, and could very well break! +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](#runtime) environment, a saved project that is not properly loaded may not work as it was intended to, and could very well break! #### 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](https://en.wikipedia.org/wiki/ZIP_(file_format)) file -that contains the following files: +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](https://en.wikipedia.org/wiki/ZIP_(file_format)) file that contains the following files: -- `project.json`, a [.json](https://en.wikipedia.org/wiki/JSON) file storing - info. -- Various image files used as [costumes](#costume). -- Various audio files used as [sounds](#sound). +* `project.json`, a [.json](https://en.wikipedia.org/wiki/JSON) file storing info. +* Various image files used as [costumes](#costume). +* Various audio files used as [sounds](#sound). 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 .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](#sb3) files, which it then loads. +The standard Scratch 3.0 editor is compatible with .sb2 files. It has a procedure for converting .sb2 files to [.sb3](#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](#sb2) and [.sb3](#sb3) files, .sb files are stored in binary using a much -less human-readable format. +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](#sb2) and [.sb3](#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. +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! ### Obsolete Blocks -> This is an interesting idea, but its inclusion is up for debate. Feel free to -> offer insight! +> 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 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 [runtime](#runtime) behavior -between Scratch versions. +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 [runtime](#runtime) 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). +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 -> 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](https://en.wikipedia.org/wiki/Porting) of -> Scratch). - -This section serves to document blocks that do not exist at all in Scratch, but -have been added unofficially to [modifications](#mod) of Scratch. This includes -both blocks added as "custom extensions," and blocks added directly to the -[palette](#palette). They are specified here in order to allow projects using -these nonstandard blocks to function properly if one were to reimplement the -Scratch VM with implementing these blocks in mind. - -> This is a dynamic section and may never be able to satisfy any particular -> standards for completeness. [You can help](#contributing) by adding -> [missing blocks](#todo-blocks) with reliable sources (e.g. links to source -> code). +> 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](https://en.wikipedia.org/wiki/Porting) of Scratch). + +This section serves to document blocks that do not exist at all in Scratch, but have been added unofficially to [modifications](#mod) of Scratch. This includes both blocks added as "custom extensions," and blocks added directly to the [palette](#palette). They are specified here in order to allow projects using these nonstandard blocks to function properly if one were to reimplement the Scratch VM with implementing these blocks in mind. + +> This is a dynamic section and may never be able to satisfy any particular standards for completeness. [You can help](#contributing) by adding [missing blocks](#todo-blocks) with reliable sources (e.g. links to source code). #### Example nonstandard block -> This is an **_example_ section** about a nonstandard block. It does not exist -> in Scratch or any modifications of it. +> This is an ***example* section** about a nonstandard block. It does not exist in Scratch or any modifications of it. **Operation:** @@ -1580,8 +1014,8 @@ the block in scratchblocks with its [ARG]uments **Arguments:** -| Name: | [Casted](#casting) to: | Provides the: | -| :---: | :-----------------------------------------------------------------------------------------------------------------------: | :----------------------------: | +| Name: | [Casted](#casting) 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](#values) | What it provides to the block. | **Procedure:** @@ -1590,17 +1024,13 @@ A deep dive into what the block does in fulfilling its operation. #### TurboWarp -[TurboWarp](https://turbowarp.org/) 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. +[TurboWarp](https://turbowarp.org/) 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. +These blocks are "weird, new blocks" specific to TurboWarp. This category of blocks is named after TurboWarp itself. ###### Last key pressed block @@ -1620,77 +1050,40 @@ None **Procedure:** -When the [runtime](#runtime) first starts, no [keys](#key) have been pressed. If -the block is run before any keys are pressed, it reports the -[empty string](#empty-string). Otherwise, the [name](#name) of the last key to -have been pressed is reported. +When the [runtime](#runtime) first starts, no [keys](#key) have been pressed. If the block is run before any keys are pressed, it reports the [empty string](#empty-string). Otherwise, the [name](#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](#special-custom-blocks) without definitions -in disguise! +These blocks are added by TurboWarp addons. They are not actually real blocks, but rather [special custom blocks](#special-custom-blocks) without definitions in disguise! #### PenguinMod -[PenguinMod](https://penguinmod.com/) is a mod of [TurboWarp](#turbowarp). It -supports most TurboWarp extensions and introduces some community-made ones of -its own. +[PenguinMod](https://penguinmod.com/) is a mod of [TurboWarp](#turbowarp). It supports most TurboWarp extensions and introduces some community-made ones of its own. TODO: Document PenguinMod blocks #### snail-ide -[Snail IDE](https://snail-ide.js.org/) is a mod of [PenguinMod](#penguinmod). It -supports most of PenguinMod's blocks and adds some of its own. +[Snail IDE](https://snail-ide.js.org/) is a mod of [PenguinMod](#penguinmod). It supports most of PenguinMod's blocks and adds some of its own. TODO: Document Snail IDE blocks #### Unsandboxed -[Unsandboxed](https://alpha.unsandboxed.org/#0) is a mod of -[TurboWarp](#turbowarp) for building games. It is compatible with TurboWarp's -blocks and adds some of its own. +[Unsandboxed](https://alpha.unsandboxed.org/#0) is a mod of [TurboWarp](#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](#contributing) information on it! Though if you do, please remember -that this a language specification for Scratch's runtime behavior, not a -[wiki](https://scratch-wiki.info/) 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](#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](#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](#turbowarp) is in - the [Addon blocks](#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. - -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‍_!_](https://snap.berkeley.edu/) 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](https://snap.berkeley.edu/snap/help/SnapManual.pdf) instead. +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](#contributing) information on it! Though if you do, please remember that this a language specification for Scratch's runtime behavior, not a [wiki](https://scratch-wiki.info/) 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](#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](#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](#turbowarp) is in the [Addon blocks](#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. + +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‍*!*](https://snap.berkeley.edu/) 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](https://snap.berkeley.edu/snap/help/SnapManual.pdf) instead. diff --git a/intro.md b/intro.md index aee148e..61e1d54 100644 --- a/intro.md +++ b/intro.md @@ -24,46 +24,3 @@ Please [contribute on GitHub](https://github.com/OceanIsEndless/scratch-spec/pul * **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 - -## FAQ - -*Questions that would be frequently asked if someone were to ask them.* - -### Where to start? - -* If you want a **general understanding** of Scratch's inner workings for whatever reason, find whatever interests you in the [table of contents](#contents) and just gloss over whatever you don't need to know. -* If you want **formal definitions** of Scratch terms, see [concepts](#concepts). -* If you want to accurately **recreate blocks**, see the [palette](#palette). - -TODO: Threading and execution behavior will be documented soon! - -* If you want to learn about project files, see [file format](#file-format). -* If you want to recreate old blocks, see [obsolete blocks](#obsolete-blocks). -* If you want more blocks, see [nonstandard blocks](#nonstandard-blocks). - -### 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](https://www.desmos.com/calculator) packager, or porting Scratch to the [Wii](https://en.wikipedia.org/wiki/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 help this super cool rapidly-developing [3DS port](https://github.com/NateXS/Scratch-3DS), 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](https://scratch-wiki.info/) 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](#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](https://blob.codes/scratch-is-cool/). It is [Turing-complete](https://en.wikipedia.org/wiki/Turing_completeness). Lots of languages far less significant than Scratch have [programming language specifications](https://en.wikipedia.org/wiki/Programming_language_specification). 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***](https://en.wikipedia.org/wiki/Scratch_(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? diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..b1ece88 --- /dev/null +++ b/todo.md @@ -0,0 +1,76 @@ +# TODO + +> [!IMPORTANT] +> This spec is a work in progress; it's nowhere near complete. **Please [contribute](#contributing) 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. + +Various things need to be worked on to make this a good resource: + +* **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 its structure should be as well. +* ⚠️ ‼️ **Cite reliable sources.** ‼️ ⚠️ This specification should provide references to the code of Scratch itself (not just wikis) to prove its claims and hopefully be an accurate source of information about the Scratch programming language. It has not been decided how to best reference material though. (Just link them, or go wiki style?) + +## 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 checked off.) Specifying [standard](#palette) blocks is the first priority. Once they are documented, the scope of this spec can be expanded to include [hidden](#hidden-blocks), [obsolete](#obsolete-blocks), and even [nonstandard](#nonstandard-blocks) blocks as well, probably in that order. + +
+ Click to view block list + +* □ [Motion Blocks](#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 [left-right]` + * □ `(x position)` + * □ `(y position)` + * □ `(direction)` + * □ [**Hidden**](#hidden-blocks) (**specify** what they do, even if nothing at all) + * □ `scroll right ()` + * □ `scroll up ()` + * □ `align scene [ v]` + * □ `(x scroll)` + * □ `(y scroll)` + * □ [**Obsolete**](#obsolete-blocks) (**imagine** what they *would* do if kept operational) + * □ `scroll right ()` + * □ `scroll up ()` + * □ `align scene [ v]` + * □ `(x scroll)` + * □ `(y scroll)` + * □ [**Nonstandard**](#nonstandard-blocks) (blocks that [mods](#mod) of Scratch added) + * □ [PenguinMod](#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](#unsandboxed) + * □ `(rotation style)` +* □ [Looks blocks](#looks-blocks) +* □ [Sound blocks](#sound-blocks) +* □ [Events blocks](#events-blocks) +* □ [Control blocks](#control-blocks) +* □ [Sensing blocks](#sensing-blocks) +* □ [Operators blocks](#operators-blocks) +* □ [Variables blocks](#variables-blocks) +* □ [List blocks](#list-blocks) +* □ [Custom blocks](#custom-blocks) +* □ [Addon blocks](#addon-blocks) +* □ *other categories of blocks* +* □ TODO: Write list of blocks TODO :) + +
From 39e7f32af9400209adbbd09509aa1250b1a21146 Mon Sep 17 00:00:00 2001 From: Grady Link Date: Mon, 28 Jul 2025 13:14:26 -0700 Subject: [PATCH 3/4] feat: do ideas page --- concepts/ideas.md | 116 +++++++++++++++++++++++++++++++++ index.md | 161 +++++++--------------------------------------- 2 files changed, 138 insertions(+), 139 deletions(-) create mode 100644 concepts/ideas.md diff --git a/concepts/ideas.md b/concepts/ideas.md new file mode 100644 index 0000000..9ade161 --- /dev/null +++ b/concepts/ideas.md @@ -0,0 +1,116 @@ +# Ideas + +The following ideas are referenced throughout this specification: + +## Asset + +A [costume](#costume) or [sound](#sound). + +### Costume + +A costume is an [image file](https://en.wikipedia.org/wiki/Digital_image) and a type of [asset](#asset) that can be graphically rendered to represent a [target](#target). It can be identified by its [name](#name) or [number](#integer). Costumes can either be [bitmap](https://en.wikipedia.org/wiki/Raster_graphics) or [vector](https://en.wikipedia.org/wiki/Vector_graphics). + +### Sound + +A sound is an [audio file](https://en.wikipedia.org/wiki/Digital_audio) and a type of [asset](#asset) that can be audibly played to the user via [blocks](#block). It can be identified by its [name](#name). + +## Block + +The fundamental component of Scratch as a programming language. In fact, they are similar to function calls 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](#undefined)) + +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](#script). + +### Standard Blocks + +[Blocks](#block) that are officially supported in Scratch 3.0. They are the most commonly used blocks in [scripts](#script) by far. + +### Hidden Blocks + +[Blocks](#block) 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](#script) may use them on occasion, but they are found less often than [standard blocks](#standard-blocks) due to their obscurity. + +## Clone + +A copy created of a [sprite](#sprite) that has all of the original sprite's code, images, and sounds, but operates independently of it. Unlike sprites, clones cannot be directly referenced via existing blocks (e.g. you cannot [glide to](#glide-to-block) it directly without knowing its position ahead of time, as it cannot be selected in the sprite dropdown menu), and exist as their own thing. They are deleted every time the [flag](#flag) is clicked, and can also be deleted manually using the [`delete this clone` block](#delete-clone-block). + +Clones can be created with the [create clone block](#create-clone-block) so long as the [maximum number of clones](#max-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](#when-i-start-as-a-clone-block). The [stage](#stage) is the [target](#target) which cannot be cloned, whereas both sprites *and clones* can themselves be cloned. + +## Edge + +Refers to the bounds that restrict the graphics of a [project](#project) from exceeding its designated region on the user's screen. + +## Flag + +> The usefulness of defining "Flag" is up for debate. Feel free to offer insight! + +The button that is intended to run scripts that start a project. It is also known as the green flag in official Scratch. It is meant to make the project `Go`, as it is labelled in its title text on the Scratch website. When clicked, it runs any scripts under [when flag clicked blocks](#when-flag-clicked-block). + +## 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](#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](#hidden-blocks), we can obtain this type of value. + +## List + +A series of [items](#item) stored together in sequence. Each item is referenced by its numerical index (aka item #), a positive [integer](#integer) ranging from `1` to the [length](#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](#max-items) that a list can hold, aka a limit to its length. + +## Mod + +A modification (altered version) of the Scratch 3.0 [runtime](#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 the [relevant appendix](#nonstandard-blocks). + +## Opcode + +A [name](#name) unique to every [block](#block) in the Scratch programming language. It tells blocks what to do. For example, if the opcode of a block is [`motion_movesteps`](#motion_movesteps), it attempts to move steps. + +## Project + +A stage and optionally some sprites packaged together to do something. They can be loaded into a [runtime](#runtime) and executed. They can also be saved as [project files](#file-format). + +## Runtime + +The environment in which a [project](#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](#file-format). + +## Script + +A set of [blocks](#block) put together to create code. Here is an example of a script: + +```sb +when flag clicked +ask [What's your name?] and wait +say (join [Hello, ] (join (answer) [!])) +stop [this script v] +``` + +Blocks are put together in the following ways: + +* TODO :D + +## Sprite + +A kind of [target](#target) that can exist on its own, have [variables](#variable) only it can set, and be moved, pointed, scaled, and hidden, all of which are things that the [stage](#stage) cannot do. + +## Stage + +A special [target](#target), with one and only one existing in every project, that is shown behind all [sprites](#sprite). It is sort of like the [global scope](https://en.wikipedia.org/wiki/Scope_(computer_science)#Global_scope) found in some programming languages, but it also exists as its own entity. + +Unlike [sprites](#sprite), 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](#variable) (aka properties or fields) that are used by contained [scripts](#script) to perform operations. + +Every target exists as its own unit independent of other targets, but they can be interconnected in some ways. There are two kinds of targets * [sprites](#sprite) and [stages](#stage). + +## User + +The individual who is interacting with the [project](#project) and provides input. They may optionally have a [username](#username) that the project can use to identify them. + +## Variable + +A container with a [name](#name) that can hold any one [value](#value). Every variable is attached to a [target](#target). If it is attached to a [sprite](#sprite), it can only be set by that sprite. If it is attached to the [stage](#stage), it can be set by any sprite, including the stage. + +There are two kinds of variables. Some variables are defined and named by the creator of a [project](#project) on a target-by-target basis and interacted with by [variables blocks](#variables-blocks), while all targets have variables that exist by default and can only be interacted with via their dedicated blocks (not variable blocks). Some examples of user-defined variables would be `(score)` or `(index)` (completely custom), while examples of built-in variables would be `(x position)`, `(direction)`, `(size)`, `(volume)`, and `(tempo)` (exist in every target). diff --git a/index.md b/index.md index ccb368d..c805ef0 100644 --- a/index.md +++ b/index.md @@ -29,28 +29,28 @@ A detailed explanation of how Scratch 3.0 works as a programming language. * [Limits](/constants#limits) * [Max Items](/constants#max-items) * [Max Clones](/constants#max-clones) - * [Ideas](#ideas) - * [Asset](#asset) - * [Costume](#costume) - * [Sound](#sound) - * [Block](#block) - * [Standard Blocks](#standard-blocks) - * [Hidden Blocks](#hidden-blocks) - * [Clone](#clone) - * [Edge](#edge) - * [Flag](#flag) - * [JavaScript](#javascript) - * [List](#list) - * [Mod](#mod) - * [Opcode](#opcode) - * [Project](#project) - * [Runtime](#runtime) - * [Script](#script) - * [Sprite](#sprite) - * [Stage](#stage) - * [Target](#target) - * [User](#user) - * [Variable](#variable) + * [Ideas](/ideas) + * [Asset](/ideas#asset) + * [Costume](/ideas#costume) + * [Sound](/ideas#sound) + * [Block](/ideas#block) + * [Standard Blocks](/ideas#standard-blocks) + * [Hidden Blocks](/ideas#hidden-blocks) + * [Clone](/ideas#clone) + * [Edge](/ideas#edge) + * [Flag](/ideas#flag) + * [JavaScript](/ideas#javascript) + * [List](/ideas#list) + * [Mod](/ideas#mod) + * [Opcode](/ideas#opcode) + * [Project](/ideas#project) + * [Runtime](/ideas#runtime) + * [Script](/ideas#script) + * [Sprite](/ideas#sprite) + * [Stage](/ideas#stage) + * [Target](/ideas#target) + * [User](/ideas#user) + * [Variable](/ideas#variable) * [Values](#values) * [Value](#value) * [Angle](#angle) @@ -157,123 +157,6 @@ A detailed explanation of how Scratch 3.0 works as a programming language. * [Unsandboxed](#unsandboxed) * [Adding Platforms](#adding-platforms) -### Ideas - -The following ideas are referenced throughout this specification: - -#### Asset - -A [costume](#costume) or [sound](#sound). - -##### Costume - -A costume is an [image file](https://en.wikipedia.org/wiki/Digital_image) and a type of [asset](#asset) that can be graphically rendered to represent a [target](#target). It can be identified by its [name](#name) or [number](#integer). Costumes can either be [bitmap](https://en.wikipedia.org/wiki/Raster_graphics) or [vector](https://en.wikipedia.org/wiki/Vector_graphics). - -##### Sound - -A sound is an [audio file](https://en.wikipedia.org/wiki/Digital_audio) and a type of [asset](#asset) that can be audibly played to the user via [blocks](#block). It can be identified by its [name](#name). - -#### Block - -The fundamental component of Scratch as a programming language. In fact, they are similar to function calls 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](#undefined)) - -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](#script). - -##### Standard Blocks - -[Blocks](#block) that are officially supported in Scratch 3.0. They are the most commonly used blocks in [scripts](#script) by far. - -##### Hidden Blocks - -[Blocks](#block) 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](#script) may use them on occasion, but they are found less often than [standard blocks](#standard-blocks) due to their obscurity. - -#### Clone - -A copy created of a [sprite](#sprite) that has all of the original sprite's code, images, and sounds, but operates independently of it. Unlike sprites, clones cannot be directly referenced via existing blocks (e.g. you cannot [glide to](#glide-to-block) it directly without knowing its position ahead of time, as it cannot be selected in the sprite dropdown menu), and exist as their own thing. They are deleted every time the [flag](#flag) is clicked, and can also be deleted manually using the [`delete this clone` block](#delete-clone-block). - -Clones can be created with the [create clone block](#create-clone-block) so long as the [maximum number of clones](#max-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](#when-i-start-as-a-clone-block). The [stage](#stage) is the [target](#target) which cannot be cloned, whereas both sprites *and clones* can themselves be cloned. - -#### Edge - -Refers to the bounds that restrict the graphics of a [project](#project) from exceeding its designated region on the user's screen. - -#### Flag - -> The usefulness of defining "Flag" is up for debate. Feel free to offer insight! - -The button that is intended to run scripts that start a project. It is also known as the green flag in official Scratch. It is meant to make the project `Go`, as it is labelled in its title text on the Scratch website. When clicked, it runs any scripts under [when flag clicked blocks](#when-flag-clicked-block). - -#### 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](#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](#hidden-blocks), we can obtain this type of value. - -#### List - -A series of [items](#item) stored together in sequence. Each item is referenced by its numerical index (aka item #), a positive [integer](#integer) ranging from `1` to the [length](#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](#max-items) that a list can hold, aka a limit to its length. - -#### Mod - -A modification (altered version) of the Scratch 3.0 [runtime](#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 the [relevant appendix](#nonstandard-blocks). - -#### Opcode - -A [name](#name) unique to every [block](#block) in the Scratch programming language. It tells blocks what to do. For example, if the opcode of a block is [`motion_movesteps`](#motion_movesteps), it attempts to move steps. - -#### Project - -A stage and optionally some sprites packaged together to do something. They can be loaded into a [runtime](#runtime) and executed. They can also be saved as [project files](#file-format). - -#### Runtime - -The environment in which a [project](#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](#file-format). - -#### Script - -A set of [blocks](#block) put together to create code. Here is an example of a script: - -```sb -when flag clicked -ask [What's your name?] and wait -say (join [Hello, ] (join (answer) [!])) -stop [this script v] -``` - -Blocks are put together in the following ways: - -* TODO :D - -#### Sprite - -A kind of [target](#target) that can exist on its own, have [variables](#variable) only it can set, and be moved, pointed, scaled, and hidden, all of which are things that the [stage](#stage) cannot do. - -#### Stage - -A special [target](#target), with one and only one existing in every project, that is shown behind all [sprites](#sprite). It is sort of like the [global scope](https://en.wikipedia.org/wiki/Scope_(computer_science)#Global_scope) found in some programming languages, but it also exists as its own entity. - -Unlike [sprites](#sprite), 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](#variable) (aka properties or fields) that are used by contained [scripts](#script) to perform operations. - -Every target exists as its own unit independent of other targets, but they can be interconnected in some ways. There are two kinds of targets * [sprites](#sprite) and [stages](#stage). - -#### User - -The individual who is interacting with the [project](#project) and provides input. They may optionally have a [username](#username) that the project can use to identify them. - -#### Variable - -A container with a [name](#name) that can hold any one [value](#value). Every variable is attached to a [target](#target). If it is attached to a [sprite](#sprite), it can only be set by that sprite. If it is attached to the [stage](#stage), it can be set by any sprite, including the stage. - -There are two kinds of variables. Some variables are defined and named by the creator of a [project](#project) on a target-by-target basis and interacted with by [variables blocks](#variables-blocks), while all targets have variables that exist by default and can only be interacted with via their dedicated blocks (not variable blocks). Some examples of user-defined variables would be `(score)` or `(index)` (completely custom), while examples of built-in variables would be `(x position)`, `(direction)`, `(size)`, `(volume)`, and `(tempo)` (exist in every target). - ### Values In Scratch, the following types of values exist: From 8f7d8b331dbaccaf3214acd6e592aa2bb94dd083 Mon Sep 17 00:00:00 2001 From: Grady Link Date: Mon, 28 Jul 2025 13:28:17 -0700 Subject: [PATCH 4/4] feat: add ideas to sidebar --- .vitepress/config.mts | 1 + 1 file changed, 1 insertion(+) diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 256c256..ced8a35 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -19,6 +19,7 @@ export default defineConfig({ items: [ { text: "Capabilities", link: "/concepts/capabilities" }, { text: "Constants", link: "/concepts/constants" }, + { text: "Ideas", link: "/concepts/ideas" }, ], }, ],