unreal-ai · git:20261031.4a31828 · 2026-10-31 · sha256 1c60b5b9ac310602
unreal-ai git:20261031.4a31828A
Immutable. This exact content never changes and is served at /api/v1/blob/1c60b5b9ac310602.
---
name: unreal-ai
description: >-
Domain skill - author and inspect Unreal Engine AI Blackboard data through
runtime-gated Python editor APIs. Provides a typed capability preflight,
bounded readback, and one minimal, transaction-backed key-authoring action.
Behavior-tree graph, StateTree and EQS node editing are documented gaps and
are not implemented here.
license: MIT
compatibility: Unreal Engine 5.0+, Python 3.7 syntax; runtime-gated, not native-qualified
allowed-tools: Bash Read Write
metadata:
dcc-mcp:
dcc: unreal
version: "0.1.0"
layer: domain
stage: authoring
search-hint: "unreal ai blackboard behavior tree key author inspect preflight state tree eqs"
tags: "unreal, ai, blackboard, behavior-tree, key, authoring, preflight"
tools: tools.yaml
---
# Unreal AI (Blackboard authoring)
An independently usable, runtime-gated Python route to the smallest high-value
AI authoring primitive: **AI Blackboard data**. It gates the exact engine
version, Python-exposed API symbols and adapter native bridge it needs before
touching the editor, then performs one minimal, undoable action with a real
reflected readback. It reuses the existing main-thread dispatcher and calls the
`DccMcpAutomationLibrary.get_enabled_plugin_names` C++ native bridge directly
for plugin enumeration (the same bridge `plugin_preflight.py` uses, but it does
not import that helper module); it adds no new discovery, threading or service
architecture.
## Capability matrix (evidence-based)
A missing same-named directory is not proof of missing support. The matrix
below distinguishes what this adapter already covers, what is partial, and the
real gaps, based on the current tool inventory and code evidence. See
[the full matrix](../../../../docs/unreal-ai-capability-matrix.md) for file and
version evidence.
| Capability | Status | Evidence / route |
| --- | --- | --- |
| AI Blackboard data | **supported (this slice)** | `unreal-ai`: preflight, inspect, author one typed key, transaction + readback |
| Behavior-tree graph nodes | **gap** | no Python-exposed graph node authoring; needs the plugin's C++ `DccMcpAutomationLibrary` typed bridge |
| StateTree | **gap** | no tool; needs the StateTree plugin and a C++ typed bridge, version-gated |
| EQS queries | **gap** | no tool; needs a C++ typed bridge; unqualified across engine versions |
| AI Perception config | **partial** | actor/component tools exist (`unreal-actors`) but there is no AI editor facade |
| Gameplay Tags registry | **partial** | config editing only, no typed tag-registry tool |
| Blueprint / Niagara / MetaSound / UMG / PCG | **supported** | existing domain skills; not re-created here |
The reference design's own evidence note concedes that many version/native AI
operations are untested. This skill does not treat that list as maturity: every
operation is gated at call time and fails closed with a typed reason and one
`next_action` when a host does not expose the required surface. Graph-level AI
authoring is intentionally left as a documented C++-bridge gap rather than a
shallow one-to-one C++-module-to-skill mapping.
## Workflow
1. Call `ai_capability_preflight` first. It is read-only and returns `ready`,
the engine version, available/missing API symbols and engine callables,
enabled plugins, and one deterministic `next_action` (`proceed`,
`update_adapter_plugin`, `enable_engine_python_api`, or
`unsupported_engine_version`). Proceed only when `ready` is true.
2. Call `inspect_ai_blackboard` to read the asset's typed keys. A missing asset
returns `exists=false` with `readback_verified=true`; an existing wrong-class asset is
rejected, never overwritten.
3. Call `author_ai_blackboard_key` with `asset_path`, `key_name` and a `key_type`
from the schema enum. It creates an empty Blackboard only when the path is
free and `create_if_missing` is true, then adds one key inside a scoped editor
transaction. It verifies the new key through a reflected readback **before**
saving, and returns a receipt with `key_count_before`, `key_count_after`,
`mutation_state` and `recovery_errors`.
4. Re-run `inspect_ai_blackboard` to confirm the key in a fresh readback.
## Preflight, errors, and undo/cancel
- Preflight gates: Unreal Engine `>= 5.0`, the seven required Python-exposed
symbols **and** the editor methods the write path calls, the
`unreal.new_object` engine callable (callability, not just presence), plus the
adapter's native plugin-enumeration bridge. It also resolves the requested
`BlackboardKeyType_*` UCLASS through `/Script/AIModule` (via `load_class`),
because UE 5.5/5.8 do not expose these classes as `unreal` module attributes;
a host that cannot resolve them must not report `ready=true`. Pass `key_type`
to gate a specific one (defaults to `float`). A failed gate yields
`ready=false` and one machine-readable `next_action`: a missing engine-supplied
callable such as `new_object` yields `enable_engine_python_api` (name the
engine Python API to enable), while a missing symbol, method, key type or
plugin bridge yields `update_adapter_plugin`. An adapter update is never
prescribed for a core engine Python API (for example `unreal.new_object`) that
no adapter plugin can add; typed `unsupported_api` failures name that engine
API instead.
- Typed errors carry a `reason` such as `preflight_not_ready`,
`unsupported_api`, `invalid_asset_path`, `invalid_key_name`,
`unsupported_key_type`, `duplicate_key`, `wrong_asset_class`,
`asset_load_failed`, `readback_mismatch`, `readback_type_mismatch`,
`save_failed` and `limit_exceeded`.
- Undo/cancel: the mutation is wrapped in `ScopedEditorTransaction`. On any
failure the error context carries `created` and `recovery_errors`. If this
call created the asset, that asset is deleted (best effort) so a
`rolled_back` result leaves no new empty asset behind; a failed deletion is
recorded in `recovery_errors`. An existing asset is never overwritten, and
an existing-but-unloadable asset fails closed with `asset_load_failed`. The
observed key array is restored and the transaction cancelled. Cancellation
is advisory for an operation already running in the editor - it does not
interrupt the editor process.
## Limits and honest boundaries
- At most 128 keys, 96-character key names, and a 240-character `/Game` package
path; exceeding a limit rejects the operation rather than truncating.
- The key type is instantiated with `new_object(cls, asset)` so it is a
persistent subobject outered to the Blackboard asset; a transient-outer key
type would pass the in-session readback but read back empty after a
save/reopen (the outer-as-asset construction was validated in diagnostic
UE 5.5/5.8 commandlets).
- Real result readback is reflected editor state in the current session; the
tool does not itself reopen the asset from disk, so `generation_verified` and
`reopen_verified` stay false. A separate real-host save-and-reopen probe is
the authoritative disk-persistence gate.
- Real Unreal Editor / commandlet and GUI/PIE acceptance are separate gates and
are not claimed here. The bounded unit contracts live in
`tests/test_ai_blackboard_authoring.py`; a host commandlet probe is sketched
in `tests/ue_ai_blackboard_commandlet.py`.