Msw Behaviourtree
Authors MSW `.behaviourtree` files end-to-end and maintains the project-specific authoring spec (`.behaviourDocs/bt-spec.md`). Scans every `.codeblock` whose paired `.mlua` extends `ActionNode`/`DecoratorNode`/`CompositeNode` to build a compact catalog of custom action/decorator/composite UUIDs, propertyKey names, and version-stamped MODNativeType strings. Then generates the full tree: RootNode → Nodes graph, Blackboard variables, nodeProperties wiring, and self-validates parent/child consistency. Triggers: 'create behaviourtree', 'new BT', 'add a behaviour tree', 'BT node graph', '비헤이비어 트리 만들어', '.behaviourtree 생성', 'SequenceNode SelectorNode', 'Blackboard variable', 'definitionId codeblock', 'startNodeId', 'build BT spec', 'refresh bt-spec', 'generate behaviourtree catalog', 'BT 스펙 생성', 'bt-spec.md 만들어', 'rescan BT nodes'.
- Skill ID
- msw-git/msw-ai-coding-plugins-official/msw-behaviourtree
- Publisher
- msw-git
- Repository
- msw-ai-coding-plugins-official
- Installs
- 0
- Files
- 5
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
msw-git/msw-ai-coding-plugins-official/msw-behaviourtreeInstalls these files- SKILL.md
- references/node-catalog.md
- references/skeleton-full.json
- references/skeleton-minimal.json
- scripts/build-spec.cjs
What this skill tells the agent
MSW BehaviourTree
End-to-end authoring skill for MSW .behaviourtree files. Owns both the project-specific authoring spec (<ProjectRoot>/.behaviourDocs/bt-spec.md) and the tree generation itself. Fixed graph rules and skeletons live in this skill's references/; the per-project spec is (re)built by this skill's local scripts/build-spec.cjs.
🚦 Execution order (follow this sequence)
0. Build / refresh the project spec (bt-spec.md)
The spec is the source of truth for every project-specific data point: each custom action/decorator/composite node's definitionId, btNodeType, visible propertyKey names, and the serialized Type.type strings stamped to this project's CoreVersion.
When to (re)build:
- First time working on BT in a project (no
.behaviourDocs/bt-spec.mdyet). - After any change that affects BT node surface area:
- new / renamed / removed
.codeblockwhose paired.mluaextendsActionNode/DecoratorNode/CompositeNode - added / removed / renamed
propertylines in such a.mlua Environment/configCoreVersionbumped (the serialized type strings are version-tagged).- The user says they recently added/changed a BT codeblock or a
.mluaproperty — stale UUIDs / missing properties silently produce broken trees. - The downstream validation (Step 7) flags a
definitionId,propertyKey, or version mismatch.
How to run — invoke this skill's local script:
node "scripts/build-spec.cjs" --projectRoot "<MSW project root>"If the current working directory is already the MSW project root, --projectRoot can be omitted. Requires Node.js on PATH (no other dependencies — pure stdlib fs/path).
Optional overrides (long flags, case-insensitive):
| Flag | Default | Notes |
|---|---|---|
--projectRoot | current working directory | MSW project root to scan |
--outputPath | <ProjectRoot>/.behaviourDocs/bt-spec.md | folder is created if missing |
--coreVersion | read from <ProjectRoot>/Environment/config (CoreVersion field) | required if the config is missing |
Example with overrides:
node "scripts/build-spec.cjs" --projectRoot "C:/path/to/project" --coreVersion 26.7.0.0The script throws if Environment/config is absent and --coreVersion is not passed — there is no fallback default.
What the spec contains:
- Project metadata — project root,
CoreVersion, generated time, discovered node counts. - Composite nodes — built-in names with fixed
definitionId/btNodeType, plus discovered custom composites (.mluadeclaresextends CompositeNode). - Custom action nodes —
Name,definitionId,btNodeType, visible property names. - Custom decorator nodes — same shape as action nodes.
- Type map — mlua type to serialized
MODNativeType.typeplus BlackboardObjectValueshape.
UUIDs come from real .codeblock files in the project — the spec never invents them. @HideFromInspector properties are filtered out automatically. Fixed authoring rules, file skeletons, and validation checklists live in this skill's references/ rather than in the generated spec.
After (re)building, read the freshly written <ProjectRoot>/.behaviourDocs/bt-spec.md and continue with the steps below. The compact spec intentionally lists only property names; when constructing nodeProperties, resolve each property's mlua type/default from the paired .mlua file, then use the type map in bt-spec.md §4 for propertyType.type.
Also read `references/skeleton-minimal.json` for the smallest valid tree, `references/skeleton-full.json` for a Composite+Decorator+Action+Blackboard example with all optional fields populated, `references/node-catalog.md` for fixed graph rules, and any existing .behaviourtree in the project (**/*.behaviourtree) to mirror conventions. Replace {CORE_VERSION} in the skeletons with the CoreVersion from bt-spec.md — both at the top level and inside every MOD.Core.* type string in Blackboard variables and nodeProperties.
1. Collect input from the user
Confirm via context, or ask via AskUserQuestion if anything is ambiguous:
| Item | Description | Example |
|---|---|---|
name | Display name for the tree | "PatrolAndChase" |
| Save path | .behaviourtree location (relative to project root) | RootDesk/MyDesk/PatrolAndChase.behaviourtree |
| Tree shape | Intended node graph (root composite + children) | Sequence → [Chase, MoveTo] |
| Custom nodes | Action/decorator/composite codeblocks the tree references | Chase, MoveTo, Jump |
| Blackboard variables | Variable name + type + initial value | TargetEntity: Entity, MoveSpeed: number = 10.0 |
| Node properties | For each custom node, which property maps to which Blackboard variable | Chase.TargetEntityKey = "TargetEntity" |
Custom-node existence check (mandatory): every custom action/decorator/composite name the user mentions must appear in bt-spec.md §1 / §2 / §3. If a referenced node is not in the spec, stop and ask the user — do not invent a UUID, do not assume a node exists by name, and do not skip rerunning Step 0.
2. Mint UUIDs
You need:
- One UUID for the file → goes into
EntryKeyandContentProto.Json.id(both identical, both prefixedbehaviourtree://). - One UUID for each node in
Nodes(nodeId).
node -e "console.log(require('node:crypto').randomUUID())"Mint up front, write into a scratch table, then assemble. Don't reuse the file UUID as a nodeId.
3. Resolve every definitionId
| Node category | definitionId value | btNodeType |
|---|---|---|
Built-in composite (SequenceNode, SelectorNode, ParallelNode) | Same string as nodeName | 1 |
Custom composite node (extends CompositeNode) | value from bt-spec.md §1 | 1 |
| Custom action node | value from bt-spec.md §2 | 0 |
| Custom decorator node | value from bt-spec.md §3 | 2 |
Custom-node UUIDs come from bt-spec.md (which read them from real .codeblock files) — never any other source.
4. Build the Blackboard
For each variable, copy the Type.type string and ObjectValue shape verbatim from bt-spec.md §4. The version-tagged substring (Version=<CoreVersion>) must match exactly — a typo silently breaks deserialization.
Variables is an ordered array; each entry: { Name, Type: { "$type": "MODNativeType", type: "<from spec>" }, ObjectValue: <from spec> }. The ObjectValue does not include a $type discriminator (unlike Value in .model files).
For Component / ComponentRef, ComponentId is <entity-uuid>:<ComponentName> (engine component) or <entity-uuid>:<scriptCodeblockUuid>:<ScriptComponentName> (script component). Mirror an existing serialized example in the project.
Numeric ObjectValues use float literal form (3.0, not 3).
Runtime caveat: the Blackboard lives on the entry's tree. If any script later callsAIComponent:SetRootNode(...)on that component, the entry tree and this Blackboard are discarded —BlackBoardreadsniland*Keyproperties stop resolving. Do not mix runtime root swaps with Blackboard-dependent trees.
4.5 Resolve node property values
For each custom node that needs nodeProperties:
- Confirm the
propertyKeyexists inbt-spec.md§1 / §2 / §3 for that node. - Find the paired
.mluaby searching forscript <NodeName> extends ActionNode,extends DecoratorNode, orextends CompositeNodeunder the project. If multiple files match, prefer the one whose sibling.codeblockhas the exactdefinitionIdUUID frombt-spec.md; if still ambiguous, ask the user. - Read the visible
propertydeclarations in that.mlua, ignoring@HideFromInspectorproperties. This gives the mlua type and default value.
More from msw-git
Use this skill in a project
Open any RiverX project, search the Skills panel for msw-git/msw-ai-coding-plugins-official/msw-behaviourtree, and install it in one click.
