Share logic across sprites
Keep scoring, inventory, or dialogue rules in one place. Every sprite and the Stage call the same function instead of copying scripts.
Complete block reference (11 blocks)
TurboWarp extension · User guide
Named Functions turns a script into a function with a name, a description, and a JSON Schema for its arguments. Any sprite can call it and get a value back—wait for the result, or start several calls and collect them later. Mark a function as a tool and other extensions, such as AI tool calling, can use it too.
Why use it
A custom block belongs to one sprite and cannot return a value. Broadcasts reach every sprite but carry no arguments and no result. Named Functions fills the gap: a callable unit that any script can reach, with checked inputs and a real return value.
Keep scoring, inventory, or dialogue rules in one place. Every sprite and the Stage call the same function instead of copying scripts.
Pass JSON in and get JSON out. A function can return a number, text, a list, or an object, and arguments are checked before the script starts.
Functions exported as tools are listed in the OpenAI function-calling shape, so an AI extension can see what your project can do and call it.
Quick start
Functions are found by reading define function hats, so there is nothing to register at startup. Place the hat, write the body, and call it.
Load Named Functions as a custom extension with Run extension without sandbox enabled. It needs the VM runtime to start function scripts.
Drag define function into any sprite. Type the name, description, and args schema directly into the hat—these fields must be literal text.
Read inputs with function argument and finish with
return. A script that ends without return reports
null.
Use call function with JSON arguments from any sprite. The block waits for the function and reports its return value.
Invalid arguments fail before the script starts, and last function error names the field that did not match.
Use the version-pinned build:
@kubohiroya/turbowarp-named-functions@0.1.2.
Load extensions only from sources you trust.
Examples
Wait for one result, start several calls and collect them together, or let another program decide which function to call.
call function takes at least one frame, because the function runs as its own script.
start function reports a promise reference such as
{"$promise":"p_1"}. await all reports
[3,7]; a failed call becomes {"$error": message}.
A tool needs a description—it is what the model reads. Treat tool arguments as untrusted input, even though they match the schema.
Schemas
The args schema is a JSON Schema object, checked by a small interpreter—no code is generated—before the function runs. Fill in returns schema to check the return value as well, or leave it blank to skip return checks.
{
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"score": {"type": "number", "minimum": 0},
"tags": {"type": "array", "items": {"type": "string"}}
},
"required": ["name", "score"],
"additionalProperties": false
}
type, properties, required,
additionalProperties (true or false), items,
enum, const, minimum, maximum,
minLength, maxLength, minItems, and
maxItems.
"type": "object".$.score must be >= 0.Behavior
Functions are scripts, not custom blocks. That makes them shareable and asynchronous, and it also sets a few rules worth knowing before you build on them.
| Situation | What happens |
|---|---|
| Each call | Takes at least one frame. Use custom blocks for tight loops. |
| Several calls to one function | Run one at a time, in order. Different functions run concurrently. |
| A function calls itself, directly or indirectly | Fails with Reentrant call: a -> b -> a instead of waiting forever. Use a custom block for recursion. |
| A function runs longer than 30 seconds | The call fails with a timeout. |
| More than 8 started calls at once | Further start function calls wait for a free slot. |
| The project stops | Running calls fail and promise references are cleared. |
| Two hats with the same name, or non-literal hat fields | The function is not defined; last function error explains why. |
Application integration
The Composition API gives another extension the same registry and dispatcher without registering the standalone blocks. The consumer owns its own define function hat opcode and forwards three blocks to it.
import {createNamedFunctions} from
'@kubohiroya/turbowarp-named-functions/composition';
const functions = createNamedFunctions({
runtime: Scratch.vm.runtime,
functionHatOpcode: 'myextension_defineFunction'
});
const tools = functions.tools();
const score = await functions.call(
'get_score', {}, {exportedOnly: true});
functions.release();
matchHat(NAME, thread) from its define function hat.argumentsFor(thread) from its argument reporter.returnFrom(thread, value) from its return block.tools() lists exported functions; call(…, {exportedOnly: true}) refuses anything not exported.cancelAll(reason) fails pending calls; release() also detaches runtime listeners.Block reference
Every block, argument, and default value is listed in the complete block reference below.
items.0.name.Troubleshooting
Check last function error first. Open each item for the most common cause and the shortest fix.
NAME, DESCRIPTION, SCHEMA, and a non-empty RETURNS must be typed into the hat, not
built from reporters. The name must be 1–64 letters, digits, _, or
-, the schema must be valid JSON with "type": "object", and
no other hat may use the same name.
ARGS must be JSON text that matches the args schema. {"a":"1"} passes a
string, not a number. Build ARGS with JSON blocks or a join that
produces valid JSON.
Recursion through named functions is rejected on purpose, because the inner call would wait for the outer one forever. Put recursive logic in a custom block and call that from the function.
The function script ended without reaching return, so the result is
null. Check every branch. If RETURNS is set, a missing return is checked
as null and may fail.
Each call takes at least one frame. Move the inner work into a custom block, or start the calls with start function and collect them with await all.
Set export as to tool and fill in DESCRIPTION. A tool
without a description is not defined.
All 11 blocks are documented below, including compatibility blocks and blocks available through optional features. Select a block to read its behavior, arguments, default values, and menu choices. Each block has a permanent link.
define function [NAME] description [DESCRIPTION] args schema [SCHEMA] returns schema [RETURNS] export as [EXPORT]Defines a named function. NAME, DESCRIPTION, and SCHEMA must be literal text. RETURNS is an optional JSON Schema for the return value; leave it blank to disable return validation.
Block type: HAT. Opcode: defineFunction. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
NAME | STRING | add | |
DESCRIPTION | STRING | Adds two numbers. | |
SCHEMA | STRING | {"type":"object","properties":{"a":{"type":"number"},"b":{"type":"number"}},"required":["a","b"]} | |
RETURNS | STRING | | |
EXPORT | STRING | none |
|
In the fixed-input editor, EXPORT is chosen from none or tool. The editor changes only this stored value; it does not run the function or the hat, and it leaves NAME, DESCRIPTION, SCHEMA, and RETURNS unchanged. The GUI Dialogs and FixedInputs startup flags are OFF by default; enable both and reload to use the form. Unchanged raw values are not rewritten, and connected reporters are not evaluated.
function argument [PATH]Inside a function, reports the argument at a dotted path such as a or items.0.name.
Block type: REPORTER. Opcode: functionArgument. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
PATH | STRING | a |
function arguments JSONInside a function, reports all arguments as JSON text.
Block type: REPORTER. Opcode: functionArgumentsJson. Permanent link
This block has no arguments.
return [VALUE]Inside a function, returns a value and ends the script. JSON text is returned as JSON; other text is returned as a string.
Block type: COMMAND. Opcode: returnValue. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
VALUE | STRING | 0 |
call function [NAME] with [ARGS]Calls a function and waits for its result. ARGS is JSON text and is checked against the args schema. Takes at least one frame.
Block type: REPORTER. Opcode: callFunction. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
NAME | STRING | add | |
ARGS | STRING | {"a":1,"b":2} |
start function [NAME] with [ARGS]Starts a function without waiting and reports a promise reference as JSON text.
Block type: REPORTER. Opcode: startFunction. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
NAME | STRING | add | |
ARGS | STRING | {"a":1,"b":2} |
await [PROMISE]Waits for a promise reference from start function and reports its result.
Block type: REPORTER. Opcode: awaitResult. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
PROMISE | STRING | {"$promise":"p_1"} |
await all [PROMISES]Waits for a JSON array of promise references and reports a JSON array of results. Failed calls become {"$error": message}.
Block type: REPORTER. Opcode: awaitAll. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
PROMISES | STRING | [] |
[PROMISE] settled?Reports whether a started function has finished, without waiting.
Block type: BOOLEAN. Opcode: isSettled. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
PROMISE | STRING | {"$promise":"p_1"} |
function [NAME] defined?Reports whether a valid define function hat with this name exists.
Block type: BOOLEAN. Opcode: isDefined. Permanent link
| Argument | Type | Default value | Menu choices |
|---|---|---|---|
NAME | STRING | add |
last function errorReports the most recent function error, or an empty string.
Block type: REPORTER. Opcode: lastError. Permanent link
This block has no arguments.