VibeUE Architecture Deep Dive: Load Skills → Discover API → Execute Code
The Problem: Context Bloat and Tool Count
When I set out to build VibeUE, I had a clear goal: give AI assistants complete control over Unreal Engine through natural language. The problem is IDE’s support about 128 MCP tools and I need upwards of 1,000.
This post is a deep dive into VibeUE’s Load Skills → Discover API → Execute Code architecture - how it works, why it works, and how you can apply these patterns to your own AI-powered tools.
I got these concepts from Anthropic’s post Code Execution with MCP and Cloudflare’s Code Mode.
I improve on it with self loading skils that load content on namespaces and classes to discover. I then use discovery methods that use introspection and reflection instead of searching through code on disk.
The VibeUE Solution: Three-Stage Workflow
VibeUE solves this with a workflow that loads knowledge just-in-time:
1. Load Skills → Domain-specific workflows and gotchas
2. Discover API → Exact method signatures and parameters
3. Execute Code → Run Python in Unreal's environment
This reduced token usage and increased tool count.
Stage 1: Load Skills - Domain Knowledge On Demand
The Skills System Architecture
Instead of loading all documentation at once, VibeUE organizes knowledge into lazy-loaded skills:
Plugins/VibeUE/Content/Skills/
├── blueprints/
│ ├── skill.md # Metadata + overview
│ ├── 01-service-reference.md # BlueprintService API
│ ├── 02-workflows.md # Step-by-step patterns
│ └── 03-common-mistakes.md # Gotchas and pitfalls
├── materials/
│ ├── skill.md
│ ├── 01-service-reference.md
│ ├── 02-workflows.md
│ └── 03-node-types.md
├── screenshots/
│ ├── skill.md
│ ├── 01-service-reference.md
│ ├── 02-workflows.md
│ └── 03-attach-image.md
└── ... (9 skills total)
Skill Metadata: YAML Frontmatter
Each skill.md defines the skill with YAML frontmatter:
---
name: blueprints
display_name: Blueprint System
description: Create and modify Blueprint assets, variables, functions, components, and node graphs
vibeue_classes:
- BlueprintService
- AssetDiscoveryService
keywords:
- blueprint
- variable
- function
- compile
auto_load_keywords:
- create blueprint
- add variable
- compile blueprint
---
How Skills Load
1. System Prompt Guidance
The base instructions (vibeue.instructions.md) tell the AI when to load skills:
## Available Skills
Load skills using `manage_skills(action="load", skill_name="<name>")`:
{SKILLS}
Skills auto-load based on keywords. Manually load with the `manage_skills` tool.
In-Editor Chat: The {SKILLS} token is dynamically replaced at runtime by VibeUE’s in-editor chat with a table of all available skills:
| Skill | Description | Services |
|---|---|---|
blueprints | Create and modify Blueprint assets… | BlueprintService, AssetDiscoveryService |
materials | Create and edit materials and shaders | MaterialService, MaterialNodeService |
screenshots | Capture editor windows for AI vision | ScreenshotService |
External IDEs: When using MCP tools from VS Code, Claude Desktop, Cursor, or Windsurf, you need to manually include skill information in your system prompt or use the manage_skills(action="list") tool to discover available skills.
2. Keyword-Based Auto-Loading
When the AI detects certain keywords in user input, it automatically loads the relevant skill:
- User says: “Create a blueprint with a health variable”
- AI detects: “blueprint”, “variable”
- Skill system auto-loads:
blueprintsskill - Only the relevant domain knowledge is loaded, keeping context efficient
3. Manual Loading
External AI clients (Claude, GitHub Copilot) manually load skills:
# List available skills
manage_skills(action="list")
# Load specific skill
manage_skills(action="load", skill_name="blueprints")
# Load multiple skills (deduplicated)
manage_skills(action="load", skill_names=["blueprints", "enhanced-input"])
What Skills Contain
Skills provide three types of knowledge that discovery alone cannot provide:
1. Critical Rules
## Critical Rules
⚠️ **ALWAYS compile before adding variable nodes**
If you add a variable but don't compile first, variable nodes will fail.
```python
add_variable(path, "Health", "Float", "100.0")
compile_blueprint(path) # REQUIRED!
add_get_variable_node(...) # Now works
**2. Common Mistakes**
```markdown
## Common Mistakes
❌ WRONG: `create_blueprint("BP_Player")`
Missing required parameters
✅ CORRECT: `create_blueprint("BP_Player", "Actor", "/Game/Blueprints")`
Include parent class and path
3. Workflows
## Workflow: Create Blueprint with Variables
1. Create blueprint with parent class
2. Add variables (strings for defaults)
3. **Compile first** ← CRITICAL
4. Now you can add variable nodes
5. Save the asset
Efficiency Benefits
The skills system dramatically reduces context overhead:
- Load only relevant domain knowledge
- Multiple skills can be loaded together when needed
- Base instructions remain lightweight
- Skills scale independently as new domains are added
Stage 2: Discover API - Never Guess Method Names
Skills tell you what to do and where to discover classes and methods. Discovery tells you exactly how to do it.
The Discovery Tools
VibeUE provides 5 MCP tools for exploring the Unreal Python API:
1. discover_python_module - Explore Module Contents
Lists all classes, functions, and constants in a module:
3. discover_python_class - Explore Class Contents
Lists all functions variables in a class:
3. discover_python_function - Get Function Details
List return type and paramters of a function
4. list_python_subsystems - Find Editor Subsystems
Lists all available editor subsystems: For fallback when our skills can get the job done.
5. manage_skills - Load Domain Knowledge
Already covered in Stage 1, but this is also part of the “discovery” phase.
Why Discovery Matters: Avoiding Silent Failures
Without discovery, AI assistants guess API signatures:
# AI guesses (WRONG):
unreal.BlueprintService.create_blueprint("BP_Player")
# Error: Missing required arguments
With discovery, AI knows the signature:
# Discovery showed: create_blueprint(name, parent_class, path)
# AI generates (CORRECT):
unreal.BlueprintService.create_blueprint(
"BP_Player",
"Actor",
"/Game/Blueprints"
)
Discovery Implementation: C++ Python Bridge
Discovery is implemented in C++ using Unreal’s Python API:
// Simplified example from VibeUE
UFUNCTION(BlueprintCallable)
FString DiscoverPythonClass(const FString& ClassName)
{
PyObject* module = PyImport_ImportModule("unreal");
PyObject* cls = PyObject_GetAttrString(module, TCHAR_TO_UTF8(*ClassName));
// Iterate methods using Python C API
PyObject* methods = PyObject_Dir(cls);
// Build JSON response with signatures
return BuildMethodsJSON(methods);
}
This is exposed to MCP clients through HTTP endpoints that call these C++ functions.
Stage 3: Execute Code - Python in Unreal Context
The final stage: actually run the code.
The execute_python_code Tool
# Execute Python code in Unreal Editor's environment
execute_python_code(code="""
import unreal
# Create blueprint
path = unreal.BlueprintService.create_blueprint(
"BP_Enemy",
"Character",
"/Game/Blueprints"
)
# Add variables
unreal.BlueprintService.add_variable(path, "Health", "Float", "100.0")
unreal.BlueprintService.add_variable(path, "Damage", "Float", "25.0")
# CRITICAL: Compile before adding nodes
unreal.BlueprintService.compile_blueprint(path)
# Save
unreal.EditorAssetLibrary.save_asset(path)
print(f"Created: {path}")
""")
Execution Environment
Code runs in Unreal’s Python interpreter with full access to:
-
VibeUE Python Services (10 services, 209 methods)
unreal.BlueprintServiceunreal.MaterialServiceunreal.ScreenshotService- etc.
-
Native Unreal Python API (7000+ methods)
unreal.EditorAssetLibraryunreal.EditorLevelLibraryunreal.SystemLibrary- All Unreal Engine Python bindings
-
Editor Context
- Currently open level
- Selected actors
- Active viewport
- Plugin state
Safety Rules
The system prompt enforces strict safety rules:
## NEVER Block the Editor
❌ FORBIDDEN:
- Modal dialogs (EditorDialog)
- input() or raw_input()
- Long time.sleep() calls
- Infinite loops
- Blocking file operations
✅ SAFE:
- unreal.* API calls
- File writes (async)
- Short operations (<5 seconds)
Execution Response
The tool returns:
{
"success": true,
"stdout": "Created: /Game/Blueprints/BP_Enemy",
"stderr": "",
"execution_time": 0.234,
"file_path": "/Game/Blueprints/BP_Enemy"
}
Error Handling
When execution fails, VibeUE provides structured errors:
# Code with error
unreal.BlueprintService.add_variable("/Game/BP_NotFound", "Health", "Float")
Response:
{
"success": false,
"error_code": 2001, // BLUEPRINT_NOT_FOUND
"error_message": "Blueprint not found at path: /Game/BP_NotFound",
"suggestion": "Use AssetDiscoveryService.search_assets() to find blueprints"
}
Error codes are centralized in ErrorCodes.h:
- 1000-1099: Parameter validation
- 2000-2999: Blueprint domain
- 3000-3999: UMG domain
- 4000-4999: Asset domain
- 5000-5999: Enhanced Input
- 6000-6999: Level Actors
- 7000-7999: Materials
- 8000-8999: Data Assets/Tables
- 9000-9999: Screenshots
Putting It All Together: Real Workflow Example
Let’s watch the three-stage workflow in action:
User Request
“Create a blueprint that has health and max health variables, both starting at 100”
Stage 1: Load Skills (Auto)
AI detects keywords: “blueprint”, “variables”
# System auto-loads blueprints skill
manage_skills(action="load", skill_name="blueprints")
Receives:
- Critical rule: Must compile before adding variable nodes
- Workflow: Create → Add Variables → Compile → Save
- Common mistake: Default values must be strings
- Services needed:
BlueprintService,AssetDiscoveryService
Stage 2: Discover API
AI knows it needs BlueprintService from the skill, now discovers exact signatures:
# What methods are available?
discover_python_class("unreal.BlueprintService", method_filter="variable")
Discovers:
create_blueprint(name: str, parent_class: str, path: str) -> stradd_variable(path: str, name: str, type: str, default_value: str) -> boolcompile_blueprint(path: str) -> bool
Stage 3: Execute Code
AI generates and executes:
execute_python_code(code="""
import unreal
# Create blueprint (discovered signature)
path = unreal.BlueprintService.create_blueprint(
"BP_Character", # name
"Actor", # parent_class (from skill knowledge)
"/Game/Blueprints" # path (full path required - from skill)
)
# Add variables (default as string - from skill)
unreal.BlueprintService.add_variable(
path,
"Health",
"Float",
"100.0" # String, not float!
)
unreal.BlueprintService.add_variable(
path,
"MaxHealth",
"Float",
"100.0"
)
# COMPILE FIRST - critical rule from skill!
unreal.BlueprintService.compile_blueprint(path)
# Save
unreal.EditorAssetLibrary.save_asset(path)
print(f"Created blueprint: {path}")
""")
Success! Blueprint created with both variables.
Why This Architecture Works
1. Context Efficiency
- Load only what’s needed
- Significant reduction in baseline context
- Skills scale independently
2. Accuracy
- Never guess method signatures
- Type-safe discovery
- Structured error codes
3. Completeness
- Full Unreal Engine API access
- Dynamic discovery means zero lag when APIs change
- Skills capture tribal knowledge
4. Developer Experience
- Natural language input
- Automatic skill loading
- Clear error messages
5. Extensibility
- Add new skills without code changes
- Skills are just markdown files
- Discovery is automatic for new services
Implementation Lessons for Your Own AI Tools
If you’re building AI-powered developer tools, here are the key patterns to steal:
1. Lazy-Load Domain Knowledge
Don’t dump all docs upfront. Organize into skills:
/skills/
├── domain-1/
│ ├── skill.md # Metadata
│ ├── workflows.md # How-to guides
│ └── gotchas.md # Things discovery can't tell you
└── domain-2/
└── ...
2. Provide Runtime Discovery
Let AI query your API structure:
discover_module() # What's available?
discover_class() # What methods?
discover_function() # What parameters?
3. Structured Error Codes
Return machine-readable errors:
{
"error_code": 2001,
"category": "BLUEPRINT",
"message": "Blueprint not found",
"suggestion": "Use search_assets() to find blueprints"
}
4. Execution Sandboxing
Run user code in a controlled environment:
- Timeout limits
- Memory limits
- API whitelist/blacklist
- Capture stdout/stderr
5. System Prompt as First-Class
Your instructions are code. Version them, test them, iterate on them:
## Workflow
1. Load skill for domain knowledge
2. Discover exact API signatures
3. Execute with discovered parameters
4. Handle errors with retry logic
Performance Impact
The three-stage workflow delivers measurable improvements:
- Reduced Context: Only load skills needed for the current task
- Faster Responses: Less context to process means quicker AI responses
- Lower Costs: Fewer tokens per request reduces API costs
- Higher Accuracy: Discovery eliminates API guessing, skills prevent common mistakes
The Future: Self-Discovering Skills
The next evolution? AI-generated skills:
- User works on a custom domain
- AI notices repeated patterns
- System offers: “Should I create a skill for character stats?”
- AI generates skill.md with:
- Discovered API usage patterns
- Common mistakes from error logs
- Workflow from successful executions
Skills become a living knowledge base that grows with usage.
Code References
All of this is open source in VibeUE:
Skills System: Plugins/VibeUE/Content/Skills/
- Markdown-based skill definitions
- YAML frontmatter for metadata
- Dynamic token replacement in system prompt
Discovery Tools: Source/VibeUE/Private/Tools/PythonDiscoveryTools.cpp
- Python C API bridge
- Dynamic class/module inspection
- JSON serialization of type information
Execution Engine: Source/VibeUE/Private/Tools/PythonExecutionTool.cpp
- Python code execution in UE context
- Stdout/stderr capture
- Timeout and safety enforcement
System Prompt: Plugins/VibeUE/Content/instructions/vibeue.instructions.md
- Lightweight base instructions
- Dynamic skill table generation
- Workflow guidance
Conclusion
The Load Skills → Discover API → Execute Code workflow isn’t just about reducing tokens. It’s about building AI tools that:
- Scale to complex APIs without context exhaustion
- Maintain accuracy through runtime discovery
- Capture tribal knowledge in versioned skills
- Execute safely in production environments
If you’re building AI-powered developer tools, these patterns will save you months of iteration on “why does the AI keep getting this wrong?”
And if you’re working with Unreal Engine, try VibeUE - the skills are lazy-loaded, the API is fully discoverable, and the Python executes right in your editor.
Have questions about the architecture? Find me on Discord or Twitter/X.