スプライト間でロジックを共有
得点計算、持ち物、会話の規則を1か所にまとめます。スクリプトを複製せず、すべてのスプライトとステージから同じ関数を呼び出します。
TurboWarp拡張機能 · 利用者ガイド
Named Functionsは、スクリプトを「名前・説明・引数のJSON Schema」を持つ関数に変えます。どのスプライトからでも呼び出して値を受け取れます。結果を待つことも、複数の呼び出しを先に始めて後でまとめて受け取ることもできます。関数をツールとして公開すれば、AIのツール呼び出しなど他の拡張機能からも使えます。
何に役立つか
ブロック定義(カスタムブロック)は1つのスプライトに属し、値を返せません。メッセージはすべてのスプライトに届きますが、引数も結果も運べません。Named Functionsはその隙間を埋め、どのスクリプトからでも呼べて、入力が検査され、本当に値を返す処理の単位を提供します。
得点計算、持ち物、会話の規則を1か所にまとめます。スクリプトを複製せず、すべてのスプライトとステージから同じ関数を呼び出します。
JSONを渡してJSONを受け取ります。数値・文字列・リスト・オブジェクトを返せ、引数はスクリプト開始前に検査されます。
ツールとして公開した関数はOpenAIのfunction calling形式で一覧化され、AI拡張機能がプロジェクトにできることを知り、呼び出せます。
はじめに
関数はdefine functionハットを読み取って見つけるため、起動時の登録は不要です。ハットを置き、本体を書き、呼び出すだけです。
サンドボックスなしで実行を有効にして、カスタム拡張機能として読み込みます。関数スクリプトの開始にVMランタイムを使うためです。
任意のスプライトにdefine functionを置きます。名前・説明・args schemaはハットに直接入力します。これらはリテラル文字列である必要があります。
function argumentで入力を読み、returnで終えます。returnせずに終わったスクリプトはnullを返します。
どのスプライトからでも、JSON引数を付けてcall functionを使います。ブロックは関数の終了を待ち、戻り値を返します。
引数が不正ならスクリプトは開始されず、last function errorが一致しなかった項目を示します。
バージョン固定のビルドを使ってください:@kubohiroya/turbowarp-named-functions@0.1.2。信頼できる配布元の拡張機能だけを読み込んでください。
使用例
1つの結果を待つ、複数の呼び出しを始めてまとめて受け取る、どの関数を呼ぶかを他のプログラムに任せる——の3通りです。
関数は独立したスクリプトとして動くため、call functionは最低1フレームかかります。
start functionは{"$promise":"p_1"}のようなプロミス参照を返します。await allは[3,7]を返し、失敗した呼び出しは{"$error": メッセージ}になります。
ツールには説明が必要です。モデルが読むのはこの説明です。引数がスキーマに一致していても、ツールの引数は信頼できない入力として扱ってください。
スキーマ
args schemaはJSON Schemaのオブジェクトで、関数の実行前に小さなインタープリターが検査します(コード生成はしません)。returns schemaを入力すると戻り値も検査し、空欄なら戻り値は検査しません。
{
"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またはfalse)、items、enum、const、minimum、maximum、minLength、maxLength、minItems、maxItems。
"type": "object"である必要があります。$.score must be >= 0)。動作
関数はブロック定義ではなくスクリプトです。そのため共有でき、非同期に動きますが、使う前に知っておきたい規則もあります。
| 状況 | 動作 |
|---|---|
| 呼び出しごと | 最低1フレームかかります。細かいループにはブロック定義を使ってください。 |
| 同じ関数への複数の呼び出し | 順番に1つずつ実行されます。異なる関数は並行して動きます。 |
| 関数が直接または間接に自分を呼ぶ | 永久に待つ代わりにReentrant call: a -> b -> aで失敗します。再帰にはブロック定義を使ってください。 |
| 関数が30秒を超えて動く | タイムアウトで失敗します。 |
| 同時に開始した呼び出しが8件を超える | 以降のstart functionは空きが出るまで待ちます。 |
| プロジェクトを停止 | 実行中の呼び出しは失敗し、プロミス参照は消去されます。 |
| 同じ名前のハットが2つある、またはハットの入力がリテラルでない | 関数は定義されず、last function errorが理由を示します。 |
アプリケーション統合
Composition APIを使うと、単体版のブロックを登録せずに、同じレジストリとディスパッチャーを別の拡張機能で利用できます。利用側は自分のdefine functionハットのopcodeを持ち、3つのブロックからAPIへ処理を渡します。
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)。argumentsFor(thread)。returnFrom(thread, value)。tools()は公開された関数の一覧を返し、call(…, {exportedOnly: true})は公開されていない関数を拒否します。cancelAll(reason)は待機中の呼び出しを失敗させ、release()はランタイムのリスナーも解除します。ブロック一覧
すべてのブロック・引数・既定値は、英語版の完全なブロックリファレンスに載っています。
items.0.nameのように引数を1つ読みます。トラブルシューティング
まずlast function errorを確認してください。各項目を開くと、よくある原因と最短の対処が分かります。
NAME・DESCRIPTION・SCHEMA、および空でないRETURNSは、レポーターで組み立てず、ハットに直接入力してください。名前は1〜64文字の英数字・_・-、スキーマは"type": "object"を持つ正しいJSONである必要があり、同じ名前のハットが他にあってはいけません。
ARGSはargs schemaに一致するJSON文字列である必要があります。{"a":"1"}は数値ではなく文字列を渡しています。JSONブロックや、正しいJSONになるjoinでARGSを組み立ててください。
内側の呼び出しが外側の終了を永久に待つことになるため、名前付き関数を通した再帰は意図的に拒否されます。再帰する処理はブロック定義に書き、関数からそれを呼んでください。
関数のスクリプトがreturnに到達せずに終わったため、結果はnullです。すべての分岐を確認してください。RETURNSを設定している場合、returnがないとnullとして検査され、失敗することがあります。
呼び出しごとに最低1フレームかかります。内側の処理をブロック定義に移すか、start functionで呼び出しを始めてawait allでまとめて受け取ってください。
export asをtoolにし、DESCRIPTIONを入力してください。説明のないツールは定義されません。