msw-behaviourtree について
MSW BehaviourTree は、MSW の `.behaviourtree` ファイルを作成するスキルです。プロジェクトファイルから専用のノード・型仕様を生成し、固定のグラフ規則と合わせてツリー構築と検証を案内します。
主な機能
- 01プロジェクト固有の BT 仕様生成
- 02プロジェクトファイルからカスタムノードを検出
- 03ノードとプロパティの型対応付け
- 04グラフ構造と子ノードの制約提示
- 05Blackboard とノードプロパティの設定支援
活用シーン
- 01MSW プロジェクト用のビヘイビアツリー作成
- 02作成前のカスタムノード ID とプロパティ確認
- 03Composite、Decorator、Action の構造化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ msw-git/ msw-ai-coding-plugins-official --skill msw-behaviourtreeインストール後、Claude Code で/msw-behaviourtreeを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/node-catalog.mdskeleton-full.jsonskeleton-minimal.jsonscripts/build-spec.cjs詳細
MSW BehaviourTree
MSW .behaviourtree ファイルのエンドツーエンドの作成スキルです。プロジェクト固有の作成仕様(<ProjectRoot>/.behaviourDocs/bt-spec.md)と、ツリーの生成の両方を担います。固定のグラフルールとスケルトンは、このスキルの references/ にあります。プロジェクトごとの仕様は、このスキルのローカルな scripts/build-spec.cjs によって構築(または再構築)されます。
🚦 実行順序(この順序に従ってください)
0. プロジェクト仕様(bt-spec.md)を構築/更新する
仕様は、プロジェクト固有のすべてのデータポイントの信頼できる唯一の情報源です。各カスタムアクション/デコレーター/複合ノードの definitionId、btNodeType、表示される propertyKey 名、およびこのプロジェクトの CoreVersion が付与されたシリアライズ済みの Type.type 文字列が含まれます。
構築(再構築)するタイミング:
- プロジェクトで初めて BT を扱うとき(まだ
.behaviourDocs/bt-spec.mdがない場合)。 - BT ノードの表面領域に影響する変更を行った後:
.mluaがActionNode/DecoratorNode/CompositeNodeを継承する、新規作成/名前変更/削除された.codeblock- そのような
.mlua内のproperty行の追加/削除/名前変更 Environment/configのCoreVersionの更新(シリアライズ済みの型文字列にはバージョンが付与されます)。
- ユーザーが、最近 BT コードブロックまたは
.mluaプロパティを追加/変更したと伝えたとき(古い UUID やプロパティの欠落は、壊れたツリーを気付かれないまま生成します)。 - 後続の検証(ステップ 7)で、
definitionId、propertyKey、またはバージョンの不一致が検出されたとき。
実行方法 — このスキルのローカルスクリプトを呼び出します:
node "scripts/build-spec.cjs" --projectRoot "<MSW project root>"
現在の作業ディレクトリがすでに MSW プロジェクトのルートであれば、--projectRoot は省略できます。Node.js が PATH に必要です(ほかの依存関係はなく、標準ライブラリの fs/path のみを使用します)。
任意のオーバーライド(長形式のフラグ、大文字と小文字を区別しません):
| フラグ | デフォルト | 備考 |
|---|---|---|
--projectRoot | 現在の作業ディレクトリ | スキャンする MSW プロジェクトのルート |
--outputPath | <ProjectRoot>/.behaviourDocs/bt-spec.md | フォルダーがない場合は作成されます |
--coreVersion | <ProjectRoot>/Environment/config の CoreVersion フィールドから読み取り | 設定ファイルがない場合は必須 |
オーバーライドを指定する例:
node "scripts/build-spec.cjs" --projectRoot "C:/path/to/project" --coreVersion <CoreVersion>
Environment/config が存在せず、--coreVersion も指定されていない場合、スクリプトはエラーをスローします。代替のデフォルト値はありません。
仕様に含まれる内容:
- プロジェクトのメタデータ — プロジェクトのルート、
CoreVersion、生成時刻、検出されたノード数。 - 複合ノード — 固定の
definitionId/btNodeTypeを持つ組み込み名、および検出されたカスタム複合ノード(.mluaでextends CompositeNodeを宣言)。 - カスタムアクションノード —
Name、definitionId、btNodeType、表示されるプロパティ名。 - カスタムデコレーターノード — アクションノードと同じ形式。
- 型マップ — mlua 型からシリアライズ済み
MODNativeType.typeへの対応、および Blackboard のObjectValueの形式。
UUID はプロジェクト内の実際の .codeblock ファイルから取得されます。仕様で UUID が作り出されることはありません。@HideFromInspector プロパティは自動的に除外されます。固定の作成ルール、ファイルのひな形、検証チェックリストは、生成される仕様ではなく、このスキルの references/ にあります。
構築(再構築)後は、新しく書き出された <ProjectRoot>/.behaviourDocs/bt-spec.md を読み、以下の手順に進みます。コンパクトな仕様には意図的にプロパティ名だけが記載されています。nodeProperties を構築する際は、対応する .mlua ファイルで各プロパティの mlua 型とデフォルト値を確認し、その後 bt-spec.md §4 の型マップを propertyType.type に使用します。
最小限の有効なツリーについては references/skeleton-minimal.json を、すべての任意フィールドを設定した Composite+Decorator+Action+Blackboard の例については references/skeleton-full.json を、固定のグラフルールについては references/node-catalog.md を読みます。また、プロジェクト内に既存の .behaviourtree(**/*.behaviourtree)があれば、慣例を確認するために読みます。ひな形の {CORE_VERSION} は bt-spec.md の CoreVersion に置き換えてください。トップレベルだけでなく、Blackboard 変数と nodeProperties 内のすべての MOD.Core.* 型文字列も置き換えます。
1. ユーザーから入力を収集する
コンテキストから確認するか、曖昧な点があれば AskUserQuestion で質問します。
| 項目 | 説明 | 例 |
|---|---|---|
name | ツリーの表示名 | "PatrolAndChase" |
| 保存先 | .behaviourtree の場所(プロジェクトルートからの相対パス) | RootDesk/MyDesk/PatrolAndChase.behaviourtree |
| ツリー構造 | 想定するノードグラフ(ルートコンポジット+子ノード) | Sequence → [Chase, MoveTo] |
| カスタムノード | ツリーが参照するアクション/デコレーター/コンポジットのコードブロック | Chase、MoveTo、Jump |
| ブラックボード変数 | 変数名+型+初期値 | TargetEntity: Entity、MoveSpeed: number = 10.0 |
| ノードプロパティ | 各カスタムノードで、どのプロパティがどのブラックボード変数に対応するか | Chase.TargetEntityKey = "TargetEntity" |
カスタムノードの存在確認(必須): ユーザーが挙げたカスタムアクション/デコレーター/コンポジットの名前はすべて、bt-spec.md §1/§2/§3 に記載されている必要があります。参照されたノードが仕様にない場合は、停止してユーザーに質問してください。UUID を作り出したり、名前からノードの存在を推測したり、Step 0 を再実行せずに進めたりしてはいけません。
2. UUID を生成する
必要な UUID は次のとおりです。
- ファイル用 UUID を 1 つ。
EntryKeyとContentProto.Json.idに指定します(どちらも同一の値で、どちらもbehaviourtree://が前置されます)。 Nodes内の各ノードに 1 つずつ UUID(nodeId)。
node -e "console.log(require('node:crypto').randomUUID())"
最初に UUID を生成してスクラッチテーブルに記録し、その後組み立てます。ファイル UUID を nodeId として再利用してはいけません。
3. すべての definitionId を解決する
| ノードの分類 | definitionId の値 | btNodeType |
|---|---|---|
組み込みコンポジット(SequenceNode、SelectorNode、ParallelNode) | nodeName と同じ文字列 | 1 |
カスタムコンポジットノード(extends CompositeNode) | bt-spec.md §1 の値 | 1 |
| カスタムアクションノード | bt-spec.md §2 の値 | 0 |
| カスタムデコレーターノード | bt-spec.md §3 の値 | 2 |
カスタムノードの UUID は bt-spec.md から取得します(実際の .codeblock ファイルから読み取った値です)。それ以外のソースから取得してはいけません。
4. ブラックボードを構築する
各変数について、bt-spec.md §4 の Type.type 文字列と ObjectValue の形をそのままコピーします。バージョン付きの部分文字列(Version=<CoreVersion>)は完全に一致している必要があります。誤記があると、デシリアライズがひそかに失敗します。
Variables は順序付き配列です。各要素は { Name, Type: { "$type": "MODNativeType", type: "<from spec>" }, ObjectValue: <from spec> } です。ObjectValue には $type の判別子を含めません(.model ファイルの Value とは異なります)。
Component/ComponentRef の場合、ComponentId は <entity-uuid>:<ComponentName>(エンジンコンポーネント)または <entity-uuid>:<scriptCodeblockUuid>:<ScriptComponentName>(スクリプトコンポーネント)です。プロジェクト内の既存のシリアライズ済みサンプルに倣ってください。
数値の ObjectValue は浮動小数点リテラル形式を使用します(3 ではなく 3.0)。
実行時の注意: ブラックボードはエントリのツリーに属します。スクリプトが後からそのコンポーネントで
AIComponent:SetRootNode(...)を呼び出すと、エントリのツリーとこのブラックボードは破棄されます。その結果、BlackBoardはnilを読み取り、*Keyプロパティは解決されなくなります。実行時のルート切り替えと、ブラックボードに依存するツリーを併用しないでください。
4.5 ノードのプロパティ値を解決する
nodeProperties が必要なカスタムノードごとに、次の手順を実行します。
- そのノードの
bt-spec.md§1/§2/§3 にpropertyKeyが存在することを確認します。 - プロジェクト内で
script <NodeName> extends ActionNode、extends DecoratorNode、またはextends CompositeNodeを検索して、対応する.mluaを見つけます。一致するファイルが複数ある場合は、同階層の.codeblockにbt-spec.mdのものと完全に一致するdefinitionIdUUID があるファイルを優先します。それでも判断できない場合は、ユーザーに確認します。 .mluaに表示されているproperty宣言を読み取ります。@HideFromInspectorプロパティは無視します。これにより、mlua の型とデフォルト値がわかります。- ユーザーが値を指定した場合、動作上デフォルト以外の値が必要な場合、または
*Keyプロパティが Blackboard 変数を参照する必要がある場合にのみ、nodePropertiesエントリを含めます。.mlua のデフォルト値をそのまま使用できる省略可能なプロパティは省略します。 *Key文字列プロパティでは、propertyValueに Blackboard 変数名を設定します。名前とゲッターの使用方法から明らかな場合は、変数を推測します(MoveSpeedKey→MoveSpeed、TargetEntityKey→TargetEntity)。一致する可能性のある Blackboard 変数が複数ある場合は、ユーザーに確認します。- リテラルプロパティには、ユーザーが指定した値を使用します。値が指定されておらず、.mlua のデフォルト値に意味がある場合は、推測した値をシリアライズせず、プロパティを省略します。
OnBehaveがプロパティに対してnil、空文字列、または無効な列挙値をチェックしており、値を推測できない場合は、ツリーを書き込む前にユーザーに確認します。
nodeProperties エントリの形式:
{
"propertyKey": "<property name>",
"propertyType": { "$type": "MODNativeType", "type": "<type from bt-spec.md §4>" },
"propertyValue": <value>
}
5. ノードを組み立てる
グラフに関する制約(書き込み前に検証してください):
- RootNode は親ノードではありません。
childNodesを持たせてはいけません。startNodeIdのみを保持し、startNodeIdはNodes内のノードを正確に 1 つだけ指します。 - ツリーに複数の最上位の動作が必要な場合は、単一の
startNodeIdとして 1 つの Composite を使用するか、単一のstartNodeIdとして 1 つの Decorator を使用します。この場合、decoChildNodesで Composite、または最終的に Composite をラップする別の Decorator チェーンをラップします。複数の動作は、その Composite のchildNodesの下に配置します。 Nodes内でnodeParentId: ""を持てるノードは、RootNode.startNodeIdが参照するノードの 1 つだけです。ルート階層に Action/Composite/Decorator ノードを複数作成してはいけません。- Composite(
btNodeType: 1)は、childNodesを通じて複数の子ノードを持てる唯一のノードカテゴリです。 - Decorator(
btNodeType: 2)は、Action、Composite、または Decorator ノードを 1 つだけラップするラッパー/親ノードです。別の Decorator の子にもできるため、Decorator 同士のチェーンも有効です。子ノード 1 つを表す単一のnodeId文字列にはdecoChildNodesを使用し、childNodesは使用しません。ラップされる子ノードのnodeParentIdにも、Decorator の ID を記録する必要があります。 - 同じ Action に適用される Decorator は、必ずチェーンにしてください。兄弟ノードとして平坦化してはいけません。 各 Decorator は、下流のサブツリーを 1 つだけ所有します。2 つ以上の Decorator で同じ Action の実行を制御・変更する場合は、
Composite → ADeco → BDeco → CDeco → Actionという 1 つのチェーンを作成します。各 Decorator のdecoChildNodesは次の Decorator(最後は Action)を指します。具体的には、単一の Action につながる 1 つのチェーン内では、2 つの Decorator が同じnodeParentIdを持ってはいけません。各 Decorator の親は直前の Decorator で、最上位の Decorator の親だけが Composite になります。兄弟 Decorator がそれぞれ異なる下流サブツリーをラップする場合は、1 つの Composite の下に配置しても有効です。✅Composite → ADeco → BDeco → CDeco → Action(チェーン — チェーン内の各 Decorator の親はそれぞれ異なります)。❌Composite → [ADeco→Action, BDeco→Action, CDeco→Action](チェーン化を避けるために Action を重複させています)。❌Composite → [ADeco, BDeco, CDeco, Action](Decorator を平坦化しています。Action をラップしておらず、実質的に孤立しています)。 - Action(
btNodeType: 0)はリーフノードです。子ノードを持たせてはいけません。
ノード書き込み時の不変条件:
- 各
nodeIdはファイル内で一意です。 - ルート以外のすべてのノードの
nodeParentIdは、実在するCompositeまたはDecoratorのnodeIdを参照します。RootNodeはNodes内にノードとして表されないため、参照してはいけません。 - ノードの親がCompositeの場合、そのCompositeの
childNodesにノードIDが含まれている必要があります。 - ノードの親がDecoratorの場合、そのDecoratorの
decoChildNodesはノードのnodeIdと一致する必要があります。親と子がどちらもDecoratorの場合でも有効です。 - Compositeの
childNodesと子のnodeParentIdは双方向で整合している必要があります。 - Actionノードでは
childNodesを省略します。DecoratorノードではchildNodesを省略し、代わりにdecoChildNodesを1つだけ使用します(nodeIdを表す文字列1つ)。 probabilityは絶対に記述しないでください。 エディターは往復保存時にこのフィールドを削除し、サポート対象のComposite(SequenceNode、SelectorNode、ParallelNode)は子ごとの重みを使用しません。プロジェクト内の古い生成済みツリーには、すべてのノードに"probability": 1.0が含まれている場合があります。読み込み時にはレガシー形式として扱い、新しいノードには記述しないでください。- Decoratorノード(
btNodeType: 2)ではnodePositionを省略します。 エディターはDecoratorをラップする子ノードに対する位置を自動的に設定し、保存時にnodePositionフィールドを書き込みません。nodePositionを持つのはCompositeとActionだけです。RootNodeブロックにも、開始ノードとは別に、独自のnodePositionがあります。 - 空のコレクションフィールドは
[]としてシリアライズせず、省略します。 まだ子ノードのないCompositeではchildNodesを完全に省略し、オーバーライドのないノードではnodePropertiesを完全に省略します。空の配列はエディターのドラフトによるものなので、作成時に含めないでください。 - Decoratorの子フィールドは
decoChildNodesです(正規のフィールドで、エディターが保存時に保持します。ChildNodeIdは往復保存時に暗黙的に削除されます)。ラップする子のnodeIdを格納する単一の文字列です(配列ではありません)。レガシーファイルを読み込む際は、手作業で作成されたDecoratorにChildNodeIdが含まれている場合がありますが、同じフィールドとして扱ってください。書き込む際は、必ずdecoChildNodesを出力してください。 RootNode.startNodeIdは、nodeIdを持つAction、Composite、またはDecoratorのいずれかを参照します。そのノードだけがnodeParentId: ""を持ちます。
*Keyを接尾辞に持つStringプロパティは、Blackboard変数の名前を格納します(実行時にBlackBoard:GetXxxを介して解決されます)。Keyの付かないプロパティは、リテラル値を格納します。
6. nodePosition の形式
nodePosition は、数値の x/y を持つ JSON オブジェクトです。
"nodePosition": { "x": 0.0, "y": 0.0 }
浮動小数点数リテラルを使用してください(0 ではなく 0.0)。従来の文字列形式 "(0.000, 0.000)" が、以前に手作業で作成されたツリーに残っている場合があります。同等のものとして読み取って構いませんが、書き込む際は必ずオブジェクト形式を使用してください(BT エディターは保存時にこの形式に正規化するため、文字列形式はファイルを初めて開いたときにノイズの多い差分として再シリアライズされます)。
エディターの軸:BT エディターは数学の慣例に従ったキャンバスを使用します。+x は右、+y は上です(右上の象限が正)。そのため、親より y が 大きい 位置に配置された子は、画面上で親より 上 に表示されます。
レイアウト規則 — ツリーを下方向に配置する:深さは −y に沿って増加し(子は親の下に配置)、兄弟ノードは親の x を中心に ±x 方向へ広がります。一般的な間隔は、深さレベル間が 200 単位、兄弟ノード間が 200 単位です。
RootNode ブロックと開始ノード — 同じ位置に重ねないでください。 RootNode.nodePosition はキャンバスの基準点であり、{ "x": 0.0, "y": 0.0 } のままにします。開始ノード(startNodeId が参照するノード)は、この基準点より 1 レベル下に配置する必要があります。(0, 0) に配置すると、エディターのキャンバス上で RootNode マーカーと視覚的に重なります。RootNode の基準点を深さ 0、開始ノードを深さ 1 として扱ってください。
RootNode.nodePosition:{ "x": 0.0, "y": 0.0 }(固定の基準点 — 移動しません)- 開始ノード(深さ 1、
startNodeIdが参照):{ "x": 0.0, "y": -200.0 } - 開始ノードの子が 1 つの場合(深さ 2):
{ "x": 0.0, "y": -400.0 } - 開始ノードの子が 2 つの場合(深さ 2):
{ "x": -100.0, "y": -400.0 }および{ "x": 100.0, "y": -400.0 } - 追加の各レベル:parent.y − 200
親の y 以上の値に子を配置しないでください。上方向に描画され、画面上で親と重なります。RootNode と開始ノードの間にも同じ規則が適用されます。開始ノードは y ≤ -200(基準点より下)に配置する必要があります。
デコレーターノードには nodePosition を指定しません。 エディターがラップされた子に対する位置を自動的に設定します。すべての btNodeType: 2 ノードではこのフィールドを省略してください。このフィールドが表示されるのは、RootNode、Composite(btNodeType: 1)、Action(btNodeType: 0)のみです。
7. 作成と検証
JSON ファイルを作成し、次のチェックリストを実行します。特に、以下を確認してください。
-
EntryKeyがbehaviourtree://{uuid}であり、ContentProto.Json.idと完全に一致している。 - トップレベルの
Id、GameId、Contentが""。Usage、UseService、DynamicLoadingが0。UsePublishが1。CoreVersionがプロジェクト(Environment/config)と一致している。StudioVersionが0.1.0.0。ContentTypeがx-mod/behaviourtree。ContentProto.UseがJson。 -
RootNodeにchildNodesがなく、RootNode.startNodeIdがNodes内のちょうど 1 つのnodeIdと一致し、その開始ノードのnodeParentIdが""であり、他のノードにnodeParentId: ""がない。 - すべての
nodeParentIdが""または既存のnodeIdである。 - すべての
nodeIdの値が一意である。 - すべての Composite について、
childNodesの ID の集合が、nodeParentIdがその Composite であるノードの集合と一致している。 - すべての Action に
childNodesがない。すべての Decorator にchildNodesがなく、decoChildNodesがちょうど 1 つある(単一のnodeId文字列。ChildNodeIdは旧形式で、エディターはラウンドトリップ時に削除します)。その ID が、nodeParentIdで Decorator を参照する Action、Composite、または Decorator の子のうち、ちょうど 1 つを指している。Decorator 同士の親子チェーンも有効であり、同じdecoChildNodes↔nodeParentIdのルールで検証する必要がある。 - Decorator チェーンのルール: 複数の Decorator が同じ Action に適用される場合、それらは単一のチェーン(
Composite → ADeco → BDeco → … → Action)を形成する必要があります。各 Action からそれを囲む Composite まで上にたどり、その 1 つの経路上で見つかった Decorator のnodeParentIdがすべて一意であることを確認します(つまり、各 Decorator の親は直前の Decorator であり、チェーン内ですでに現れた別の Decoratorではありません)。同じチェーン内で 2 つの Decorator がnodeParentIdを共有するのは無効です。同じ Composite の下にある兄弟 Decorator が、それぞれ異なる下流サブツリーをラップするのは問題ありません(一意性は全体ではなく、チェーンごとに適用されます)。 - どのノードも
"probability"をシリアライズしない。(旧形式の1.0値は読み込み時に現れることがありますが、作成時には決して記述しません。) - すべての Composite と Action に、オブジェクト形式の
nodePosition{ "x": <num>, "y": <num> }があり、浮動小数点リテラルを使っている。書き込み時に旧形式の"(x.xxx, y.yyy)"文字列を使わない。Decorator ノードにはnodePositionを一切指定しません。 - 開始ノードを RootNode のアンカーに重ねないでください。
RootNode.nodePositionが{ "x": 0.0, "y": 0.0 }であり、startNodeIdが参照するノードのy ≤ -200.0(通常は{ "x": 0.0, "y": -200.0 })であることを確認します。開始ノードが Decorator(nodePositionなし)の場合は、チェーン上でその下にある最初の Composite/Action がこのオフセットを満たす必要があります。 - ノードが空の配列をシリアライズしない。子がない Composite では
childNodesを省略し、オーバーライドがないノードではnodePropertiesを省略します。"childNodes": []や"nodeProperties": []は書き込まないでください。 - すべてのカスタムノードの
definitionIdがbt-spec.mdからコピーされている(決して独自に作らない)。 - すべての
nodeProperties[].propertyKeyが、そのノードについてbt-spec.mdに記載されたプロパティと一致している。 - すべての
*KeyプロパティのpropertyValueが、適切な型のBlackboard.Variables[].Nameと一致している。 - すべての型文字列が
bt-spec.md§4 からそのままコピーされている(バージョンタグ付きで、誤記に弱い)。 - バージョンの相互確認: すべての
MOD.Core.*型文字列について、Version=X.Y.Z.Z部分文字列(Blackboard.Variables[].Type.typeおよびNodes[].nodeProperties[].propertyType.type内)が、ファイルのトップレベルにあるCoreVersionと一致している。相違があるとデシリアライズが警告なしに失敗します。これは、bt-spec.mdがプロジェクトの現在のCoreVersionより古い場合によく起こります。異なる場合は、書き込む前にステップ 0 を再実行してください。(System.*型は不変のVersion=4.0.0.0を使用し、対象外です。) - JSON を解析できる:
node -e "JSON.parse(require('node:fs').readFileSync(process.argv[1],'utf8'))" "<path>"
チェックに失敗した場合は、完了を報告する前に修正してください。
📂 このスキルで使用するファイル
scripts/build-spec.cjs— プロジェクトをスキャンし、<ProjectRoot>/.behaviourDocs/bt-spec.mdを出力する Node.js スクリプトです。ステップ 0 で実行します。<ProjectRoot>/.behaviourDocs/bt-spec.md— 生成される簡潔なカタログです。ノード名、definitionId、btNodeType、プロパティ名、型文字列の信頼できる唯一の情報源です。上記のスクリプトで書き込まれ、ステップ 1~7 で使用されます。references/skeleton-minimal.json— 最小限の有効なツリーです(空の Blackboard、子を持たない単一の Composite ルート)。references/skeleton-full.json—nodeProperties(リテラル値とKeyサフィックス)および値が設定されたBlackboardを持つ、Composite → Decorator → Action です。ツリーが単純でない場合は、構造の参考として使用してください。references/node-catalog.md—btNodeTypeの値、有効なグラフ構造、Keyサフィックスの規則、スペックビルダーによるノードの検出方法についての説明です(参考用として保持。実行時のカタログはbt-spec.mdにあります)。
🔁 編集ワークフロー(既存ファイル)
- ファイル全体を読みます。内容を確認せずに編集してはいけません。UUID と親子グラフの整合性を保つ必要があります。
- ファイルのラッパー UUID(
EntryKey/ContentProto.Json.id)は変更しないでください。外部参照が壊れます。 - ノードを追加する場合:新しい
nodeIdを生成し、Nodesに追加して、親 Composite のchildNodesを更新し、新しいノードのnodeParentIdを設定します。 - ノードを削除する場合:
Nodesから削除し、すべての Composite のchildNodesからその ID を削除します。Composite だった場合は、子ノードの親を変更するか、子ノードも削除するかを決めてください。nodeParentIdの参照先がなくならないようにしてください。 - 編集に、スペックの最終生成後にプロジェクト内で変更された可能性があるカスタムノード名、プロパティ、型が関係する場合は、先にステップ 0 を再実行してください。
- 編集のたびに、ステップ 7 の検証チェックリストを再実行してください。