Agent skill

Blueprints

by kevinpbuckley in kevinpbuckley/VibeUE

Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces.

MITAuto-check passedGame Development

Install Blueprints

skills CLI
$ npx skills add kevinpbuckley/VibeUE --skill blueprints -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install kevinpbuckley/VibeUE blueprints --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/kevinpbuckley/VibeUE.git skills-src && mkdir -p .claude/skills && cp -r skills-src/Content/Skills/blueprints .claude/skills/blueprints && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
blueprints
GitHub stars
730
Token cost
~7.7k tokens
SKILL.md length
2,515 words
Files
7 (incl. scripts)
Skills in repo
39
Repo updated
First seen
Licence
MIT

At a glance

Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces.

  • The user asks to create a Blueprint/BP
  • SKILL.md covers Critical Rules, Task Index, Sub-docs and Verification, plus 1 more section
  • Component to a Blueprint
  • Make an event dispatcher/delegate

What it does

Blueprints is an agent skill from kevinpbuckley/VibeUE. Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces. Use when the user asks to create a Blueprint/BP, add a variable or component to a Blueprint, make an event dispatcher/delegate, implement a Blueprint interface, or inspect a Blueprint's class/components. For node-level graph wiring, also load blueprint-graphs.

Its SKILL.md is about 7.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 7 other files, including scripts (for example `introspection.md` and `workflows.md`).

It sits in Game Development. The repository describes itself as: Unreal Engine Vibe Coding tool. The licence is MIT.

When your agent uses it

  • The user asks to create a Blueprint/BP
  • Component to a Blueprint
  • Make an event dispatcher/delegate
  • Implement a Blueprint interface

Example prompts

  • “/blueprints”

Requirements

  • Python 3

What it can do on your machine

Read from SKILL.md and the folder at commit dc051be. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 4 files in scripts/, which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Blueprints loads about 7.7k tokens when it runs. Until then it costs about 94 tokens; SKILL.md has 2,515 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~94
When it runs · the whole SKILL.md, loaded when a task matches
~7.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from kevinpbuckley/VibeUE at commit dc051be, republished under its MIT licence (© kevinpbuckley). 2,515 words, ~7,652 tokens.

