vvvv-fileformat について
vvvv-fileformat は、vvvv gamma で使われる .vl のビジュアルデータフロードキュメントを理解・編集するためのスキルです。パッチを保守またはプログラムから変更する際に、XML 構造、ID、配置、リンクの意味を保つための指針と、再利用可能な Python エディターおよび MCP/CLI アダプターを提供します。
主な機能
- 01.vl ドキュメント構造の解説
- 02ノード、ピン、リンク編集の指針
- 03ID と配置情報の保持
- 04Python エディターを提供
- 05検証規則と編集ガイドを収録
活用シーン
- 01既存の vvvv gamma パッチの変更
- 02.vl ドキュメントとリンクの検証
- 03プログラムからのデータフロー構築
- 04ノードや実行構造の問題調査
MCP 対応
このスキルには、編集機能を MCP クライアントに提供する対応 MCP アダプターと CLI アダプターが含まれます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tebjan/ vvvv-skills --skill vvvv-fileformatインストール後、Claude Code で/vvvv-fileformatを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
best-practices.mdformat-reference.mdhelp-patch-authoring.mdlocal-access.mdprogrammatic-editing.mdscripts/vl-patch-manipulator/.mcp.jsonpyproject.tomlREADME.mdscripts/vl-patch-manipulator/.codex-plugin/plugin.jsonscripts/vl-patch-manipulator/src/vl_patch_manipulator/__init__.pybenchmark.pycatalog.pycli.pydiagnostics.pydocument.pyids.pyoperations.pyserver.pysession.pyspatial.pyscripts/vl-patch-manipulator/tests/test_feedback.pytest_framework.pytest_generator_layout_rules.pytest_input_placements.pytest_peer_order_and_names.pytest_process_orphans.pytest_processes.pytest_server.pytest_slots.pytest_spatial_scopes.py詳細
VL ファイル形式 (.vl)
概要
.vl ファイルは、vvvv gamma 向けのビジュアルデータフロープログラムをエンコードした XML ドキュメントです。主な要素は次のとおりです。
- Document — ルート要素で、依存関係と 1 つのトップレベル Patch を含みます
- Patch — ビジュアル要素 (Nodes、Pads、Links、Canvases) のコンテナです
- Node — 操作呼び出し、型定義、またはリージョンです
- Pin — Node 上の入力/出力です (定義側で定義されます)
- Pad — 値を表示/編集するためのビジュアルデータ要素 (IOBox) です
- Link — 2 つの端点をその ID を参照して接続します
- Canvas — ビジュアル的なグループ化コンテナです (論理スコープは持ちません)
- ProcessDefinition — Fragments によるライフサイクル定義 (Create、Update) です
- Slot — 型定義内の状態フィールドです
既存のドキュメントを編集するときは、要求された変更によって移動が必要にならない限り、未知の XML、宣言順序、ID、ノードの幅、および確立されたジオメトリを保持してください。XML として妥当であることだけでは、ノードサーフェス、ピンの順序、またはレイアウトが正しいことの証明にはなりません。
このスキルには、再利用可能な Python エディターと、それに対応する MCP/CLI アダプターが含まれています。 初回使用時に、7 日以内にコレクション全体で成功した上流チェックがない場合は、共有メンテナンスポリシーに従ってください。 上流と選択的に比較してください。プロジェクトが所有する拡張機能を上書きしないでください。検証済みの汎用的な知見は、バージョン/再現手順および公開の許可とともに提供してください。 レンダラー固有の事実は、それを所有するプロジェクト内に保持してください。インストール済みのコピーは、承認されたインストール/更新ワークフローを通じてのみ更新されます。
XML ルートと名前空間
<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:p="property" xmlns:r="reflection" Id="C2vqbtoStWoOI1eKIKZBBM"
LanguageVersion="2024.6.0" Version="0.128">
</Document>
| プレフィックス | URI | 目的 |
|---|---|---|
p | property | 必須。 子要素としての複合プロパティ (<p:NodeReference>) |
r | reflection | 任意。明示的な null 値のために r:IsNull="true" を使用する場合のみ |
ルート属性: Id (base62 GUID)、LanguageVersion (例: "2024.6.0")、Version (常に "0.128")。
ID システム
すべての要素は一意の Id を持ちます — [0-9A-Za-z] を使用した 22 文字の VL エンコード GUID です。すべての ID はドキュメント内で一意でなければなりません。GUIDEncoders.GuidTobase62(Guid.NewGuid()) またはマニピュレーターの new_vl_id() で生成してください。VL のエンコーディングは、1 つの 128 ビット整数を通常の base62 にしたものではありません。アルファベット ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789、Guid.ToByteArray() のバイト順、およびそれぞれ 11 文字ずつ独立してエンコードされた 2 つの 64 ビット半分を使用します。ソースは、対応する vvvv ソースチェックアウト内の VL.Lang/src/ImmutableModel/Internal/GUIDEncoders.cs です。22 文字という形だけから ID コーデックをでっち上げないでください。
Link の Ids は、2 つ以上のデータハブ ID のカンマ区切りの並びです。VL の Link.SourceId は最初のもので、SinkId は最後のものです。中間の ID は有効なルーティング用データハブであり、余分なリンクや不正なリンクではありません。空の、または片側だけの <Link> は、エディターでの未完了のドラッグ操作によって書き込まれることがあります。vlpatch validate はこれを拒否します。マニピュレーターの明示的な apply --remove-incomplete-links --connect SOURCE_ID TARGET_ID は、意図した端点を確認した後にのみ使用してください。近接しているという理由だけで欠落した端点を推測しないでください。ペアではないというだけの理由で 3 つの ID を持つリンクを破棄しないでください。新しい各 ProcessNode の出力が実際にレンダラーグループに到達することを確認するために、vvvv でパッチを再度開いてください。XML のパース成功だけでは、有効なコントリビューションが確立されたことにはなりません。
要素の階層
Document
├── NugetDependency (0..n)
├── DocumentDependency (0..n)
├── PlatformDependency (0..n)
└── Patch (exactly 1, top-level)
├── Canvas (DefaultCategory, CanvasType="FullCategory")
└── Node (Name="Application")
└── Patch (inner)
├── Canvas (CanvasType="Group")
│ ├── Node (operation calls)
│ ├── Pad (IOBoxes)
│ └── ...
├── Patch (Name="Create")
├── Patch (Name="Update")
├── ProcessDefinition
│ ├── Fragment → Create patch
│ └── Fragment → Update patch
└── Link (0..n)
重要: 依存関係は Document の直接の子であり、Patch の内部ではありません。
依存関係
<NugetDependency Id="..." Location="VL.CoreLib" Version="2024.6.0" />
<DocumentDependency Id="..." Location="./MyOtherFile.vl" />
<PlatformDependency Id="..." Location="VL.Core.dll" />
ほとんどすべてのドキュメントには VL.CoreLib が必要です。IsForward="true" を使用して、型をコンシューマーに再エクスポートしてください。
NodeReference システム (Choices)
<p:NodeReference> プロパティは、Node が何であるかを定義します。対象のシンボルを識別する <Choice> 要素を含みます。
オペレーション呼び出し
<p:NodeReference LastCategoryFullName="Primitive.Math" LastDependency="CoreLibBasics.vl">
<Choice Kind="NodeFlag" Name="Node" Fixed="true" />
<Choice Kind="OperationCallFlag" Name="+" />
</p:NodeReference>
- 第一候補:
Fixed="true"を伴うKind="NodeFlag"(形状インジケーター) - 第二候補:
ProcessAppFlag(ステートフル) またはOperationCallFlag(ステートレス)
カスタム Process/ノードの登録名には、スペースを含まない PascalCase を使用します。実際の
ストック名/インポート名は保持してください。ローカルヘルパーには rename_local_process を
使用して、その定義と対応する呼び出しセレクターが一緒に変わるようにします。表示ラベルだけでは
登録済みノードの名前は変わりません。semantic edits を参照してください。
LastCategoryFullName/LastDependency は最後に確認されたエディターヒントであり、完全な
オーバーロードセレクターではありません。動作する呼び出しから、実際に保存された Choices、
CategoryReference、および任意の PinReference セレクターを保持してください。アダプティブ呼び出しと
明示的オーバーロード呼び出しは異なる契約です。Fixed を無差別に追加/削除しないでください。
スカラーの Cons とシーケンスの Concat については、Spread-to-memory アダプティブ呼び出しと
別個の MutableArray オーバーロードについて、
collection dimensions and adaptive conversions をお読みください。
型定義
<Choice Kind="ContainerDefinition" Name="Process" />
<CategoryReference Kind="Category" Name="Primitive" />
<Choice Kind="ClassDefinition" Name="Class" />
<Choice Kind="RecordDefinition" Name="Record" />
<Choice Kind="InterfaceDefinition" Name="Interface" />
<Choice Kind="ForwardDefinition" Name="Forward" />
リージョン
<Choice Kind="StatefulRegion" Name="Region (Stateful)" Fixed="true" />
<CategoryReference Kind="Category" Name="Primitive" />
<Choice Kind="ApplicationStatefulRegion" Name="If" />
リージョンは StatefulRegion を FIRST Choice として使用します (NodeFlag ではありません)。If/ForEach には ApplicationStatefulRegion を、Cache には ProcessStatefulRegion を使用します。
Node 要素
<Node Name="MyNode" Bounds="300,200,65,19" Id="...">
<p:NodeReference>...</p:NodeReference>
<Pin Id="..." Name="Input" Kind="InputPin" />
<Pin Id="..." Name="Output" Kind="OutputPin" />
</Node>
主な属性: Id、Name、Bounds ("X,Y" または "X,Y,W,H")、Summary、Tags。
Pin 要素
<Pin Id="..." Name="Value" Kind="InputPin" DefaultValue="42" />
<Pin Id="..." Name="Result" Kind="OutputPin" />
Kind の値: InputPin、OutputPin、StateInputPin、StateOutputPin、ApplyPin。
可視性: Visible (デフォルト)、Optional、OnCreateDefault、Hidden。
Pad 要素 (IOBox)
<Pad Id="..." Bounds="200,160,80,20" ShowValueBox="true" isIOBox="true" Value="3.14"
Comment="My Value">
<p:TypeAnnotation LastCategoryFullName="Primitive" LastDependency="CoreLibBasics.vl">
<Choice Kind="TypeFlag" Name="Float32" />
</p:TypeAnnotation>
</Pad>
isIOBox の小文字の i に注意してください。一般的な型: Boolean、Int32、Float32、Float64、String、Vector2、Vector3。
Comment Pad
<Pad Id="..." Bounds="100,100,400,25" ShowValueBox="true" isIOBox="true"
Value="Title text here">
<p:TypeAnnotation><Choice Kind="TypeFlag" Name="String" /></p:TypeAnnotation>
<p:ValueBoxSettings>
<p:fontsize p:Type="Int32">9</p:fontsize>
<p:stringtype p:Assembly="VL.Core" p:Type="VL.Core.StringType">Comment</p:stringtype>
</p:ValueBoxSettings>
</Pad>
可視の見出しは、fontsize を 15 にした同じ構造を使用します。クリック可能な URL は、
stringtype を Link に設定した同じ String Pad を使用します。
Link 要素
<Link Id="..." Ids="outputPinId,inputPinId" />
Ids の形式: "sourceId,sinkId" または "sourceId,intermediateHubId,sinkId" (およびそれより長い経路) — ソースが最初、シンクが最後です。参照リンクには IsHidden="true" を使用します。IsFeedback="true" は任意のノードリンクに対する遅延ではありません。検査対象のコンパイラーはそのリンクの代入をスキップするだけで、保存された状態を作成しません。まず実際のカメラ/入力の契約を確認してください。レンダラーがすでにウィンドウ入力を接続されたカメラに関連付けている場合、後方リンクや Slot は不要です。明示的なウィンドウ入力フィードバックを必要とするカメラについては、検証済みの Slot パターンをコピーしてください。Process の内部 Patch 上の 1 つの Slot、その SlotId を共有する別個の読み取り/書き込み Pad、および通常のリンクです。読み取り Pad はカメラに供給し、ウィンドウは書き込み Pad に供給します。直接的なカメラ/ウィンドウのサイクルを閉じて、それを単にフィードバックとラベル付けしないでください。
ProcessDefinition とフラグメント
<Patch Id="innerPatchId">
<Canvas Id="..." CanvasType="Group" />
<Patch Id="createId" Name="Create" />
<Patch Id="updateId" Name="Update" />
<ProcessDefinition Id="...">
<Fragment Id="..." Patch="createId" Enabled="true" />
<Fragment Id="..." Patch="updateId" Enabled="true" />
</ProcessDefinition>
</Patch>
フラグメントの Patch 属性は、兄弟の <Patch> 要素の Id を参照します。
コンテナーが Process である Application の場合、このライフサイクルブロックは
必須です。Create と Update が空であっても同様です。Group キャンバスだけでは
表示可能な XML にすぎません。vvvv はそれを開いてすべてのノードとリンクを描画できますが、
実行エントリーポイントがないため、データフロー全体がグレーのままで決して実行されません。
バリデーターとジェネレーターは、名前付きの兄弟パッチの両方と、その両方をターゲットとする
有効なフラグメントの両方を必須とする必要があります。
制御フロー領域
領域は 4 値の Bounds ("X,Y,W,H") を使用し、境界に ControlPoints を持ちます:
<Node Bounds="100,200,400,300" Id="...">
<p:NodeReference LastCategoryFullName="Primitive" LastDependency="Builtin">
<Choice Kind="StatefulRegion" Name="Region (Stateful)" Fixed="true" />
<CategoryReference Kind="Category" Name="Primitive" />
<Choice Kind="ApplicationStatefulRegion" Name="If" />
</p:NodeReference>
<Patch Id="...">
<Canvas Id="..." CanvasType="Group"></Canvas>
<Patch Id="thenId" Name="Then" />
<Fragment Id="..." Patch="thenId" Enabled="true" />
</Patch>
<ControlPoint Id="..." Bounds="150,200" Alignment="Top" />
<ControlPoint Id="..." Bounds="150,500" Alignment="Bottom" />
</Node>
領域パッチ名: If は Then/Else を使用し、ForEach は Create/Update/Dispose を使用し、Cache は Create/Update を使用します。
ControlPoint は双方向の領域ポータルであり、従来の入力ピンではありません。
リンクは、領域の外側から合法的にこれを対象とし、内側から (または領域出力の場合はその逆に) これをソースとします。CPU インスタンサトランスフォームには、同梱の
PatchSession.add_matrix_repeat_builder(...) を使用してください。これは正規の
Cache/Repeat/MutableArray 構造を作成し、割り当てと反復に単一のカウントを使用し、
安定した ReadOnlyMemory<Matrix> エンドポイントを返します。
その位置入力は、直接の TransformSRT 変換ではなく、Repeat の XyZ.Input に中継される Vector2 スプレッドです。そのスカラー Y とスケーリングのエンドポイントは
別個です。明示的な MutableArray<T> -> ReadOnlyMemory<T> オーバーロード
参照を保持してください。構造的な XML 検証だけでは vvvv の型解決を証明できません。
TypeAnnotation
<p:TypeAnnotation>
<Choice Kind="TypeFlag" Name="Float32" />
</p:TypeAnnotation>
<p:TypeAnnotation LastCategoryFullName="Collections" LastDependency="VL.Collections.vl">
<Choice Kind="TypeFlag" Name="Spread" />
<p:TypeArguments>
<TypeReference LastCategoryFullName="Color" LastDependency="CoreLibBasics.vl">
<Choice Kind="TypeFlag" Name="RGBA" />
</TypeReference>
</p:TypeArguments>
</p:TypeAnnotation>
スロット要素 (状態フィールド)
共有リソースの場合、複数のアクセサ Pad が 1 つの名前付きスロットをローカルに読み取ることができます。
スロットは実際の状態です。初期化、読み取り/書き込みのコンパイラ順序、リソース
ライフタイムは依然として重要です。配置によって 1 フレーム遅延が保証されるわけではありません。
リソースプロデューサを複製する代わりに PatchSession.add_slot_read(...) を使用してください。
ローカルプロセス内で、PatchSession.add_input_placement(...) を使用して同じ入力の配置を繰り返します。これは、既存のシグネチャ Pin への隠し参照リンクを持つ新しい ControlPoint を作成します。別のパラメータや発明された DefinitionId ではありません。読み取りをそのコンシューマのそばに、関連するクリエイティブ
コントロールをまとめて保持してください。programmatic-editing.md を参照してください。
<Slot Id="..." Name="MyField">
<p:TypeAnnotation><Choice Kind="TypeFlag" Name="Float32" /></p:TypeAnnotation>
<p:Value>0.5</p:Value>
</Slot>
完全な最小例
<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:p="property" Id="A1b2C3d4E5f6G7h8I9j0Kl"
LanguageVersion="2024.6.0" Version="0.128">
<NugetDependency Id="B2c3D4e5F6g7H8i9J0k1Lm" Location="VL.CoreLib"
Version="2024.6.0" />
<Patch Id="C3d4E5f6G7h8I9j0K1l2Mn">
<Canvas Id="D4e5F6g7H8i9J0k1L2m3No" DefaultCategory="Main"
BordersChecked="false" CanvasType="FullCategory" />
<Node Name="Application" Bounds="100,100" Id="E5f6G7h8I9j0K1l2M3n4Op">
<p:NodeReference>
<Choice Kind="ContainerDefinition" Name="Process" />
<CategoryReference Kind="Category" Name="Primitive" />
</p:NodeReference>
<Patch Id="F6g7H8i9J0k1L2m3N4o5Pq">
<Canvas Id="G7h8I9j0K1l2M3n4O5p6Qr" CanvasType="Group" />
<Patch Id="H8i9J0k1L2m3N4o5P6q7Rs" Name="Create" />
<Patch Id="I9j0K1l2M3n4O5p6Q7r8St" Name="Update" />
<ProcessDefinition Id="J0k1L2m3N4o5P6q7R8s9Tu">
<Fragment Id="K1l2M3n4O5p6Q7r8S9t0Uv"
Patch="H8i9J0k1L2m3N4o5P6q7Rs" Enabled="true" />
<Fragment Id="L2m3N4o5P6q7R8s9T0u1Vw"
Patch="I9j0K1l2M3n4O5p6Q7r8St" Enabled="true" />
</ProcessDefinition>
</Patch>
</Node>
</Patch>
</Document>
検証ルール
- すべての ID は一意でなければなりません (22 文字の base62 GUID)
xmlns:p="property"はDocument上に存在しなければなりませんVersion="0.128"は常に必須です- フラグメント
Patchは既存の兄弟 Patch ID を参照しなければなりません - リンク
Ids: 少なくとも 2 つの空でないデータハブ ID — ソースが最初、シンクが最後。中間ハブは保持してください CanvasType="FullCategory"はルートキャンバスのみに指定します- すべてのドキュメントに
VL.CoreLib依存関係が必要です - アプリケーションノードがエントリポイントです (Name="Application", ContainerDefinition)。また、Process Application には Create + Update の兄弟パッチと、両方に対して有効な ProcessDefinition フラグメントが必要です
- 要素名は大文字と小文字を区別します (
Patchでありpatchではありません) isIOBoxは小文字のiを使用します- 依存関係は
PatchではなくDocumentの子です - リポジトリ所有のテキストはバイトオーダーマークなしの UTF-8 です
- パブリックピンとその順序は、ライブ/リフレクションされたカタログまたは本番シグネチャから取得され、発明されてはなりません
- 表示されるヘルプ文は String Pad アノテーションを使用します。XML コメントはキャンバスヘルプではありません
- リンク端点の型は互換性がなければなりません。検証済みのガンマバージョンでは、
Integer32とInteger32 (Unsigned)は暗黙的に交換可能ではありません。拒否されたリンクは値を渡しません。型付き IOBox は、新しい Link 表現ではなく、その TypeAnnotation を実際のコンシューマ契約に修正する必要があるかもしれません。シェーダーファクトリは、実際のリフレクションルールからピン型を決定します。シェーダーシグネチャとライブノードメタデータを比較してください。ピン型が変更された場合は、影響を受ける IOBox/コンシューマをまとめて移行してください。エディタの link-type diagnostic はカタログ既知の端点型のみをチェックし、実際のシグネチャが利用できない場合は沈黙したままです。
よくある間違い
xmlns:p="property"名前空間宣言を忘れる- 依存関係を
DocumentではなくPatchの中に置いてしまう - Link の方向が逆になっている(最初の ID はソース/出力でなければなりません)
- 表示されている Application Group キャンバスを、その Create/Update パッチや有効な ProcessDefinition フラグメントを省略したまま実行可能なものとして扱ってしまう
- Bounds の形式が間違っている(カンマを使用し、スペースは入れない:
"100,200,65,19") isIOBoxの代わりにIsIOBoxを使用している- ノードの中心をピン位置として扱ってしまう
- ピンをアルファベット順に並べたり、メイン出力を診断出力の後に配置したりしてしまう
- すでに手作業で配置されたパッチに対してドキュメント全体のレイアウトを実行してしまう
- 視覚的な
Overlayを意図していた場面で制御フロー領域を使用してしまう、またはその逆 - 表示されるコメントを XML の `` として書いてしまう
GridSpread (2D)の Width を外側のセル中心間の距離として扱ってしまう。中央揃えの場合、Centerはグリッドの中点であり、セル中心の間隔は各軸でWidth / Countです。位置 x = -1.6, 0, 1.6 および z = 0, -2.5 の 3×2 グリッドを整列させるには、Center = (0, -1.25)、Width = (4.8, 5.0)、Count = (3, 2) を使用します。XML のリンクだけでなく、レンダリングされたパッチに対して検証してください。
すべての属性、Choice の種類、シリアライズの詳細を含む完全な要素リファレンスについては、format-reference.md を参照してください。 レイアウト、正確なピンアンカー、ノードのサイズ設定、および人手を保つ編集ルールについては、座標を変更する前に best-practices.md をお読みください。
ローカルな Process 定義を持つドキュメントでは、layout_analysis(canvas=...) と render_svg(..., canvas=...) を使用して、アタッチされた
Canvas ごとにジオメトリを検査してください。
独立したヘルパー座標を 1 つのグローバルキャンバスとして扱ってはいけません。
繰り返し配置された入力や Slot パッドは、移動しても 2 座標の Bounds を保持します。
それらのラベルは衝突レビューに含める必要があります。
programmatic-editing.md を参照してください。
ヘルプパッチの分類、表示される注釈、オーバーレイ、Help Browser マニフェスト、隣接アセット、および検証については、help-patch-authoring.md をお読みください。
損失を保つ自動編集と、リポジトリの永続的なパッチマニピュレーターについては、programmatic-editing.md をお読みください。Python の edit_batch、MCP の vl_edit、CLI の vlpatch edit は、1 つの発見可能なセマンティックコントラクトを共有しています。現在の引数には vl_capabilities / vlpatch capabilities を、スコープ ID には vl_canvases を使用してください。新しいオーサリング API は、同じ変更の中で 3 つのサーフェスすべてに公開され、パリティテストされる必要があります。すでに実行中の MCP プロセスは、追加されたツールを読み込むために再起動/再接続が必要です。ファイルのみの検証は、ライブの vvvv コンパイルではありません。