Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
8a51f1f
feat(custom-extensions): init
gradylink Sep 17, 2025
1e3837b
feat(custom-extensions): init json api
gradylink Sep 17, 2025
7d7fb4c
feat(custom-extensions): init json api content
gradylink Sep 17, 2025
011f19d
feat(custom-extensions): add info about arg names
gradylink Sep 17, 2025
726b89a
feat(custom-extensions): init file api content
gradylink Sep 17, 2025
59addf9
feat(custom-extensions): seperate functions, types
gradylink Sep 17, 2025
dba3dc8
feat(custom-extensions): init runtime api content
gradylink Sep 20, 2025
0f0096a
feat(custom-extensions): new permissions and apis
gradylink Sep 20, 2025
aa47c95
feat(custom-extensions): runtime wip warning
gradylink Sep 20, 2025
093c663
feat(custom-extensions): split types and variables
gradylink Sep 20, 2025
de8fffe
feat(custom-extensions): init extensions content
gradylink Sep 25, 2025
1d1b0cc
refactor(custom-extensions): new core extensions
gradylink Sep 25, 2025
6e8999c
feat(custom-extensions): init extension info api
gradylink Sep 25, 2025
b9458f0
feat(custom-extensions): init input api content
gradylink Sep 25, 2025
215a1df
feat(custom-extensions): add clone api
gradylink Sep 26, 2025
ed9b556
feat(custom-extensions): add update api content
gradylink Sep 26, 2025
8dbedfc
feat(custom-extensions): add runtime api warning
gradylink Sep 26, 2025
02f70be
feat(custom-extensions): runtime api username
gradylink Sep 26, 2025
9201655
refactor(custom-extensions): improve format layout
gradylink Oct 2, 2025
d278a83
feat(custom-extensions): version info in format
gradylink Oct 2, 2025
a2c15ad
feat(custom-extensions): add versions to format
gradylink Oct 2, 2025
ecce2fa
feat(custom-extensions): add testing to versions
gradylink Oct 2, 2025
f660522
fix(custom-extensions): add missing lua bytecode
gradylink Oct 2, 2025
4edfdf8
feat(custom-extensions): add more input stuff
gradylink Oct 3, 2025
b604083
feat(custom-extensions): render api content
gradylink Oct 3, 2025
5308790
chore(custom-extensions): remove runtime warning
gradylink Oct 3, 2025
7b431e5
feat(custom-extensions): get costume as data url
gradylink Oct 3, 2025
b19de09
feat(custom-extensions): init network api content
gradylink Oct 8, 2025
f0eb7d9
feat(custom-extensions): add big endian note
gradylink Oct 8, 2025
3b0b2a8
feat(custom-extensions): init settings
gradylink Oct 9, 2025
ce5be46
refactor(custom-extensions): simpler update api
gradylink Oct 15, 2025
67d2fdf
fix(custom-extensions): files heading level
gradylink Oct 15, 2025
db9119e
feat(custom-extensions): add `"any"` as mouse btn
gradylink Oct 16, 2025
40d9165
fix(custom-extensions): `"any"` in event handler
gradylink Oct 16, 2025
5757b91
feat(custom-extensions): remove `input.onEvent`
gradylink Oct 17, 2025
85c538b
feat(custom-extensions): init `input.devices`
gradylink Oct 17, 2025
a364ac6
feat(custom-extensions): add touch input device
gradylink Oct 17, 2025
b1ed164
chore(custom-extensions): add new platforms
gradylink Mar 29, 2026
64c3626
chore(extensions/format): add og xbox
gradylink Oct 24, 2026
090bd8e
chore(extensions/format): update version stuff
gradylink Oct 24, 2026
0c3e788
fix(extensions/extensions): add missing platforms
gradylink Oct 24, 2026
c35f56b
feat(intro): init
Starlii10 Oct 24, 2026
3d506f2
feat(dev-intro): init
Starlii10 Oct 24, 2026
978ded5
Merge branch 'feat/custom-extensions' of https://github.com/ScratchEv…
Starlii10 Oct 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export default defineConfig({
logo:
"https://github.com/ScratchEverywhere/ScratchEverywhere/blob/main/gfx/logo_se.png?raw=true",
siteTitle: false,
sidebar: [
{
sidebar: {
"/": [{
items: [
{ text: "Introduction", link: "/intro" },
{ text: "Installation", link: "/install" },
Expand All @@ -42,7 +42,45 @@ export default defineConfig({
{ text: "Controls", link: "/controls" },
{ text: "Settings", link: "/settings" },
],
},
}],
"/extensions/": [
{
items: [
{ text: "Introduction", link: "/extensions/intro" },
],
},
{
text: "Dev",
items: [
{ text: "Introduction", link: "/extensions/dev-intro" },
{ text: "File Format", link: "/extensions/format" },
{
text: "API",
items: [
{ text: "General", link: "/extensions/general" },
{ text: "JSON", link: "/extensions/json" },
{ text: "File System", link: "/extensions/files" },
{ text: "Network", link: "/extensions/network" },
{ text: "Input", link: "/extensions/input" },
{ text: "Render", link: "/extensions/render" },
{ text: "Updates", link: "/extensions/updates" },
{
text: "Platform Specific",
link: "/extensions/platform-specific",
},
{ text: "Runtime", link: "/extensions/runtime" },
{ text: "Audio", link: "/extensions/audio" },
{ text: "Extensions", link: "/extensions/extensions" },
],
},
],
},
],
},

nav: [
{ text: "Docs", link: "/intro" },
{ text: "Custom Extension Docs", link: "/extensions/intro" },
],

socialLinks: [
Expand All @@ -60,6 +98,9 @@ export default defineConfig({
search: {
provider: "local",
},
outline: {
level: [2, 3],
},
},
markdown: {
theme: {
Expand Down
3 changes: 3 additions & 0 deletions extensions/audio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
> [!INFO]
> This page hasn't been written yet. Please remember extensions are WIP, so
> documentation for it is incomplete.
35 changes: 35 additions & 0 deletions extensions/dev-intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Developer Intro to Custom Extensions

Custom extensions come in two forms: **Lua extensions** and **native
extensions**. Native extensions are more powerful as they have direct access to
the SE! source code, and are best used for complex blocks or those with strict
performance requirements. Lua extensions are better for simple blocks, as they
are easy to program.

## Lua Extensions

Lua extensions are broken into two parts: the Lua code itself and a metadata
JSON file. As an example, here's the `meta.json` for the JSON extension:

```json
{
"$schema": "https://raw.githubusercontent.com/ScratchEverywhere/seec/refs/heads/main/schema.json",
"core": false,
"id": "skyhigh173JSON",
"name": "JSON",
"description": "Handle JSON strings and arrarys.",
"permissions": []
}
```

The format of this file can be found in the schema file.

Compiling a Lua extension is done with
[seec](https://github.com/ScratchEverywhere/seec).

## Native Extensions

Native extensions require that you are able to compile SE! itself. In order for
a native extension to work on Scratch Everywhere!, it must be built on the
**same system**, using the **same compiler** and the **same arguments**, with
the **same version of Scratch Everywhere!**.
70 changes: 70 additions & 0 deletions extensions/extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Extensions

## Types

### `extensions.info: table`

#### `core: boolean`

Whether or not the extension is a core extension.

#### `id: string`

The ID of the extension.

#### `name: string`

The name of the extension.

#### `description: string`

The extension's description.

#### `permissions: ("localfs" | "rootfs" | "network" | "input" | "render" | "update" | "platform-specific" | "runtime" | "audio" | "extensions")[]`

A list of all the permissions the extension has.

#### `platforms: ("3ds" | "wiiu" | "wii" | "gamecube" | "switch" | "vita" | "pc" | "xbox" | "wasm" | "psp" | "ps4" | "nds" | "webos")[]`

A list of all the platforms the extension supports.

## Variables

### `extensions.active: string[]`

A list of all extensions the current project uses.

### `extensions.installed: string[]`

A list of all extensions that are installed on the device. This does not include
extensions embedded in the project.

### `extensions.embedded: string[]`

A list of all embedded extensions. This includes both extensions embedded in the
project and the Scratch Everywhere! executable.

## Functions

### `extensions.send(id: string, message: string)`

Sends the specified message to a specific extension.

### `extensions.sendAll(message: string)`

Sends the specified message to all extensions.

### `extensions.receive(id: string, callback: fun(message: string))`

Takes in a callback that is called whenever a message is received from a
specific extension.

### `extensions.receiveAll(callback: fun(message: string))`

Takes in a callback that is called whenever a message is received from any
extension.

### `extensions.getInfo(id: string)`

Gets info about a specific custom extension. Returns a [`extensions.info`]()
table.
54 changes: 54 additions & 0 deletions extensions/files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# File System

> [!NOTE]
> The file system API requires either the root or local file system permissions.

## Root Location

If the root file system permission is present the file system root will be
`sdmc:/` on console, `/` on Unix-like systems (Linux, macOS, BSD), and `C:\` on
Windows.

For the local file system permission the root location will be the
`se:/extension-data/<EXTENSION_ID>`.

If both are present then the root file system permission takes priority.

## Current Directory

If the root file system permission is present then the current directory will be
the root of the Scratch Everywhere! directory.

If the local file system permission is present then the current directory is
`se:/extension-data/<EXTENSION_ID>`.

If both are present then the local file system permission takes priority.

## Functions

### `files.read(path: string)`

Reads the entire file at the inputed path into a string.

### `files.write(path: string, content: string)`

Overwrites the specified file's content with the provided content.

### `files.append(path: string, content: string)`

Appends the specified content the specified file.

### `files.mkdir(path: string)`

Creates a directory at the given path.

### `files.ls(path: string)`

Lists all files in a directory, including dot files.

### `files.mainDirectory`

> [!NOTE]
> This variable is only available with the root file system permission.

The path of the Scratch Everywhere! directory.
143 changes: 143 additions & 0 deletions extensions/format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
> [!NOTE]
> Most people shouldn't need to worry about this. This is for people
> implementing SE! extensions, and people working on compilers like seec.

# SEE (Scratch Everywhere! Extension)

All strings are UTF-8 and all numbers are big endian.

## Magic Strings

All `.see` files start with the magic string `SE! EXTENSION` (not
null-terminated.)

## Version Info

This section contains all info about versioning. It is made up of 3 bytes. The
first byte is the version of this file format, the second byte is the major
version of the API the extension was designed for, and the third byte is the
minor version of the API the extension was designed for.

### File Format Versions

- `0`: initial
- `1`: added Xbox to the platforms flag

### API Versions

- `0.1`: initial

## Core Extensions

The core extensions flag is made up of 1 byte that is either `0` if the
extension is not a core extension, or `1` of the extension is a core extension.
Core extensions allow creating blocks that are not tied to the specific
extension ID.

## Extension Info

The extension info section contains information about the extension. It is made
up of 3 null-terminated strings in this order:

- Extension ID
- Extension Name
- Extension Description

## Permissions

The permissions section contains the necessary permissions the extension needs,
it is made up of a single unsigned 16-bit integer.

- 1st bit represents if the extension needs local file system access. This is
what should be used the majority of the time.
- 2nd bit represents if the extension needs root file system access. This is not
recommended for most extensions.
- 3rd bit represents if the extension needs internet access.
- 4th bit represents if the extension needs access to inputs.
- 5th bit represents if the extension needs access to rendering.
- 6th bit represents if the extension has update functions that need to be
called each frame.
- 7th bit represents if the extension needs access to platform specific APIs
(e.g. Amiibo or account information.)
- 8th bit represents if the extension needs access to the runtime (e.g. sprite
position, costume, or variables.)
- 9th bit represents if the extension needs access to audio APIs.
- 10th bit represents if the extension needs access to be able to communicate
with other extensions.

## Supported Platforms

The platforms section is a single unsigned 16-bit integer with its bits
representing the platforms that the extension works on. Most extensions should
support all platforms.

- 1st bit: 3DS
- 2nd bit: Wii U
- 3rd bit: Wii
- 4th bit: GameCube
- 5th bit: Switch
- 6th bit: PC
- 7th bit: Vita
- 8th bit: NDS
- 9th bit: PS4
- 10th bit: PSP
- 11th bit: webOS
- 12th bit: WASM
Comment thread
Starlii10 marked this conversation as resolved.
- 13th bit: Xbox

## Settings

The settings section allows custom extensions to provide modifiable settings
available in the runtime's UI.

The section begins with a single byte for the number of settings available in
the extension.

The rest of the section is made up of data for each setting. The size of these
settings is not always the same (not even the same number of data types.) All
settings start with a single byte repsenting the type of the extension, followed
by 2 null-terminated strings, one for the ID of the setting, and another for the
name of the setting. The name and ID is always followed by a default value, the
size of which varies between types. Some types also have additional data.

### Toggles

Toggles have the type of `0x12`. Toggles' default value is a single byte with a
`1` representing enabled and a `0` representing disabled.

### Text

Text settings have the type of `0x63`. Their default value is a null-terminated
string. They also have another null-terminated string called the prompt which is
what will be displayed in the on-screen keyboard when editing the text setting.

### Sliders

Sliders have the type of `0x6E`. Their default value is a 32-bit float. Sliders
also have an additional three 32-bit floats in this order, slider max, slider
minimum, and slider snap.

## Blocks

The blocks section is actually split into two sub-sections, the block types
section and the block IDs section.

### Block Types

The block types section itself is null-terminated and is simply represented by 1
byte for each block which tells the runtime what type of block, each block is.

- `0x1`: Command
- `0x2`: Hat
- `0x3`: Event
- `0x4`: Reporter
- `0x5`: Boolean

### Block IDs

After the block types is the block IDs. Each ID is a null-terminated string.
There should be the same amount of IDs as types.

## Lua Bytecode

Following everything else is simply just some compiled Lua bytecode (`.luac`).
9 changes: 9 additions & 0 deletions extensions/general.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# General API

These are functions, variables, and types that don't really have dedicated APIs.

## Variables

### `settings: table<string, string | number | boolean>`

A table representing each settings' ID and its value.
Loading
Loading