Download SKILL.mdSave it as .claude/skills/blueprints/SKILL.md (or your agent's skills folder). This skill also uses 6 other files; get the full folder from GitHub.
name
blueprints
description
Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces. Use when the user asks to create a Blueprint/BP, add a variable or component to a Blueprint, make an event dispatcher/delegate, implement a Blueprint interface, or inspect a Blueprint's class/components. For node-level graph wiring, also load blueprint-graphs.
display_name
Blueprint System
vibeue_classes
BlueprintService, AssetDiscoveryService
unreal_classes
EditorAssetLibrary
keywords
blueprint, create blueprint, variable, component, compile, introspection, event dispatcher, dispatcher, delegate, multicast, broadcast, call delegate…
related_skills
blueprint-graphs

🧠 Brains complement: IF an unreal-engine-skills-manager tool (external MCP) exists in this session, call it with {action: "load", skill: "blueprint-fundamentals"} for UE domain knowledge on this topic — correct APIs, architecture, best practices — and treat it as the rubric for any review / "best practices" question. If no such tool is available (e.g. running under Claude Code or Codex without that MCP), skip this line entirely and proceed with this skill alone — do NOT attempt the call.

Blueprint System Skill

For node-level graph editing (adding nodes, connecting pins, wiring logic, timers, layout), load the blueprint-graphs skill.

Critical Rules

⚠️ Components added with add_component are NOT on the CDO

add_component creates a SCS node template, not an instance on the class default object. So the obvious way to configure it silently does nothing — get_components_by_class on the CDO returns an empty list and the loop body never runs:

python
# WRONG - prints [], the mesh is never assigned, and nothing errors
cdo = unreal.get_default_object(bp.generated_class())
for c in cdo.get_components_by_class(unreal.SkeletalMeshComponent):
    c.set_editor_property("skeletal_mesh_asset", mesh)

# CORRECT - go through the service, which edits the SCS template
BS.set_component_property(BP, "Windmill", "SkeletalMeshAsset", "/Game/X/SK_Windmill.SK_Windmill")
BS.set_component_property(BP, "Windmill", "AnimationMode", "AnimationBlueprint")
BS.set_component_property(BP, "Windmill", "AnimClass", "/Game/X/ABP_Windmill.ABP_Windmill_C")

Values are strings: an asset takes its object path (/Game/X/SK.SK), a class takes the _C path, an enum takes the entry name. Read back with get_component_property to confirm — it returns the resolved object, e.g. /Script/Engine.SkeletalMesh'/Game/X/SK_Windmill.SK_Windmill'. Components that come from the parent C++ class are on the CDO and can be set directly; only SCS-added ones need the service.

Level Blueprints: pass the MAP path

Every unreal.BlueprintService.* function that takes a blueprint_path also accepts a map/world path (e.g. /Game/Maps/MainMenu) and resolves it to that level's Level Blueprint — inspect and edit level scripts exactly like normal Blueprints. Explicit subobject paths (/Game/Maps/MyMap.MyMap:PersistentLevel.MyMap) work too. Compile still goes through unreal.BlueprintEditorLibrary.compile_blueprint(...) on the returned/loaded level script, and the MAP asset is what you save afterwards (unreal.EditorAssetLibrary.save_asset("/Game/Maps/MyMap")).

⚠️ Engine BlueprintTools args are {refPath} objects, NOT strings

Every UObject/UClass argument to the engine BlueprintTools toolset (blueprint, asset_type, graph, parent_class, …) is a reference object {"refPath": "<object path>"}, and these tools return the same shape. Passing a plain string fails with "<x> is not a valid object path for property '<arg>'". This rule is only for the engine BlueprintTools call_tool path — VibeUE's own unreal.BlueprintService.* Python methods still take plain string paths.

The refPath must be the full object path — /Game/Dir/Asset.Asset (the asset name repeated after the dot). A bare package path (/Game/Dir/Asset, no .Asset) is rejected. Two safe ways to get one:

python
# (a) Reuse what create/load returns — it is already a {refPath} object:
bp_ref = call_tool("create", "editor_toolset.toolsets.blueprint.BlueprintTools",
                   {"folder_path": "/Game/BP", "asset_name": "BP_X",
                    "asset_type": {"refPath": "/Script/Engine.Actor"}})["returnValue"]

# (b) Build one from a package path you already have:
def bp_ref_of(p):  # "/Game/Dir/BP_X" -> {"refPath": "/Game/Dir/BP_X.BP_X"}
    name = p.rsplit("/", 1)[-1].split(".")[0]
    return {"refPath": p if "." in p.rsplit("/", 1)[-1] else f"{p}.{name}"}

All the arguments={"blueprint": path, ...} / {"blueprint": bp, ...} examples in the sub-docs are shorthand — wrap the path with bp_ref_of(...) (or reuse the returned ref) when you actually call. On success these tools return {"returnValue": null}; an error comes back as a Parameter error.

⚠️ Creating a Blueprint — engine BlueprintTools.create

Blueprint basics now live on the engine's BlueprintTools toolset (VibeUE extends the native MCP endpoint). Create a Blueprint with call_tool, not unreal.BlueprintService.create_blueprint (that method was cut):

python
# CORRECT — folder_path + asset_name are strings; asset_type is a {refPath} class reference.
result = call_tool(
    tool_name="create",
    toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
    arguments={"folder_path": "/Game/Blueprints", "asset_name": "BP_MyActor",
               "asset_type": {"refPath": "/Script/Engine.Actor"}},
)
# -> {"returnValue": {"refPath": "/Game/Blueprints/BP_MyActor.BP_MyActor"}}
bp_ref = result["returnValue"]   # reuse this {refPath} object for later BlueprintTools calls

The folder and asset name are passed separately (folder_path + asset_name) — do not jam a full asset path into one argument. asset_type is the parent class as a {refPath}: /Script/Engine.Actor, /Script/Engine.Pawn, /Script/Engine.Character, or a Blueprint's generated class "/Game/.../BP_Base.BP_Base_C".

Blueprint Types in add_variable — engine BlueprintTools.add_variable

Adding a variable is also an engine BlueprintTools call now (unreal.BlueprintService.add_variable was cut). Use call_tool with blueprint, name, type_name (and add_object_variable / add_struct_variable for object- and struct-typed variables):

python
# CORRECT — blueprint is a {refPath} object; name/type_name are strings
call_tool(
    tool_name="add_variable",
    toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
    arguments={"blueprint": {"refPath": "/Game/BP_MyActor.BP_MyActor"}, "name": "Health", "type_name": "float"},
)

When the variable's type is a Blueprint class, use the Blueprint asset name directly in type_name. Do not add _C, and do not construct a generated class path — just use the name ("BP_Enemy", or the full "/Game/Blueprints/BP_Enemy"). Appending _C ("BP_Enemy_C") or guessing a generated class path is wrong; the type system resolves Blueprint names automatically via asset search.

Engine structs need the F prefix: color variables are "FLinearColor" / "FColor" — plain "LinearColor" / "Color" is not resolved. Unsure of a type string? Use the surviving unreal.BlueprintService.search_variable_types("Linear") to look it up.

Supported primitive type_name values (exact): bool, int, float, byte, name, string, text, Vector, Rotator, Transform, Vector2D, LinearColor. Use int (not int32) and float (not double) — add_variable rejects int32/double with "Unknown type 'int32'. Supported: …". For other engine structs (e.g. FColor, FGameplayTag) use add_struct_variable with struct_type; for object/class refs use add_object_variable with object_class as a {refPath}:

python
# Object-reference variable — object_class is a {refPath} to the class
call_tool("add_object_variable", "editor_toolset.toolsets.blueprint.BlueprintTools",
    {"blueprint": {"refPath": "/Game/BP_MyActor.BP_MyActor"}, "name": "DeathFX",
     "object_class": {"refPath": "/Script/Niagara.NiagaraSystem"}})
Struct/object/enum types from Python — add_member_variable (VibeUE delta)

From inside execute_python_code, unreal.BlueprintService.add_member_variable(bp_path, name, type_string, default="", is_array=False, container_type="") creates a member variable with full type-string support — structs, objects, enums, and containers — in one batchable Python call (no call_tool round-trip). It takes the same type strings as add_function_local_variable ("float", "FVector", "FStateTreeDelegateDispatcher", "AActor"):

python
unreal.BlueprintService.add_member_variable(bp_path, "FinishRotatingDispatcher", "FStateTreeDelegateDispatcher")
unreal.BlueprintService.add_member_variable(bp_path, "Waypoints", "FVector", "", True)  # FVector array
unreal.BlueprintEditorLibrary.compile_blueprint(unreal.EditorAssetLibrary.load_asset(bp_path))

Returns False (with the reason in the log) on a duplicate name or an unresolvable type string. Compile after adding — the variable is registered but the class is only rebuilt on compile.

Removing one variable — remove_member_variable (VibeUE delta)

unreal.BlueprintService.remove_member_variable(bp_path, name, force=False) removes exactly one member variable. The engine alternative, BlueprintEditorLibrary.remove_unused_variables, sweeps every unreferenced variable — use this when you want to delete just one. It counts Get/Set references across all graphs first: with references present and force=False it refuses (returns False, logs the referencing graphs and node counts); with force=True it removes the variable and its referencing nodes. A component name (from the Simple Construction Script) is refused with a pointer to the component API. Verifies by readback and returns True only when the variable is gone.

python
unreal.BlueprintService.remove_member_variable(bp_path, "UnusedScratch")        # refuses if referenced
unreal.BlueprintService.remove_member_variable(bp_path, "OldHealth", True)       # force: nodes go too
⚠️ Adding a function graph — engine BlueprintTools.add_function_graph

Creating a function graph moved to the engine toolset (create_function / add_function on BlueprintService were cut). Use call_tool with blueprint + graph_name:

python
call_tool(
    tool_name="add_function_graph",
    toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
    arguments={"blueprint": {"refPath": "/Game/Blueprints/BP_MyActor.BP_MyActor"}, "graph_name": "DoThing"},
)

Refining the graph afterward still uses the surviving VibeUE delta methods (add_function_parameter, add_function_local_variable, get_function_parameters, get_function_info, override_function, open_function_graph).

⚠️ Method Name Gotchas
WRONGCORRECT
get_component_info(path, name)get_component_info(type) - takes ONLY type!
⚠️ Property Name Gotchas
WRONGCORRECT
info.inputsinfo.input_parameters
var.namevar.variable_name
⚠️ Python Naming: Boolean b Prefix Is Stripped

UE Python strips the lowercase b prefix from boolean properties. Always use the name without it:

C++ namePython name
bAlreadyOverriddenalready_overridden
bIsEventStyleis_event_style
bIsNativeEventis_native_event
bEnabledenabled

Do not use b_already_overridden, b_is_event_style, etc. — these will raise AttributeError.

Exception: the string-based CDO accessors get_property / set_property take the native C++ property name, so booleans KEEP the b prefix there ("bReplicates", not "replicates"). See the next section.

⚠️ CDO Properties: get_property / set_property (replication, lifespan, etc.)

Use these to read/write Class Default Object properties like replication or initial lifespan:

python
import unreal
bp = "/Game/Blueprints/TestActor"

# READ — returns a single value: str, or None if the property wasn't found. NOT a (success, value) tuple!
value = unreal.BlueprintService.get_property(bp, "bReplicates")   # "True" / "False" (a STRING)
life  = unreal.BlueprintService.get_property(bp, "InitialLifeSpan")  # "5.000000"

# WRONG — raises ValueError: too many values to unpack
# success, value = unreal.BlueprintService.get_property(bp, "bReplicates")

# WRITE — values are strings; returns bool
unreal.BlueprintService.set_property(bp, "bReplicates", "True")

# Compile via the engine BlueprintTools toolset (compile_blueprint was cut from BlueprintService):
# call_tool(tool_name="compile_blueprint",
#           toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
#           arguments={"blueprint": {"refPath": "/Game/Blueprints/TestActor.TestActor"}})
unreal.EditorAssetLibrary.save_asset(bp)

Rules:

  • Returns str or None — UE Python collapses bool Func(..., Out&) into one return value. This applies to every get_*_info method too (get_variable_info, get_function_info, get_component_info, get_node_details): they return the info struct or None, never a tuple.
  • Property names are the native C++ names: bReplicates, InitialLifeSpan, bCanBeDamaged — the b prefix is NOT stripped here (a stripped name returns None).
  • Values read back as strings: compare value == "True", not value is True.
  • On UE 5.3+, set_property maps the deprecated GameplayEffect CDO fields InheritableGameplayEffectTags and InheritableOwnedTagsContainer to their Asset Tags and Target Tags GameplayEffect Components. Writing only the legacy fields is otherwise erased by UGameplayEffect::PreSave.
⚠️ Info Struct Fields (don't guess — these are the complete lists)

get_blueprint_info(path) → BlueprintDetailedInfo: blueprint_name, blueprint_path, parent_class, is_widget_blueprint, variables, functions, components.

StructFields
BlueprintFunctionInfo (from list_functions)function_name, return_type, parameters, is_override, is_pure — there is no function_type and no input_parameters (that's the Detailed struct)
BlueprintFunctionDetailedInfo (from get_function_info)function_name, graph_guid, input_parameters, output_parameters, local_variables, is_override, is_pure, node_count — there is no return_type; return values are entries in output_parameters (each param: parameter_name, parameter_type, is_output, is_reference, default_value)
BlueprintVariableInfovariable_name, variable_type, category, is_public, is_exposed, default_value
BlueprintVariableDetailedInfo (from get_variable_info)variable_name, variable_type, type_path, category, default_value, tooltip, is_array, is_set, is_map, is_instance_editable, is_blueprint_read_only, is_expose_on_spawn, is_expose_to_cinematics, is_private, replication_condition — booleans use the is_ prefix (instance_editable alone raises AttributeError)
BlueprintLocalVariableInfo (in BlueprintFunctionDetailedInfo.local_variables)variable_name, friendly_name, variable_type, display_type, default_value, category, guid, is_const, is_reference, is_array, is_set, is_map — local variables are NOT parameters: there is no parameter_name
BlueprintPinInfo (from get_node_pins / node.pins)pin_name, pin_type, is_input, is_connected, default_value — direction is the single is_input bool; there is no is_output (use not pin.is_input)
BlueprintNodeTypeInfo (from discover_nodes)display_name, category, spawner_key, node_class, tooltip, is_pure, is_latent, keywords — the description text is tooltip, not description
BlueprintComponentInfocomponent_name, component_class, attach_parent, is_root_component, is_scene_component, is_inherited, children
BlueprintGraphInfo (from list_graphs)graph_name, graph_kind, node_count
BlueprintNodeInfo (from get_nodes_in_graph)node_id, node_type, node_title, pos_x, pos_y, pin_names, pins
BlueprintCompileResultsuccess, num_errors, num_warnings, errors, warnings
ComponentDetailedInfo (from get_component_info)name, display_name, class_path, category, parent_class, is_scene_component, is_primitive_component, property_count, function_count — there is no description
ComponentTypeInfo (from get_available_components)name, display_name, class_path, category, base_class, is_scene_component, is_primitive_component, is_abstract
ComponentPropertyInfo (from get_all_component_properties)property_name, property_type, category, value, is_editable, is_inherited
Component API quick reference (all on unreal.BlueprintService)

These signatures are complete — no need to discover_python_class them again:

MethodNotes
get_available_components(search_filter="", max_results=50) → [ComponentTypeInfo]Discover addable component types by partial name match
get_component_info(component_type) → ComponentDetailedInfo or NoneTakes ONLY the type name — no blueprint path
list_components(bp) / get_component_hierarchy(bp) → [BlueprintComponentInfo]Both return the same flat list — use attach_parent / children / is_root_component fields to render the tree
component_exists(bp, name) → boolFast idempotency check before adding
add_component(bp, type, name, parent_name="") → boolCompiles inline. See root behavior below
remove_component(bp, name, remove_children=True) → boolRemoves children too by default
reparent_component(bp, name, new_parent) → bool
set_root_component(bp, name) → boolNew root must be a SceneComponent. Old auto-generated DefaultSceneRoot is removed; an old user-created root and any other root-level scene components become children of the new root
get_component_property(bp, comp, prop) → str or None
set_component_property(bp, comp, prop, value) → boolvalue is a STRING — see formats below
get_all_component_properties(bp, comp, include_inherited=True) → [ComponentPropertyInfo]list_component_properties is an alias
compare_components(bp_a, comp_a, bp_b, comp_b) → str or NoneDiff as text; same or different blueprints
set_collision_settings(bp, comp, collision_enabled, object_type, collision_profile, channel_responses) → boolCollision lives in BodyInstance — set_component_property cannot reach it

Root component behavior: components added with no parent_name go to root level. The first scene component added this way replaces the auto-generated DefaultSceneRoot and becomes the root; later parentless scene components become floating siblings, NOT children of the root. To build a hierarchy, pass parent_name when adding, or use reparent_component / set_root_component.

Show full SKILL.md (975 more words)Show less
⚠️ Property Value String Formats (set_component_property)

Values are strings in UE export-text syntax. Check property_type via get_all_component_properties before guessing a struct format:

Property typeFormat example
float / int32 / bool"5000.0", "25", "true"
FVector / FRotator"(X=0,Y=0,Z=50)", "(Pitch=0,Yaw=90,Roll=0)"
FColor (e.g. light LightColor)"(R=255,G=127,B=0,A=255)" — integer bytes 0–255
FLinearColor"(R=1.0,G=0.5,B=0.0,A=1.0)" — floats 0–1
Enum (e.g. IntensityUnits)"Candelas"

❌ Common mistake: LightColor is FColor, so passing LinearColor-style floats like "(R=1,G=0.5,B=0)" silently produces a nearly-black light (R=1 of 255), not orange.

⚠️ StateTree Dispatcher Variable Type

To add a StateTree delegate dispatcher variable to a Blueprint task (e.g. STT_*):

python
# Use type "FStateTreeDelegateDispatcher" — NOT "EventDispatcher".
# The engine's BlueprintTools.add_variable REJECTS this type ("Unknown type" — basic types
# only, live-verified); use the VibeUE struct-capable door instead:
unreal.BlueprintService.add_member_variable(bp_path, "FinishRotatingDispatcher", "FStateTreeDelegateDispatcher")
unreal.BlueprintEditorLibrary.compile_blueprint(unreal.EditorAssetLibrary.load_asset(bp_path))

"EventDispatcher" is a Blueprint-only concept and is not a valid type string. The correct type for StateTree delegate transitions is the USTRUCT FStateTreeDelegateDispatcher. After adding this variable, use bind_transition_to_delegate on the StateTree to link it to a transition — it matches the task by registered class name (STT_Rotate_C), not asset path.

Event Dispatchers (regular Blueprint multicast delegates)

Use the dedicated dispatcher API — NOT add_variable — to create the multicast delegates that appear in the Blueprint editor's Event Dispatchers section:

MethodWhat it does
add_event_dispatcher(bp_path, name)Adds the dispatcher (member variable + signature graph). Skeleton is recompiled inline; the dispatcher is callable immediately.
add_event_dispatcher_parameter(bp_path, name, param_name, param_type, is_array=False, container_type="")Adds a parameter to the dispatcher's signature. Subscribers receive these as inputs.
add_call_delegate_node(bp_path, graph, name, pos_x, pos_y)Spawns the "Call <Name>" broadcast node on a UK2Node_CallDelegate. Wire the broadcast into its execute pin.
remove_event_dispatcher(bp_path, name)Removes the dispatcher and its signature graph.
python
import unreal

bp = "/Game/StateTree/BP_Cube"

# 1. Create the dispatcher (no compile needed before placing nodes — skeleton is regenerated inline)
unreal.BlueprintService.add_event_dispatcher(bp, "FinishedLooking")

# 2. (Optional) Add parameters to the signature
unreal.BlueprintService.add_event_dispatcher_parameter(bp, "FinishedLooking", "Direction", "FRotator")

# 3. Spawn the Call node and wire something into its execute pin
call_id = unreal.BlueprintService.add_call_delegate_node(bp, "EventGraph", "FinishedLooking", 1400, -700)
unreal.BlueprintService.connect_nodes(bp, "EventGraph", timeline_id, "Finished", call_id, "execute")

# 4. Compile (engine BlueprintTools toolset) + save
# call_tool(tool_name="compile_blueprint",
#           toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools",
#           arguments={"blueprint": bp})
unreal.EditorAssetLibrary.save_asset(bp)

Pins on the Call node: execute (input exec), then (output exec), self (input target — defaulted to Self), plus one input pin per signature parameter.

Subscribing to it elsewhere:

  • Preferred — add_delegate_bind_on_variable(other_bp, graph, variable_name, "FinishedLooking", x, y) when the dispatcher lives on the class of an existing variable (e.g. Cube : BP_Cube_C). Mirrors add_function_call_on_variable: derives the owner class from the variable's type, creates the bind node + Get, and auto-wires Target. Pair with add_custom_event_node and wire CustomEvent.OutputDelegate → Bind.Delegate.
  • Lower-level — add_delegate_bind_node(other_bp, graph, "<owner class>", "FinishedLooking", x, y) when you have no variable to derive from. <owner class> accepts "Self", native class names (with/without U/A prefix), Blueprint asset paths (/Game/.../BP_Cube), or short BP names with/without _C (BP_Cube, BP_Cube_C). You wire the Target pin yourself.

Common mistakes:

  • ❌ add_variable(bp, "FinishedLooking", "EventDispatcher") — "EventDispatcher" is not a real type string; use add_event_dispatcher instead.
  • ❌ Treating the dispatcher like a regular variable (add_get_variable_node on it produces a delegate-getter, not a broadcast). The broadcast node is UK2Node_CallDelegate and is created only by add_call_delegate_node.
  • ❌ Skipping the compile before saving the asset. The skeleton compiles inline on dispatcher creation, but the final asset still needs the engine BlueprintTools.compile_blueprint toolset call before save_asset to ensure the generated class is up-to-date.
Blueprint Interfaces (implement / remove)

Add or remove a Blueprint Interface on a Blueprint class — the equivalent of Class Settings → Interfaces → Add in the editor.

MethodWhat it does
add_interface(bp_path, interface)Implements the interface on the Blueprint. No-op (returns True) if it is already implemented. Marks the Blueprint structurally modified and recompiles it inline.
remove_interface(bp_path, interface)Removes the interface from the Blueprint. Marks structurally modified and recompiles inline.
python
import unreal

bp = "/Game/Blueprints/BP_Player"

# Prefer the FULL interface asset path — most reliable resolution
unreal.BlueprintService.add_interface(bp, "/Game/Interfaces/BPI_Interactable")

# Short name also works IF the interface asset is already loaded in the editor
unreal.BlueprintService.add_interface(bp, "BPI_Interactable")

# Persist (both methods compile inline, but still save the asset)
unreal.EditorAssetLibrary.save_asset(bp)

# Remove it later
unreal.BlueprintService.remove_interface(bp, "BPI_Interactable")
unreal.EditorAssetLibrary.save_asset(bp)

Notes & gotchas:

  • Prefer the full asset path (e.g. /Game/Interfaces/BPI_Interactable). Short-name resolution only finds interface Blueprints that are already loaded in the editor; a full path always loads and resolves.
  • Both methods recompile the Blueprint inline (CompileBlueprint) but do not save it — call EditorAssetLibrary.save_asset(bp) afterward to persist.
  • add_interface is idempotent — calling it for an interface that is already implemented returns True without duplicating it.
  • After adding an interface, its functions appear as overridable events/functions; use override_function(bp_path, function_name) to implement them in the graph.
  • Both return bool (True on success). A False from add_interface means either the interface path could not be resolved, or it resolved to an asset that is not a Blueprint Interface (e.g. a normal Blueprint or one merely parented to UInterface) — check the log and pass a real Blueprint Interface asset path.
  • The interface must be a true Blueprint Interface (BPTYPE_Interface), created with BlueprintInterfaceFactory. add_interface validates this and returns False for non-interface classes rather than letting the compile fail.

Authoring the interface itself. A Blueprint Interface is nothing but its function graphs, so an empty one contributes nothing when implemented. Use create_function_graph() to define it — it is the counterpart to override_function(), which can only override a function that already exists:

python
BS = unreal.BlueprintService
BS.create_function_graph(bpi_path, "Interact")                                  # void -> an event on implementers
BS.create_function_graph(bpi_path, "GetDisplayName")                            # returns the graph name, "" on failure
BS.add_function_parameter(bpi_path, "GetDisplayName", "Name", "string", True)   # is_output=True -> a return value

BS.add_interface(bp_path, bpi_path)
BS.override_function(bp_path, "Interact")   # void interface fn -> event node in the EventGraph

create_function_graph() also works on a normal Blueprint (pass is_pure=True for a pure function). It returns "" and logs the reason for: an empty or non-identifier name, a name already used by any graph on the Blueprint, or a name that already exists on the parent hierarchy — that last case is override_function()'s job, and a shadowing graph would be a duplicate-function compile error.

A return-valued interface function is materialised as a graph on the implementer and shows up in list_graphs() as Interface (<InterfaceClass>).


Task Index

TaskWorkflowSample script (run via execute_python_code)
Create a Blueprint + variablesworkflows.md → Create a Blueprintscripts/create_blueprint.txt
Add components + set propertiesworkflows.md → Add componentsscripts/add_component.txt
Add an event dispatcher (delegate)workflows.md → Event dispatcherscripts/event_dispatcher.txt
Implement a Blueprint interfaceworkflows.md → Implement an interfacescripts/add_interface.txt
Inspect a Blueprint (components, parent class)introspection.md—
Node-level graph editingload the blueprint-graphs skill—

Sub-docs

  • workflows.md — step-by-step create/component/dispatcher/interface workflows with copy-paste Python.
  • introspection.md — what Blueprint introspection works/doesn't in UE 5.7 (CDO reads, parent class via asset tags, listing BPs by class, getting level actors).

Verification

After any edit: compile via the engine BlueprintTools.compile_blueprint toolset call (call_tool(tool_name="compile_blueprint", toolset_name="editor_toolset.toolsets.blueprint.BlueprintTools", arguments={"blueprint": path})) and check the result's success / num_errors, then unreal.EditorAssetLibrary.save_asset(path). Don't claim success until compile reports zero errors.

Additional gotchas

  • SubobjectDataSubsystem is an ENGINE subsystem (get_engine_subsystem); get_object_for_blueprint lives on SubobjectDataBlueprintFunctionLibrary; SCS templates are named <Name>_GEN_VARIABLE; a SubobjectDataHandle has no is_valid() — test k2_find_subobject_data_from_handle(h) is not None.
  • set_collision_enabled(NO_COLLISION) on a spawned actor's component does not survive save/reload; set_collision_profile_name("NoCollision") serialises, and can_ever_affect_navigation=False persists.
  • Engine collision profiles predate custom trace channels, so a channel with no explicit entry falls back to the ini default response (BLOCK); a scripted volume or primitive must set each custom channel's response explicitly.

© kevinpbuckley, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 6 other files (scripts) in Content/Skills/blueprints of kevinpbuckley/VibeUE.

  • SKILL.md
  • introspection.md
  • scripts/add_component.txt
  • scripts/add_interface.txt
  • scripts/create_blueprint.txt
  • scripts/event_dispatcher.txt
  • workflows.md

Open the folder on GitHubat commit dc051be

Compare with similar skills

Blueprints next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Blueprints compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Blueprints this skillkevinpbuckley/VibeUE730—~7.7kAutomated safety check: PassMIT
Image to Three.js Modelimg2threejs/img2threejs18k1 repos~8.2kAutomated safety check: PassApache-2.0
Web CloneJane-xiaoer/claude-skill-web-clone1k1 repos~2.7kAutomated safety check: PassMIT
Threejs Game Directormajidmanzarpour/threejs-game-skills2.5k—~2.2kAutomated safety check: PassMIT
Game Asset Generatorhtdt/godogen7.1k—~2.8kAutomated safety check: PassMIT
Threejs Gameplay Systemsvalkor-ai/loom1.2k1 repos~1.4kAutomated safety check: PassApache-2.0

Similar skills

  • Image to Three.js Model

    img2threejs/img2threejs

    Rebuilds the object in a reference image as a procedural, animation-ready Three.js model written entirely in code, using staged sculpting with quality checks.

    18k GitHub starsUsed in 1 repo~8.2k tokens
    Game DevelopmentAuto-check passed
  • Web Clone

    Jane-xiaoer/claude-skill-web-clone

    网站复刻 / 克隆方法论。USE WHEN 用户说 复刻网站、克隆网站、clone website、抄个站、仿站、 照着这个站做一个、reproduce site、还原某个网页效果、把这个站搬下来改成我的、 复刻某个交互/WebGL/Canvas/Three.js 效果。提供「先拿真源码 → 判路径 → 逆向拆解 → 搭工程 → 替换内容」的可移植决策树,覆盖静态站 /…

    1k GitHub starsUsed in 1 repo~2.7k tokens
    Game DevelopmentAuto-check passed
  • Threejs Game Director

    majidmanzarpour/threejs-game-skills

    Entrypoint for building, upgrading, and finishing Three.js browser games.

    2.5k GitHub stars~2.2k tokensUpdated 13 days ago
    Game DevelopmentAuto-check passed
  • Generates game art from text prompts: PNG images, GLB 3D models, rigged characters, animations and sprites, with background removal.

    7.1k GitHub stars~2.8k tokensUpdated 9 days ago
    Game DevelopmentAuto-check passed
  • Build and iterate playable Three.js game systems: starter scaffold, architecture, design briefs, core loops, level and encounter design, entities, input, camera, collision and physics, scoring…

    1.2k GitHub starsUsed in 1 repo~1.4k tokens
    Game DevelopmentAuto-check passed
  • Uloop Execute Dynamic Code

    CyberAgentGameEntertainment/NovaShader

    Execute C with Unity APIs when existing uloop tools cannot inspect or edit enough.

    1.6k GitHub starsUsed in 1 repo~1.9k tokens
    Game DevelopmentAuto-check passed

More from kevinpbuckley/VibeUE

All 39 skills in this repo
  • Unreal Animation Bone Editor

    kevinpbuckley/VibeUE

    Previews, validates and bakes bone-rotation edits on Unreal Engine AnimSequences, enforcing a coordinate space and a constraint-checked preview-validate-bake loop.

    730 GitHub stars~1.3k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Animation Montage

    kevinpbuckley/VibeUE

    Creates and edits Unreal Engine Animation Montages through AnimMontageService: sections, slots, segments, branching points, notifies and blend settings.

    730 GitHub stars~3.6k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal AnimSequence Editor

    kevinpbuckley/VibeUE

    Creates and edits AnimSequence keyframes and bone tracks in Unreal Engine through AnimSequenceService, following an inspect, preview, validate and bake workflow with correct bone-space handling.

    730 GitHub stars~3.2k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Asset Import and Export

    kevinpbuckley/VibeUE

    Imports files into Unreal Engine, exports textures, reads the Content Browser selection and checks open assets via VibeUE, plus mesh reimport material fixes.

    730 GitHub stars~6.5k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Engine Settings Control

    kevinpbuckley/VibeUE

    Changes Unreal Engine console variables, scalability levels and raw INI values through VibeUE's Python API, now that registered settings moved to the engine's own toolset.

    730 GitHub stars~1.3k tokensUpdated 3 days ago
    Auto-check passed
  • Unreal Enhanced Input Setup

    kevinpbuckley/VibeUE

    Creates and wires Unreal Engine Enhanced Input assets through VibeUE's InputService: Input Actions, Mapping Contexts, key bindings, triggers and modifiers.

    730 GitHub stars~2.4k tokensUpdated 3 days ago
    Auto-check passed

Questions about Blueprints

What does Blueprints do?

Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces. Blueprints is an agent skill from kevinpbuckley/VibeUE. Create and modify Blueprint assets, variables, functions, components, event dispatchers, and interfaces.

When should I use Blueprints?

Blueprints fits situations like: the user asks to create a Blueprint/BP; component to a Blueprint; make an event dispatcher/delegate; implement a Blueprint interface.

How do I install Blueprints in Claude Code?

Run `npx skills add kevinpbuckley/VibeUE --skill blueprints -a claude-code`. Or copy the skill folder (Content/Skills/blueprints in kevinpbuckley/VibeUE) into .claude/skills/blueprints in your project. Claude Code loads it when a task matches its description.

How do I install Blueprints in Codex?

Run `npx skills add kevinpbuckley/VibeUE --skill blueprints -a codex`. Or copy the skill folder (Content/Skills/blueprints in kevinpbuckley/VibeUE) into .agents/skills/blueprints in your project. Codex loads it when a task matches its description.

Can I use Blueprints in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kevinpbuckley/VibeUE --skill blueprints -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/blueprints, .gemini/skills/blueprints, .github/skills/blueprints and .opencode/skills/blueprints in your project.

What does Blueprints need to run?

SKILL.md names no scripts, command-line tools or credentials: Blueprints is instructions for the agent only. Our summary lists: Python 3.

Does Blueprints access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Blueprints safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Blueprints use?

Blueprints is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Blueprints use?

About 7.7k tokens (SKILL.md is roughly 31k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Blueprints?

Skills that share tags, products or a category with Blueprints: Image to Three.js Model (img2threejs/img2threejs, 18k stars), Web Clone (Jane-xiaoer/claude-skill-web-clone, 1k stars), Threejs Game Director (majidmanzarpour/threejs-game-skills, 2.5k stars) and Game Asset Generator (htdt/godogen, 7.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Blueprints?

kevinpbuckley (a GitHub user) maintains it in kevinpbuckley/VibeUE, which has 730 GitHub stars. The repository holds 39 skills in this directory. The repository was last updated on October 7, 2026.

Source: kevinpbuckley/VibeUE on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.