Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
UEAGENT_TOKENNoThe plugin's Auth token (Editor Preferences > Plugins > UEAgent; default empty). When set, every request to the MCP server must send `Authorization: Bearer <token>`, and the project's `.mcp.json` entry reads the value from `${UEAGENT_TOKEN}`.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
add_ai_stimuli_sourceA

Adds a UAIPerceptionStimuliSourceComponent to an actor and registers it as a source for the supplied AISense (default Sight). Idempotent: re-run returns the existing component.

Returns: { actor_name: string, component_name: string, sense: string, registered: bool, already_existed: bool }

configure_ai_sight_radiusA

Set SightRadius and LoseSightRadius (default sight_radius times 1.5) on the sight config of the AIPerceptionComponent of an AI-possessed pawn or an AIController. The actor is looked up in the editor world, not PIE, so an unpossessed pawn is an error. Returns sight_radius, lose_sight_radius and sight_sense_count; 0 means no sight config, nothing changed.

Returns: { actor_name, sight_radius, lose_sight_radius, sight_sense_count }

create_ai_controller_blueprintA

Create a Blueprint asset parented to AAIController, compile and save it. Idempotent: if the asset already exists it is loaded and returned.

Returns: { name: string, asset_path: string, parent_class: string, generated_class: string, is_ai_controller: bool, already_existed: bool, created: bool }

get_actor_teamA

Reads the native FGenericTeamId assigned to an actor (or its Controller, for a Pawn possessed by an AAIController). Returns the engine-reserved NoTeam id (255) if neither the actor nor its Controller implements IGenericTeamAgentInterface.

Returns: { actor_name, team_id, resolved_on: "actor"|"controller"|"none", is_no_team }

get_ai_perceived_actorsA

List the actors that the AIPerceptionComponent of an AI-possessed pawn, or of an AIController, currently perceives by any sense, without changing anything. The actor is looked up in the editor world, not PIE, so an unpossessed pawn is an error. Returns count and perceived [{actor_name}]; no last-sensed time is included.

Returns: { actor_name, perceived: [{actor_name}], count }

set_actor_teamA

Assigns a native FGenericTeamId to an actor via IGenericTeamAgentInterface, falling back to the actor's Controller when the actor itself doesn't implement the interface (e.g. an ACharacter possessed by an AAIController — the only class implementing it in vanilla UE 5.8). Refreshes any UAIPerceptionComponent listeners on the resolved agent so Sight/Hearing/Touch affiliation filtering (cached at listener-update time) reflects the new team immediately.

Returns: { actor_name, team_id, applied, resolved_on: "actor"|"controller", perception_listeners_refreshed }

set_native_team_attitudeA

Installs (once per process) a custom FGenericTeamId::AttitudeSolver backed by an MCP-owned symmetric table, then records the pairwise attitude for team_a/team_b. Pairs not explicitly set fall back to the engine's own default (same team -> Friendly, else Hostile). This drives the engine's own AI Perception affiliation filtering (Sight/Hearing/Touch DetectionByAffiliation), which reads FGenericTeamId::GetAttitude directly.

Returns: { team_a, team_b, attitude, resolved_attitude, solver_installed }

check_asset_circular_dependencyA

Depth-first search of an asset's dependency graph looking for a CYCLE, returning has_circular_dependency plus the actual circular_path that closes the loop and its length -- the diagnosis for cook failures, load-order surprises and Blueprints that will not compile in isolation. Complements get_asset_dependencies (one level out) and get_asset_dependencies_recursive (the whole closure without cycle detection). WARNING: check search_limit_reached before trusting a false: the walk stops at max_depth / max_visited, and a cycle beyond those limits reads exactly like no cycle at all.

Returns: { asset_name: string, asset_path: string, has_circular_dependency: bool, nodes_visited: int, max_depth_reached: int, search_limit_reached: bool, circular_path: [string] (the cycle itself, its first package repeated at the end), cycle_length: int (packages in the cycle), root_in_cycle: bool, lead_in_path?: [string] (root ... first package of the cycle, when the root only leads into it), suggestion?: string (the edge that closes the cycle), dependency_type: string }

diff_blueprint_componentsA

Compare the COMPONENT trees of two Blueprints (or of one Blueprint against a components[] array captured earlier from get_blueprint_scs_tree) and report which components were added, removed or changed, where "changed" means the class, attach_parent, attach_socket, source or relative transform (0.01 tolerance) differ. It reuses get_blueprint_scs_tree's full enumeration, so native + own SCS + inherited components are all in scope, most-derived-wins. Use it for "did a reparent or a merge lose a component?" -- feeding a pre-change scs_tree as components_b makes it a before/after check without a second asset. removed = in A only, added = in B only. Read-only. diff_blueprints covers components AND graphs AND variables; get_blueprint_component_overrides goes deeper into ONE component's per-property provenance.

Returns: { blueprint_a, a_path, blueprint_b, b_path, side_b_source, added:[record], removed:[record], changed:[{name, class, changes:{class?:{a,b}, attach_parent?:{a,b}, attach_socket?:{a,b}, source?:{a,b}, transform?:{a,b}}}], unchanged_count, counts_a:{native,scs,inherited}, counts_b:{...}, truncated, total_differences }

diff_blueprint_graphsA

Diff ONE named graph across two Blueprints or AnimBlueprints: which nodes were added, removed and changed, with per-pin default-value and link changes and, for AnimGraph nodes, the FAnimNode config and property-binding differences. The focused, far cheaper subset of diff_blueprints for when you already know the single graph you care about (an "AnimGraph", a function, a collapsed composite). Same NodeGuid matching caveat: it compares a fork against its original meaningfully, but two independently authored Blueprints show every node as added/removed. Read-only.

Returns: { blueprint_a, blueprint_b, graph_name, resolved_graph_a, resolved_graph_b, node_count_a, node_count_b, nodes_added, nodes_removed, nodes_changed, truncated, nodes_examined_a, nodes_examined_b, total_differences }

diff_blueprintsA

Structural diff of TWO Blueprints (or AnimBlueprints): parent class, SCS components, variables, functions, and per graph a node-by-node diff of what was added, removed and changed, where a changed node reports its title, per-pin default-value and link changes and -- for AnimGraph nodes -- the internal FAnimNode config and property-binding differences. WARNING: nodes are matched by NodeGuid, which duplicating or forking an asset PRESERVES: this is built to compare a fork against its original, and two independently authored Blueprints will show every single node as added/removed, which is noise, not a finding. Read-only. Siblings: diff_blueprint_graphs for ONE named graph, diff_blueprint_components for components only, get_blueprint_component_overrides for per-property provenance, compare_objects for two LIVE UObjects instead of authored structure. Watch graphs_not_examined[] -- when the node budget runs out the remaining graphs are listed there instead of being reported as identical.

Returns: { blueprint_a, blueprint_b, a_path, b_path, a_class, b_class, parent_class:{a,b,changed}, components:{added,removed,changed}, variables:{added,removed,changed}, functions:{added,removed,common}, graphs:[{graph_name, nodes_added, nodes_removed, nodes_changed, node_count_a, node_count_b, nodes_examined_a, nodes_examined_b, truncated}], graphs_identical:[string], graphs_not_examined:[{graph_name, reason}], graphs_only_in_a, graphs_only_in_b, truncated, max_nodes, max_nodes_per_graph, nodes_examined, total_differences }

diff_object_snapshotsA

Compare two snapshots taken by snapshot_object and report which properties were added, removed or CHANGED, at the object level and per component, with both values side by side. The second half of the before/after measurement: capture a baseline, run the action, capture again, and this tells you what actually moved -- instead of trusting the acting call's own success flag. Also the way to diff editor-vs-PIE and, in co-op, SERVER-vs-CLIENT state for the same actor, which is the only proof that a value really replicated. Sides can be given as stored handles, as inline snapshot objects (from snapshot_object(return_snapshot=true)), or as paths to persisted snapshot files; a_origin/b_origin report which route each side came from. compare_objects is the same idea for two LIVE objects at one instant.

Returns: { handle_a, handle_b, a_origin, b_origin, a_object_path, b_object_path, a_class, b_class, a_world, b_world, properties:{added,removed,changed}, components:{added,removed,changed:[{component, properties:{added,removed,changed}}]}, total_differences }

find_blueprint_assets_by_classA

Search a content path for every Blueprint ASSET whose generated class derives from a target UClass, returning asset name, asset path, generated class and the deepest NATIVE parent -- "give me every Blueprint that is a Pawn / a Widget / an ActorComponent" without hand-scanning folders. Use get_blueprint_children when the base is itself a Blueprint rather than a C++ class, list_derived_classes for classes instead of assets, and get_assets_by_tag when you want a registry tag rather than an inheritance test. WARNING: it LOADS every Blueprint under package_path to read its GeneratedClass, so scope the path narrowly on a big project rather than sweeping all of /Game.

Returns: { class_name, target_class, package_path, total, assets:[{ asset_name, asset_path, generated_class, native_parent }] }

find_erroring_blueprintsA

Scan a content path for Blueprints and AnimBlueprints sitting in a compile ERROR state and report each one with its status, error/warning counts and its FIRST error message -- the search for the culprit when PIE refuses to start because of an asset nobody was working on. It reads the loaded compile Status and recompiles the erroring ones with a results log to extract that message. WARNING: loading every Blueprint under a broad path is heavy enough to stall the editor on thousands of assets: scope path narrowly, and reach for only_loaded=true first -- the Blueprint that aborts PIE is usually still in memory, so that fast in-memory pass normally finds it without a single disk load. Complements validate_assets_in_path and audit_blueprint_health by listing EVERY erroring Blueprint with its first error in one call. WARNING: the scope parameter is named path, NOT search_path: pass the wrong name and it is silently ignored, the default /Game applies, and the tool sweeps the whole project while the answer looks scoped to your folder.

Returns: { path, scanned, inspected, only_loaded, erroring_count, warning_count, results_truncated, blueprints:[{ asset_path, name, class, status, num_errors, num_warnings, first_error }] }

get_asset_dependenciesA

List every package an asset DEPENDS ON (its outgoing edges), each with its class and loaded state -- "what does this asset drag in with it?", the input to a migration or import budget. Direction matters: this is what the asset NEEDS; get_asset_dependents / get_asset_referencers answer who needs IT. Use get_asset_dependencies_recursive for the transitive closure and check_asset_circular_dependency to detect cycles. WARNING: these are PACKAGE-level edges from the Asset Registry: they cannot tell you WHICH node or property creates the edge (that is find_blueprint_node_references), and a name built at runtime or resolved through a DataRegistry produces no edge at all.

Returns: { asset_name: string, asset_path: string, dependencies: [object], dependencies_count: int, total_dependencies: int, max_results: int, results_truncated: bool, exclude_engine: bool, dependency_type: string }

get_asset_dependentsA

List every package that REFERENCES an asset (its incoming edges), each with its class and loaded state -- "who breaks if I delete or move this?", addressed by asset NAME. Direction matters: this is who needs IT; get_asset_dependencies is what it needs. Nearly the same query as get_asset_referencers -- prefer THAT one when the name could be ambiguous (it refuses to guess and echoes resolved_package, while this one silently takes the first /Game match), and prefer this one when you want the hard/soft split via dependency_type. Package-level edges only: use find_blueprint_node_references to find call sites inside graphs.

Returns: { asset_name: string, asset_path: string, dependents: [object], dependents_count: int, total_dependents: int, max_results: int, results_truncated: bool, exclude_engine: bool, dependency_type: string }

get_asset_referencersA

List every asset that REFERENCES a target asset -- "who breaks if I delete, move or rename this?" -- wrapping AssetRegistry::GetReferencers over the Package category and returning each referencing package with its primary asset's name, path and class. It accepts an object path, a package path or a bare name, echoes resolved_package so you can confirm it queried the package you meant, and REFUSES an ambiguous bare name with the candidate list instead of picking one. Hard references only by default (the "what keeps this loaded" audit); set include_soft_references=true to include TSoftObjectPtr / FSoftObjectPath edges. Its mirror is get_asset_dependencies (what this asset needs); get_asset_dependents answers the same direction as this one from a bare asset name, and find_blueprint_node_references finds call sites INSIDE graphs, which package-level references cannot see.

Returns: { asset_path, resolved_package, include_soft_references, total, returned, results_truncated, referencers:[{ package_name, asset_name?, asset_path?, asset_class? }] }

get_blueprint_childrenA

List every Blueprint asset that inherits from a given Blueprint -- the "what breaks if I change this base class?" blast-radius query, and the inverse of get_blueprint_parent. Use find_blueprint_assets_by_class when the base is a NATIVE C++ class rather than a Blueprint, get_class_hierarchy to walk upwards instead, and get_asset_referencers for references that are not inheritance at all.

Returns: { blueprint_name: string, blueprint_path: string, children: [object], children_count: int, max_results: int, results_truncated: bool, parent_blueprint_valid: bool, ambiguous_matches?: [string] }

get_blueprint_component_overridesA

Per-property PROVENANCE on a Blueprint's component templates: which values this Blueprint actually OVERRODE and which it merely inherits. Over the same components as get_blueprint_scs_tree (native CDO + own SCS + inherited chain) it resolves the effective template down the SCS -> child ICH override -> ancestor SCS -> native CDO cascade, never minting an ICH override, and compares each editable property against a baseline -- the archetype by default, or the same-named template in other_blueprint for the "fork vs original" question -- with the ENGINE's equality (FProperty::Identical, PPF_DeepComparison) instead of exported text. Each result is CLASSIFIED (identical | real_override | text_localization_metadata_only | object_outer_only | export_text_only | type_mismatch | no_baseline), so FText localization and object-outer noise stop masquerading as edits. WARNING: component templates can go STALE in memory (values can flip just from an editor restart): pass verify_on_disk to cross-check the raw .uasset bytes -- for anything not string-ish it answers found:null / applicable:false, never a misleading false. Read-only. list_instance_overrides asks the same question about a PLACED ACTOR.

Returns: { blueprint_name, blueprint_path, other_blueprint?, other_blueprint_path?, baseline_mode, components:[{component, resolved, template_name, template_path, scs_variable_name, component_key_guid, matched_by_scs_node, component_class, source, declaring_class, resolved_from_class, authored_here, baseline_source, baseline_path, baseline_class, component_class_mismatch, properties:[{component, property, property_display, value, baseline_value, inherited_value, inherited_value_available, authored_here, declaring_class, resolved_from_class, template_source, baseline_source, kind, differs, identical_deep, export_text_equal, export_text_value, export_text_baseline, note, on_disk?}], properties_reported, properties_examined, properties_truncated}], components_examined, components_truncated, properties_examined, override_count, noise_count, identical_count, no_baseline_count, on_disk:{found,not_found,not_applicable}, templates_may_be_stale, success }

get_blueprint_components_listA

List the components a Blueprint declares in its OWN Simple Construction Script, each with class, root flag, scene/primitive flags, mobility, physics and collision state, and static-mesh path + material count when it has one. WARNING: it shows ONLY this Blueprint's own SCS: components inherited from a parent Blueprint and native components from the C++ CDO are INVISIBLE here, so a short list is not proof the component is missing -- get_blueprint_scs_tree returns native + own SCS + inherited, source-classified, and is the right call whenever the answer matters. Use get_actor_components for a live actor instance instead of an asset.

Returns: { blueprint_name: string, blueprint_path: string, components: [object], components_count: int, max_results: int, results_truncated: bool, has_simple_construction_script: bool, blueprint_valid: bool, ambiguous_matches?: [string] }

get_blueprint_exec_pathA

Report which exec nodes and BRANCHES actually RAN inside a Blueprint at runtime -- which Branch went true, which FunctionResult fired -- read from the editor's Blueprint-debugger trace stack. Unlike trace_blueprint_execution and profile_blueprint_execution, which are STATIC and list every node that exists, this reflects real execution, so it answers "did that path run at all?" when a graph fails silently. WARNING: two-phase by construction: the VM only records the trace for the object currently being DEBUGGED, so call it ONCE with object_path to arm recording (SetObjectBeingDebugged), then drive the PIE scenario, then call it AGAIN to read the recorded path -- a single call returns nothing and that is not a bug. Requires a running PIE session with Blueprint debugging; world (including 'server' / 'client' / 'pie:N') selects which instance gets armed, and the response stamps which world it was.

Returns: { blueprint_name, blueprint_path, debug_object_set, object_path, trace_stack_size, filtered_count, path:[{index, node_id, node_class, node_title, graph, function, context, is_branch, is_function_result, observation_time}], note, world_selector, world_name, world_package, world_type, net_mode, pie_instance (the world of the ARMED debug object; nulls when none was armed) }

get_blueprint_functions_listA

List every graph a Blueprint AUTHORED -- function graphs, MACROS, interface implementation graphs, event graphs and ubergraph pages -- each with its node count and a REAL is_override (resolved against the parent class chain AND every implemented interface, reporting the declaring class) and is_pure (read from the graph's UK2Node_FunctionEntry FUNC_BlueprintPure flag, not guessed). The map to read before get_graph_nodes, which needs an exact graph name. WARNING: ubergraph_pages is the authored EventGraph you actually see in the editor; event_graphs are the TRANSIENT compiled graphs and come back EMPTY on a Blueprint that has not compiled this session -- an empty event_graphs is not an absence of events. Use get_class_functions for the compiled class surface (including inherited and native functions) instead of the authored graphs, and get_function_info for one function's signature.

Returns: { blueprint_name: string, blueprint_path: string, functions: [{name, type, nodes_count, is_pure?, is_override?, override_declaring_class?, interface_class?}], functions_count: int, function_graphs_count: int, event_graphs_count: int, macro_graphs_count: int, interface_graphs_count: int, ubergraph_pages_count: int, override_count: int, filter_type: string, max_results: int, results_truncated: bool, blueprint_valid: bool, ambiguous_matches?: [string] }

get_blueprint_parentA

Read which class a Blueprint ASSET inherits from: parent class name and path, whether that parent is native C++ or another Blueprint, and the Blueprint's own type (Normal / Interface / MacroLibrary / FunctionLibrary / LevelScript / Const). The first question to ask about an unfamiliar Blueprint, and the way to tell whether a library class sneaked into the parent chain. It returns ONE level -- get_class_hierarchy walks the whole ancestor chain of the compiled class, get_blueprint_children lists descendants, and verify_reparent_success checks the chain against an expectation after a reparent. WARNING: an ambiguous bare name still resolves to the FIRST match and only lists the rest in ambiguous_matches (the other match is often a dated backup copy that backup_asset wrote under /Game/MCP_Backups), so run resolve_asset_by_name first or pass the full path.

Returns: { blueprint_name: string, blueprint_path: string, blueprint_valid: bool, parent_class: string, parent_class_path: string, has_parent: bool, parent_is_native: bool, blueprint_type: string, ambiguous_matches?: [string] }

get_blueprint_scs_treeA

Enumerate the COMPLETE component tree of a Blueprint asset -- native components from the C++ CDO, its own SCS nodes, and everything inherited down the ancestor chain -- each classified by source with its class, attach parent/socket and transform, most-derived-wins. The component listing to use by default: get_blueprint_components_list sees ONLY the Blueprint's own SCS and silently omits native and inherited ones. component_class filters by class OR ANY SUBCLASS across all three sources, which Actor::GetComponentsByClass cannot do (it only ever sees a constructed instance's OwnedComponents, never SCS templates on a Blueprint nobody instantiated). WARNING: before concluding a component does not exist, read omitted_total, NOT results_truncated: null templates and name-shadowed ancestor entries are dropped without setting it, and omitted_duplicate_names[]/omitted_null_templates[] name what disappeared (counted before the component_class filter). scs_cdo_desync / generated_property_exists flag an SCS that disagrees with the compiled class -- the fingerprint of a half-reverted asset. See diff_blueprint_components to compare two trees, get_actor_components for a live instance.

Returns: { blueprint_name: string, blueprint_path: string, blueprint_valid: bool, parent_class: string, parent_class_path: string, components: [object], components_count: int, counts: object, has_simple_construction_script: bool, results_truncated: bool, max_results: int, component_class_filter: string|null, component_class_resolved: bool, desync_count: int, blueprint_status: string, generated_class_available: bool, omitted_duplicate_names: [{name, source, owner_class, shadowed_by?}], omitted_duplicate_count: int, omitted_null_templates: [{name, source, owner_class}], omitted_null_template_count: int, omitted_total: int } -- each component record also carries generated_property_exists (bool|null) and scs_cdo_desync (bool|null): the compiler mints one FObjectProperty per SCS node with the SAME FName as the node (SCS_Node.h, KismetCompiler.cpp), so a MISSING property means the SCS and the compiled class disagree -- the fingerprint of an asset left half-reverted. This tool emits Node->GetVariableName() VERBATIM; it does NOT normalize a trailing digit.

get_blueprint_variables_listA

List the variables a Blueprint AUTHORED itself (UBlueprint::NewVariables) with name, pin category, category, tooltip and the flags that matter for co-op and UI work: is_public (BlueprintVisible), is_editable, is_blueprint_read_only, is_replicated (CPF_Net) and is_expose_on_spawn. The quick "what state does this Blueprint own, and is it replicated?" listing. WARNING: own variables only: inherited variables, native C++ UPROPERTYs and component-backed variables are NOT here -- use get_class_properties on the generated class (..._C) for the full property surface, or get_blueprint_variable_detailed_info for one variable's full descriptor and default value.

Returns: { blueprint_name: string, blueprint_path: string, variables: [object], variables_count: int, max_results: int, results_truncated: bool, blueprint_valid: bool, ambiguous_matches?: [string] }

snapshot_objectA

Capture the properties and components of one object into a named in-memory snapshot (read-only) for a later diff_object_snapshots: before vs after an action, editor vs PIE, or "server" vs "client" via world. persist=true also writes Saved/MCPAudits/snapshots/.json to survive a restart. compare_objects diffs two live objects instead.

Returns: { handle, object_path, resolved_path, class, world (the coarse "pie"/"editor" family label the snapshot itself carries), world_selector (what was asked for), property_count, component_count, component_template_count, persisted, snapshot_path?, persist_error?, snapshot?, world_name, world_package, world_type, net_mode, pie_instance }

verify_reparent_successA

Check, after a reparent_blueprint, that the Blueprint really ended up where you wanted: it confirms the parent class against an expectation, reports the compile status, and -- when you feed it counts captured BEFOREHAND -- verifies no components or variables were lost, listing every failed invariant in regressions[]. This is the oracle for a reparent, because reparent_blueprint's own return value says nothing about whether the class survived it. WARNING: read-only by default, which means it reports the CACHED Blueprint->Status: pass force_compile=true to recompile and get the real status plus the compiler messages (compile_messages[] is empty without it, and compile_ran tells you which mode you got). Component count comes from the compiled CDO (native + SCS + inherited). Omit the expected_* counts to skip those invariants; get_blueprint_scs_tree or get_blueprint_variables_list before the reparent is where they come from.

Returns: { blueprint_name, blueprint_path, parent_class, expected_parent_class, parent_match, compile_status, compile_match, compile_ran, compile_messages:[{severity,message}], compile_num_errors, compile_num_warnings, component_count, expected_component_count, components_match, variable_count, expected_variable_count, variables_match, regressions:[string], success }

add_anim_bone_trackA

Add the animation track of one skeleton bone to a UAnimSequence through its data controller, filled with num_keys identity keys (zero translation, identity rotation, unit scale), as one undo step, then save the package. An existing track stays but its keys are replaced (idempotent). A bone_name the sequence's skeleton does not have is an error and nothing is written; an omitted bone_name targets the root bone. A missing sequence or skeleton is an error and a failed save makes success false, with saved=false and save_error. Real poses: set_anim_bone_track_keys; inverse: remove_anim_bone_track.

Returns: { anim_sequence_path, bone_name, num_bone_tracks, num_keys, success, saved, save_error, message }

add_anim_composite_segmentA

Append an FAnimSegment referencing a real UAnimSequence to a UAnimComposite's AnimationTrack, then recompute its length. A failed save makes success false, with saved=false and save_error.

Returns: { composite_path, animation_path, num_segments, composite_length, segments, success, saved, save_error }

add_anim_conduitA

Add a conduit node named conduit_name to an existing state machine of an Animation Blueprint (a missing blueprint or machine is an error; create the machine with add_anim_state_machine), then mark the blueprint structurally modified and save it without compiling. Idempotent by name: an existing conduit is returned unchanged (already_existed true). The conduit is placed unconnected: link it to states with add_anim_transition; remove_anim_conduit undoes it. Refused while PIE runs unless force=true; a failed save is an error, the change kept in memory.

Returns: { anim_blueprint_path: string, machine_name: string, conduit_name: string, node_class: string, conduit_created: bool, already_existed: bool, saved: bool, conduit_count: int, save_error?: string }

add_anim_curve_nameA

Register a curve name as curve metadata on a USkeleton (USkeleton::AddCurveMetaData) in an undo transaction, then save the skeleton package. Idempotent: a name already registered is a success with added=false, already_existed=true and saved=false, and the skeleton is neither modified nor saved. It adds no keys -- to put a keyed float curve on a UAnimSequence use add_anim_float_curve; remove_anim_curve_name is the inverse. An unknown skeleton is an error and a failed save makes success false, with saved=false and save_error.

Returns: { skeleton_path, curve_name, present, added, already_existed, curve_count, saved, save_error, message }

add_anim_float_curveA

Add a float curve (Editable flag) to a UAnimSequence through its data controller and set its keys from [time, value] pairs as linear keys with auto tangents, in one undo step, then save the package. An existing float curve of that name is kept and its keys are replaced (idempotent); one that already holds exactly those keys is a success with changed=false and saved=false, and nothing is written or saved. curve_found confirms the curve and num_keys counts the keys sent. A missing sequence is an error and a failed save makes success false, with saved=false and save_error. Rekey: set_anim_curve_keys; transform curves: add_anim_transform_curve; a skeleton-only name: add_anim_curve_name; read back: get_anim_curve_data.

Returns: { anim_sequence_path, curve_name, num_float_curves, num_keys, curve_found, changed, success, saved, save_error, message }

add_anim_graph_nodeA

Place a UAnimGraphNode_* (by class name) into an AnimGraph or a state's inner graph. Saves the ABP but does NOT recompile it -- run compile_anim_blueprint after your edits for runtime effect.

Returns: { node_id, node_class, graph_name, pins[], saved } (NodeToJson of the created node)

add_anim_notifyA

Add an instance of a UAnimNotify class at a time on a UAnimSequence notify track (created when missing) and save the sequence; each call adds another event, and an unknown class is an error. Returns time and success. For montages use add_montage_notify; for durations add_anim_notify_state. A failed save makes success false, with saved=false and save_error.

Returns: { animation_path, notify_name, time, success, saved, save_error, message }

add_anim_notify_nameA

Register a notify name in the AnimationNotifies list of a USkeleton inside an undo transaction and save the skeleton package; returns present, notify_count and saved. A name already registered is a success with added=false, already_existed=true and saved=false, and the skeleton is neither modified nor saved. Without skeleton_path it edits /Engine/EngineMeshes/SkeletalCube_Skeleton. A failed save makes success false, with saved=false and save_error.

Returns: { skeleton_path, notify_name, present, added, already_existed, notify_count, saved, save_error, message }

add_anim_notify_stateA

Add an instance of a UAnimNotifyState class with a start time and duration to a UAnimSequence notify track (created when missing) and save the sequence; each call adds another event, and unknown classes are refused. Returns start_time, duration and success. For instant notifies use add_anim_notify. A failed save makes success false, with saved=false and save_error.

Returns: { animation_path, notify_state_name, start_time, duration, success, saved, save_error, message }

add_anim_slot_groupA

Add an animation slot group (the groups montage slots belong to) to a USkeleton asset and save it. Idempotent: an existing group returns added false and changes nothing, but the skeleton is still saved; a failed save returns success false. Returns added and slot_group_count.

Returns: { asset_path: string, group_name: string, added: bool, slot_group_count: int, saved: bool }

add_anim_stateA

Add a state node to a state machine inside an Animation Blueprint.

Returns: { anim_blueprint_path: string, machine_name: string, state_name: string, node_class: string, state_created: bool, already_existed: bool, saved: bool, state_count: int, save_error?: string }

add_anim_state_machineA

Add a state machine node named machine_name to the top-level AnimGraph of an Animation Blueprint, then mark the blueprint structurally modified and save it without compiling (compile_anim_blueprint gives runtime effect). Idempotent by name: an existing machine is returned unchanged (already_existed true). The node starts with only its entry and is not connected to the Output Pose: wire it with connect_anim_graph_pins, fill it with add_anim_state, add_anim_conduit and add_anim_transition, or build it in one call with build_animation_state_machine. Refused while PIE runs unless force=true; a failed save is an error, the change kept in memory.

Returns: { anim_blueprint_path: string, machine_name: string, node_class: string, state_machine_graph: string, state_machine_created: bool, already_existed: bool, saved: bool, state_machine_count: int, save_error?: string }

add_anim_sync_markerA

Append an authored sync marker (name and time, on marker track 0) to a UAnimSequence in an undo transaction and save it; duplicates are not checked, nor is the time checked against the sequence length. Returns num_sync_markers. Remove with remove_anim_sync_marker. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, marker_name, time, num_sync_markers, success, saved, save_error, message }

add_anim_transform_curveA

Add a transform curve (RCT_Transform) to a UAnimSequence via the data controller. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, curve_name, num_transform_curves, num_keys, keys_set, success, saved, save_error }

add_anim_transitionB

Create a source->target transition in an anim state machine.

Returns: { anim_blueprint_path: string, machine_name: string, source_state: string, target_state: string, transition_created: bool, already_existed: bool, crossfade_duration: number, blend_mode: string, bidirectional: bool, priority_order: int, transition_count: int, saved: bool, save_error?: string }

add_animation_asset_to_pose_search_databaseA

Append an animation asset to a UPoseSearchDatabase as an enabled entry over its full range, then save the database; an asset already in it is left alone (already_existed=true). The asset type is not checked, and the search index is not rebuilt: run build_pose_search_database_index afterwards.

Returns: { database_path, animation_asset_path, animation_asset_count, added, already_existed, saved, message }

add_blendspace_sampleA

Add a blend sample (animation + blend position) to a BlendSpace. A failed save makes success false, with saved=false and save_error.

Returns: { blendspace_path, sample_index, num_samples, success, saved, save_error, message }

add_boneA

Add a bone named bone_name to the reference skeleton of a USkeleton asset under parent_name (omitted or empty: an extra root bone), with local_transform relative to the parent (a zero or missing scale becomes 1), then save the skeleton. Idempotent by name: an existing bone is returned (added false, already_existed true) without checking its parent or saving. An unknown parent is an error, and so is a failed save. Only the skeleton changes: skeletal meshes using it get no new bone, and there is no undo entry. No commit_bone_changes is needed; set_bone_parent and set_bone_transform edit bones, add_virtual_bone adds virtual ones.

Returns: { asset_path, bone_name, bone_index, parent_index, bone_count, added, already_existed, saved, op: "add_bone" }

add_ik_goalA

Add an IK goal to an IK Rig, associated with a bone, through the IK Rig controller (one undo transaction), then save the asset. If bone_name is omitted, a leaf bone of the rig's skeletal mesh is picked automatically. Idempotent: a goal of that name on the same bone is not re-created but returned with already_exists=true, saved=false and a note, and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, goal_name: string, bone_name: string, goal_count: int, saved: bool, already_exists?: bool, save_error?: string, note?: string }

add_ik_retarget_chainA

Add a retarget bone chain from start_bone to end_bone, optionally tied to an IK goal, to an IK Rig asset and save it. Both bones must exist in the skeleton of the rig; the chain name is made unique, so read chain_name back. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, chain_name: string, start_bone: string, end_bone: string, goal_name: string, chain_count: int, saved: bool, save_error?: string }

add_ik_solverA

Add an IK solver to the bottom of an IK Rig's solver stack. Solver type is one of "FullBodyIK", "Limb", "Pole", "BodyMover", "SetTransform" or "StretchLimb" (default "FullBodyIK"). Unknown types are rejected with an honest error. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, solver_index: int, solver_type: string, solver_struct: string, solver_count: int, saved: bool, save_error?: string }

add_montage_notifyA

Append a name-only notify event (no UAnimNotify class) to a UAnimMontage at an absolute trigger time on notify track 0 and save the montage; every call appends another event. Returns trigger_time, notify_count and the notifies name list. Remove with remove_montage_notify. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, notify_name, trigger_time, notify_count, notifies, added, saved, save_error, message }

add_montage_sectionA

Add a composite section to a UAnimMontage at an absolute start time, or move the existing section of that name there; it does not link sections (use link_montage_sections). Saves the montage in an undo transaction and returns start_time, section_count, sections, already_existed and added (true only for a new section). A section of that name already at that start time is a success with changed=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, section_name, start_time, section_count, sections, already_existed, added, changed, saved, save_error, message }

add_montage_segmentA

Append an animation segment referencing a real UAnimSequence to a montage slot. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, anim_sequence_path, slot_name, segment_count, montage_length, play_rate, loop_count, success, saved, save_error }

add_montage_slotA

Add an empty slot animation track with the given slot name to a UAnimMontage in an undo transaction and save it; an existing slot of that name is a success with added=false, already_existed=true and saved=false, and the montage is neither modified nor saved. Returns slot_count, the slots list and present. Fill it with add_montage_segment; inverse: remove_montage_slot. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, slot_name, slot_count, slots, present, already_existed, added, saved, save_error, message }

add_motion_warping_componentA

Attach a UMotionWarpingComponent to an actor in the editor world. Idempotent: if the actor already has one, returns the existing instance with already_existed:true instead of creating a duplicate. The component is NewObject(Actor, FName("MotionWarping")) followed by RegisterComponent() so it shows up in GetComponents() immediately. The owning world's level is marked dirty so the editor persists the change on save; no explicit SavePackage call (avoids the noise of saving a transient actor out of an editor world).

Returns: { actor_path: string, component_path: string, already_existed: bool }

add_notify_trackA

Add a named notify TRACK to a UAnimSequence (the track itself, not events on it) in an undo transaction and save it. A track of that name already there is a success with already_existed=true and nothing saved; a failed save makes success false, with saved=false and save_error.

Returns: { animation_path, track_name, track_names, track_count, already_existed, saved, save_error, message }

add_pose_search_channel_to_schemaA

Add a feature channel of channel_type to a UPoseSearchSchema asset or, when a channel of that class is already there, overwrite its Weight instead (already_existed=true); then finalize via PostEditChange and save. Returns schema_cardinality and channel_count; success stays true if the save fails: read saved.

Returns: { schema_path, channel_type, channel_class, weight, schema_cardinality, channel_count, added, already_existed, weight_updated, saved, message }

add_pose_search_roled_skeletonA

Append a roled FPoseSearchRoledSkeleton (Skeleton + optional MirrorDataTable under a Role) to a UPoseSearchSchema for multi-character search. Idempotent on role: if an entry already exists under that role it no-ops (added=false, already_existed=true) instead of pushing a duplicate -- use set_pose_search_schema_skeleton if you actually want to REPLACE the skeleton bound to a role.

Returns: { asset_path, role, skeleton_path, mirror_data_table_path, roled_skeleton_count, added, already_existed, saved }

add_pose_to_pose_assetA

Add a pose copied from the skeleton reference pose to a UPoseAsset under the given name (a pose of that name is replaced) and save it; refused when the asset has no skeleton. Returns num_poses, num_tracks and already_existed. For poses from animation frames use create_pose_asset_from_anim_sequence. A failed save makes success false, with saved=false and save_error.

Returns: { pose_asset_path, pose_name, num_poses, num_tracks, present, added, already_existed, saved, save_error, message }

add_retargeter_opA

Add a retarget op to the op stack of an IK Retargeter asset through its controller (one undo transaction), then save the asset; op_index and op_name are where and how the engine placed it. Default type: FK Chains op. An unknown op type, or a singleton op type the stack already has, is an error. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, op_index: int, op_name: string, op_type: string, op_count: int, saved: bool, save_error?: string }

add_rig_boneA

Add a bone to the hierarchy of a Control Rig Blueprint, under parent_name or at the root, then compile and save the blueprint. The engine keeps names unique, so element_key is the name the bone really got. Refused while PIE runs unless force is set.

Returns: { asset_path: string, element_key: string, element_type: string, parent: string, bone_count: int, null_count: int, control_count: int, curve_count: int, other_count: int, total: int, saved: bool, save_error: string }

add_rig_controlB

Add a control to a Control Rig's hierarchy. Control types: Bool, Float, ScaleFloat, Integer, Vector2D, Position, Scale, Rotator, Transform, EulerTransform (defaults to Float).

Returns: { asset_path: string, element_key: string, element_type: string, control_type: string, control_type_recognized: bool, parent: string, bone_count: int, null_count: int, control_count: int, curve_count: int, other_count: int, total: int, saved: bool, save_error: string }

add_rig_nullB

Add a null (space) to a Control Rig's hierarchy.

Returns: { asset_path: string, element_key: string, element_type: string, parent: string, bone_count: int, null_count: int, control_count: int, curve_count: int, other_count: int, total: int, saved: bool, save_error: string }

add_rigvm_linkA

Link an output pin to an input pin in the main RigVM graph of a Control Rig Blueprint (URigVMController::AddLink, no undo entry); a link already into that input pin, or out of an execute output pin, is replaced. Pins are NodeName.PinName paths as get_rigvm_graph lists them. A new link is then compiled and saved; a failed link (pins missing, incompatible or already linked) is an error with linked and saved false, and nothing is compiled or saved. Refused during PIE unless force. Add nodes with add_rigvm_node and set unlinked inputs with set_rigvm_pin_default; Blueprint graphs use connect_pins.

Returns: { asset_path: string, source_pin: string, target_pin: string, linked: bool, link_count: int, saved: bool, save_error: string }

add_rigvm_nodeB

Add a rig-unit node to a Control Rig's RigVM solver graph

Returns: { asset_path: string, node_name: string, node_title: string, node_type: string, pin_count: int, node_count: int, saved: bool, already_exists: bool, save_error: string }

add_skeletal_mesh_lodB

Append a new LOD entry to a skeletal mesh (clone of LOD 0 build settings).

Returns: { skeletal_mesh_path: string, lod_index: int, lod_count: int, screen_size: float, added: bool, note: string }

add_skeletal_mesh_socketA

Add a socket on a named bone of a skeletal mesh asset (undoable) and save the mesh. A copy also goes to the mesh's skeleton, which is then saved too; when the skeleton already has a socket of that name, the mesh has no skeleton, or the skeleton is engine content or under a read-only root, no copy is made (added_to_skeleton false) and skeleton_note says why. Errors, writing nothing, when the mesh does not load, the mesh already has a socket of that name, or the bone is missing from the mesh or its skeleton. success is false when a changed package fails to save. Edit existing sockets with set_skeletal_mesh_socket_transform or rename_skeletal_mesh_socket; skeleton-only sockets with add_socket_to_skeleton_asset.

Returns: { socket_name: string, bone_name: string, socket_count: int, location_x: float, location_y: float, location_z: float, added_to_skeleton: bool, skeleton_path: string, skeleton_note: string?, saved: bool, save_error: string?, skeleton_saved: bool?, skeleton_save_error: string? }

add_socket_to_skeleton_assetA

Add a socket to a USkeleton asset on a bone (the root by default) at a bone-relative location and rotation, then save; an existing socket of that name is updated in place (already_existed true). A failed save makes success false, with saved=false and save_error. A socket on a skeletal mesh asset (copied to its skeleton when that skeleton is project content): add_skeletal_mesh_socket.

Returns: { asset_path: string, socket_name: string, bone_name: string, socket_count: int, added: bool, already_existed: bool, saved: bool, save_error: string? }

add_virtual_boneA

Add a virtual bone from a source bone to a target bone of a USkeleton asset, named "VB _" by the engine, then save. Bone names are not checked against the skeleton; an existing pair returns that bone with already_exists true. Returns virtual_bone_name and virtual_bone_count.

Returns: { asset_path: string, virtual_bone_name: string, source_bone: string, target_bone: string, virtual_bone_count: int, saved: bool, already_exists: bool }

add_warp_target_to_componentA

Add (or update in-place) a FMotionWarpingTarget on an existing UMotionWarpingComponent. Exactly one of three payload shapes must be supplied: (1) component_path -> AddOrUpdateWarpTargetFromComponent(name, comp, NAME_None, false, TargetsForwardVector, ZeroVector, ZeroRotator); (2) location + rotation -> AddOrUpdateWarpTargetFromLocationAndRotation; (3) location only -> AddOrUpdateWarpTargetFromLocation. The engine API is idempotent by WarpTargetName (replace-in-place). Marking the owning actor dirty so the editor persists the change.

Returns: { actor_path: string, target_name: string, warp_target_count: int, source: string, already_existed: bool }

assign_skeletal_mesh_physics_assetA

Assign a physics asset to a skeletal mesh (or pass null/empty to clear it).

Returns: { skeletal_mesh_path: string, physics_asset_path: string, assigned: bool, cleared: bool, physics_asset_name: string }

bake_skeletal_mesh_lodB

Run the editor's skeletal-mesh reduction pipeline via USkeletalMeshEditorSubsystem::RegenerateLOD.

Returns: { skeletal_mesh_path: string, old_lod_count: int, new_lod_count: int, lod_count: int, baked: bool, regenerate_even_if_imported: bool, generate_base_lod: bool, bake_warning: string }

build_animation_state_machineA

Atomic JSON-spec builder for an Animation Blueprint state machine. Builds (or reuses) the state machine, then iterates states, transitions, and per-transition rules in one idempotent call. Replaces 8+ primitive cmds (add_anim_state_machine + add_anim_state + add_anim_transition + set_anim_transition_rule_*) with a single spec. Re-running with the same spec is a no-op (each primitive is internally idempotent: state-by-name, transition-by-source+target). For repeated invocations that change rule shape, the rule is re-applied on the existing transition.

Returns: { success: bool, anim_blueprint_path: string, machine_name: string, machine_already_existed: bool, states_created: int, states_skipped: int, transitions_created: int, transitions_updated: int, transitions_skipped: int, errors: [string], compiled: bool, compiled_after: bool }

build_pose_search_database_indexA

Request an async build of the PoseSearch index for a database

Returns: { database_path, schema_path, schema_cardinality, animation_asset_count, wait_for_completion, result, success, in_progress, failed, message }

clear_anim_graph_node_pin_bindingA

Remove the property binding from one input pin of an AnimGraph node (inverse of set_anim_graph_node_pin_binding), dropping a stale binding without recreating the node. Returns was_bound, is_bound and cleared; an unbound pin gives cleared=false, not an error. Undoable; saves the AnimBP without recompiling (run compile_anim_blueprint).

Returns: { node_id, pin_name, was_bound, is_bound, cleared, saved }

clear_anim_transition_ruleA

Remove every rule node from a transition's BoundGraph except the sink.

Returns: { anim_blueprint_path, machine_name, source_state, target_state, rule_cleared, sink_present, removed_count, remaining_rule_nodes, saved, save_error? }

clear_motion_warping_targetsA

Remove EVERY FMotionWarpingTarget from a UMotionWarpingComponent in one call (there is no bulk engine API; use remove_warp_target for a single named target). Reports previous + new count and the names it removed. Idempotent: clearing an already-empty component returns cleared:false + count:0, not an error.

Returns: { actor_name, cleared, previous_count, new_count, removed_names: [string] }

collapse_montage_segmentsA

Collapse a montage slot track's segments end-to-end (no gaps, order preserved). A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, slot_name, segment_count, applied, saved, save_error, message }

commit_bone_changesA

Mark a skeleton dirty + save it. YOU DO NOT NEED THIS after add_bone / remove_bone / rename_bone / set_bone_transform: each of those already notifies the skeleton's listeners on its own. It exists for the cases those do not cover -- batched mutations made outside the modifier, or an asset import that never went through one (interop with other tools).

Returns: { asset_path, committed, force, bone_count, saved, op: "commit_bone_changes" }

compile_anim_blueprintA

Compile an Animation Blueprint synchronously and save its package, even when the compile fails; returns status (EBlueprintStatus name), is_up_to_date, has_error and the error and warning messages with their counts. Refused while PIE runs unless force=true. Use get_anim_blueprint_info to inspect without compiling.

Returns: { anim_blueprint_path: string, compiled: bool, status: string, is_up_to_date: bool, has_error: bool, error_count: int, warning_count: int, errors: [string], warnings: [string], saved: bool, save_error?: string }

configure_animation_eventsA

Switch the tick of a skeletal mesh component in the editor world (or the one the world param picks): despite the name, it only toggles component ticking and tick-when-paused. Returns the previous and current tick flags; nothing is marked dirty or saved.

Returns: { component_name: string, requested_settings: string, events_configured: bool, previous_tick_enabled: bool, previous_tick_when_paused: bool, current_tick_enabled: bool, current_tick_when_paused: bool, component_valid: bool, component_class: string, anim_instance_class: string?, has_anim_instance: bool, world: string, world_name: string|null, world_package: string|null, world_type: string|null, net_mode: string|null, pie_instance: number }

connect_anim_graph_pinsA

Wire two AnimGraph pins (pose links AND data pins) using the graph's OWN schema. USE THIS INSTEAD OF connect_pins inside an AnimGraph: the generic connect_pins uses the K2 schema, which does not understand FPoseLink/FComponentSpacePoseLink pose pins, whereas this goes through UAnimationGraphSchema::TryCreateConnection so pose links connect correctly. Saves the ABP but does NOT recompile it -- run compile_anim_blueprint after your edits for runtime effect.

Returns: { connected, source_node_id, target_node_id, saved }

connect_ik_goal_to_solverA

Connect an existing IK Rig goal to a solver, creating that solver's per-goal effector/settings, in one undo transaction, then save the asset. This is the step that makes get_/set_ik_goal_settings work: a goal added via add_ik_goal is not attached to any solver until connected. Idempotent: re-connecting an already-connected goal is a success with already_connected:true, saved:false and a note, and nothing is saved, avoiding the duplicate the raw engine call would create. An unknown goal or out-of-range solver_index is an error. A failed save makes success false, with saved=false and save_error.

Returns: { ik_rig_path: string, goal_name: string, solver_index: int, connected: bool, already_connected: bool, saved: bool, save_error?: string, note?: string }

copy_anim_graph_nodesA

Copy a set of AnimGraph nodes (with internal FAnimNode settings + intra-selection wiring) between graphs. Equivalent to the editor's copy/paste: preserves each node's runtime struct properties and any links WITHIN the copied set (links to nodes outside the selection are dropped). Saves the destination ABP but does NOT recompile it -- run compile_anim_blueprint after your edits for runtime effect.

Returns: { copied_count, id_map:{old->new}, imported_nodes[], missing_node_ids[], saved }

create_anim_blueprintA

Create an Animation Blueprint (parent UAnimInstance) for a skeleton at package_path/name with the editor factory, compile it and save it; an existing Animation Blueprint at that path is returned unchanged (already_existed=true). Refused while PIE runs unless force=true. Returns asset_path, generated_class and target_skeleton_set.

Returns: { asset_path: string, name: string, skeleton_path: string, generated_class: string, is_anim_instance: bool, target_skeleton_set: bool, created: bool, already_existed: bool, saved: bool, save_error?: string }

create_anim_compositeA

Create and save a UAnimComposite asset bound to a USkeleton, under /Game. Idempotent: a UAnimComposite already at that path is returned unchanged with already_existed=true and saved=false, and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { name, package_path, asset_path, composite_path, skeleton, num_segments, created, already_existed, saved, save_error, message }

create_anim_montageA

Create and save an empty-but-valid UAnimMontage asset under /Game. Idempotent: a UAnimMontage already at that path is returned unchanged with already_existed=true and saved=false, and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { name, package_path, asset_path, montage_path, skeleton_path, slot_names, slot_name, slot_count, section_count, created, already_existed, saved, save_error, message }

create_anim_sequenceA

Create a UAnimSequence at package_path/anim_name bound to the USkeleton at skeleton_path (default the engine SkeletalCube_Skeleton) and save it; its data model gets frame_rate rounded to whole fps and round(length_seconds * fps) frames, but no bone tracks or curves. Idempotent: a UAnimSequence already at that path is returned unchanged (already_existed=true, saved=false, length and rate not applied) and nothing is saved; another asset class there or an unknown skeleton is an error. A failed save makes success false, with saved=false and save_error, and the new asset stays in memory only. Fill it with add_anim_bone_track or add_anim_float_curve; inspect it with get_anim_sequence_info.

Returns: { anim_sequence_path, anim_name, skeleton, play_length, frame_rate, num_frames, success, saved, save_error, already_existed, message }

create_blend_spaceA

Create and save a UBlendSpace (or UBlendSpace1D) asset under /Game. Idempotent: a UBlendSpace already at that path is returned unchanged with already_existed=true and saved=false, and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { name, package_path, asset_path, blend_space_path, is_1d, skeleton_path, axis_name, axis_min, axis_max, axis_grid_num, sample_count, created, already_existed, saved, save_error, message }

create_control_rig_blueprintA

Create a Control Rig Blueprint (non-modular) at package_path/name with UControlRigBlueprintFactory, compile it and save it. Idempotent: an existing Control Rig Blueprint there is returned unchanged (already_existed=true). Returns asset_path, generated_class, is_control_rig and saved; refused while PIE runs unless force is set.

Returns: { asset_path: string, name: string, generated_class: string, is_control_rig: bool, created: bool, already_existed: bool, saved: bool, save_error: string }

create_editable_skeletal_meshA

Duplicate a skeletal mesh (default /Engine/EngineMeshes/SkeletalCube) to package_path/skeletal_mesh_name in the project's content so it can be edited, creating the folder if needed. The copy keeps the source's skeleton (create_editable_skeleton makes a /Game skeleton) and is saved only when source control is enabled, otherwise follow with save_asset. Idempotent: a skeletal mesh already at that path is returned with created=false; any other asset there is an error. A source_mesh that is not a skeletal mesh is an error, and so is a destination that is engine content, under a read-only root or under no mounted root. duplicate_asset copies other asset types.

Returns: { asset_path: string, skeletal_mesh_name: string, source_mesh: string, created: bool }

create_editable_skeletonB

Create an editable /Game skeleton by duplicating an engine skeleton

Returns: { asset_path: string, name: string, source: string, bone_count: int, created: bool, saved: bool, save_error: string }

create_ik_retargeterA

Create and save a UIKRetargeter asset wiring source + target IK Rigs. An existing retargeter at that path is rewired and saved when either rig differs; when it already uses both rigs nothing changes, nothing is saved (saved=false) and a note says so. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, name: string, source_ik_rig: string, target_ik_rig: string, created: bool, already_existed: bool, saved: bool, save_error?: string, note?: string }

create_ik_rigA

Create and save a UIKRigDefinition asset and set its source skeletal mesh. Idempotent: an existing rig is loaded and only given the mesh, then saved, when it has another one; when it already has that mesh, or the mesh does not load or the engine refuses it (skeletal_mesh_set false), nothing changes, nothing is saved and a note says why. The default skeletal_mesh_path is /Engine/EngineMeshes/SkeletalCube. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, name: string, skeletal_mesh: string, skeletal_mesh_set: bool, created: bool, already_existed: bool, saved: bool, save_error?: string, note?: string }

create_pose_assetA

Create an empty UPoseAsset (no poses) at package_path/name, bound to the USkeleton at skeleton_path (default the engine SkeletalCube_Skeleton), and save it; no undo transaction. Idempotent: a UPoseAsset already at that path is returned untouched with already_existed=true and saved=false, even when bound to another skeleton, and nothing is saved. A name taken by another asset class or an unknown skeleton is an error, and a failed save makes success false, with saved=false and save_error. Add poses with add_pose_to_pose_asset; to build one from animation frames use create_pose_asset_from_anim_sequence.

Returns: { name, package_path, asset_path, pose_asset_path, skeleton, num_poses, created, already_existed, saved, save_error, message }

create_pose_asset_from_anim_sequenceA

Create a UPoseAsset built from a real UAnimSequence's frames and save it. Idempotent: a UPoseAsset already at that path is returned unchanged with already_existed=true and saved=false, and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { pose_asset_path, pose_asset_name, source_anim, skeleton_path, num_poses, created, success, already_existed, saved, save_error }

create_pose_search_databaseA

Create and save a UPoseSearchDatabase data asset bound to a UPoseSearchSchema

Returns: { name, package_path, asset_path, database_path, schema_path, schema_cardinality, animation_asset_count, created, already_existed, saved, message }

create_pose_search_schemaB

Create and save a UPoseSearchSchema data asset bound to a USkeleton

Returns: { name, package_path, asset_path, schema_path, skeleton_path, sample_rate, schema_cardinality, channel_count, created, already_existed, saved, message }

create_retarget_poseA

Create a new retarget pose for editing in an IK Retargeter through its controller, then save the asset. The engine makes the name unique, so read pose_name back. The pose is set as the current pose after creation, ready for bone rotation edits via set_retarget_pose_bone_rotation. A failed save makes success false, with saved=false and save_error.

Returns: { ik_retargeter_path: string, pose_name: string, source_or_target: string, success: bool, saved: bool, save_error?: string }

create_skeletal_mesh_morph_targetA

Register a new morph target on a skeletal mesh asset in memory only, for the rest of the editor session: it is never saved (persisted_to_disk is always false), and a mesh rebuild or reload drops any morph the mesh's imported source data does not contain. Each LOD gets one tiny seed delta on vertex 0 so the morph counts as valid; write real deltas with set_morph_target_deltas. Marks the mesh dirty. Idempotent: an existing name returns created=false and already_exists=true.

Returns: { morph_target_name: string, skeletal_mesh_path: string, created: bool, persisted_to_disk: bool, total_morph_targets: int, note: string }

delete_montage_sectionA

Delete the first composite section with that name (FName match, case ignored) from a UAnimMontage and save it; a missing name is a success with removed=false and nothing saved. Links from other sections (NextSectionName) are not updated. Returns removed_index, section_count and the remaining sections. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, section_name, removed_index?, already_existed, removed, section_count, sections[], saved, save_error, message }

disconnect_anim_graph_pinsA

Break AnimGraph pin links: a specific source->target link, or ALL links on the source pin. Use the specific form to insert a node into an existing chain (break A->B, then wire A->N and N->B). Saves the ABP but does NOT recompile it -- run compile_anim_blueprint after your edits for runtime effect.

Returns: { disconnected, broke_all, source_node_id, source_pin, saved }

disconnect_ik_goal_from_solverA

Disconnect a goal from a solver, removing that solver's per-goal effector/settings, through the IK Rig controller (one undo transaction), then save the asset. Inverse of connect_ik_goal_to_solver. Idempotent: disconnecting a goal that isn't connected is a success with was_connected:false, saved:false and a note, and nothing is saved. An out-of-range solver_index is an error. A failed save makes success false, with saved=false and save_error.

Returns: { ik_rig_path: string, goal_name: string, solver_index: int, connected: bool, was_connected: bool, saved: bool, save_error?: string, note?: string }

duplicate_anim_sequenceA

Copy a UAnimSequence to a new asset package_path/new_name with the same skeleton (StaticDuplicateObject) and save it; a name already taken by any asset, in memory or on disk (the source included), is refused and nothing is touched. A failed save makes success false, with saved=false and save_error, and the copy stays in memory only. Returns duplicate_path and duplicate_class. For other asset types use duplicate_asset.

Returns: { source_path, duplicate_path, duplicate_class, saved, save_error }

edit_anim_notifyA

Edit an existing FAnimNotifyEvent on a UAnimSequence (identified by name + occurrence) in an undo transaction and save it. No editable field is an error before anything changes; edits that leave the event as it is are a success with applied=false, applied_count 0 and saved=false, and the sequence is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { animation_path, notify_name, occurrence_index, matched_count, notify, applied_count, applied, saved, save_error, message }

edit_blendspace_sampleA

Edit a blend sample (by index): blend value and/or animation. At least one of blend_value / animation_path is required; both are individually optional so you can retime a sample without touching its animation, or swap the animation without moving it. A sample that already has those values is a success with value_edited=false, animation_replaced=false and saved=false, and the blend space is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { blendspace_path, index, value_edited, animation_replaced, num_samples, samples, saved, save_error, message }

evaluate_pose_search_queryA

Run a live motion-matching query on a PIE/Game actor against a loaded UPoseSearchDatabase (UPoseSearchLibrary::MotionMatch) and return the best-match asset + search cost, plus the query trajectory. Diagnoses why a chooser returns null. Best-effort: per-channel cost is not exposed by the BlueprintPure result.

Returns: { world_mode, actor_name, actor_resolved, anim_instance_class, pose_history_name, pose_history_found, database_path, query_trajectory_samples[], trajectory_sample_count, is_trajectory_empty, has_match, best_match_asset, best_match_database, best_cost, selected_time, is_continuing_pose_search, wanted_play_rate, is_mirrored, is_looping, per_channel_cost[], note, world_name, world_package, world_type, net_mode, pie_instance }

get_active_montagesA

Report the AnimMontage(s) currently playing on a live PIE actor's skeletal mesh (useful for blend-out debugging).

Returns: { actor, actor_name, component, world, anim_instance_class, montage_count, is_any_montage_playing, top_montage_id, enumeration, montages: [{ index, montage_path, montage_name, is_top, current_section, position, normalized_position, length, play_rate, blend_weight, desired_weight, blend_time, is_playing, is_active, instance_id, slots:[string] }], world_name: string|null, world_package: string|null, world_type: string|null, net_mode: string|null, pie_instance: number }

get_anim_asset_infoA

Load any animation asset and report its class, skeleton and asset_type (montage, composite, pose, sequence, blendspace or animation_asset) plus the counts of that type: sections/slots/notifies, segments, poses/tracks/curves, length, samples. Read-only; get_montage_info, get_anim_sequence_info and get_blendspace_samples give detail.

Returns: { asset_path, class, skeleton, num_segments, num_poses, section_count, slot_count, notify_count, sequence_length, rate_scale, num_tracks, num_curves, sample_count, asset_type }

get_anim_blueprint_infoA

Read an Animation Blueprint without compiling or changing it: target skeleton, parent and generated class, is_anim_instance, is_template, graph_count, and the state machines of its top-level AnimGraph with their state counts (conduits not counted). list_anim_state_machines scans every function graph.

Returns: { asset_path: string, target_skeleton: string, target_skeleton_set: bool, parent_class: string, generated_class: string, is_anim_instance: bool, is_template: bool, graph_count: int, state_machine_count: int, state_machines: [{ name: string, state_count: int }] }

get_anim_curve_dataA

Read one curve of a UAnimSequence without changing it: for a float curve its flags, num_keys and keys as time/value pairs; for a transform curve only flags and a summed num_keys. found=false (still a success) when the curve does not exist.

Returns: { anim_sequence_path, curve_name, curve_type, found, num_keys, flags, time, value, keys }

get_anim_curve_namesA

List the bone tracks, float curves, and transform curves on a UAnimSequence

Returns: { sequence_path, bone_track_count, float_curve_count, transform_curve_count, bone_tracks, float_curves, transform_curves }

get_anim_graph_node_propertiesA

Read the internal FAnimNode struct of an AnimGraphNode as typed JSON (the runtime settings, not the K2 pin surface get_graph_nodes reports). Use it to mirror a reference ABP's settings when grafting nodes: Pose History PoseCount/CollectorName, Slot SlotName, blend params...

Returns: { node_id, node_class, node_struct, node_properties:{...} }

get_anim_notifiesA

List the notify events of a UAnimSequence without changing it: name, trigger time, duration, track_index and the notify_class or notify_state_class of each, plus num_notifies. Use get_notify_track_names for track names and get_montage_info for the notifies of a montage.

Returns: { name, time, duration, track_index, notify_class, notify_state_class, animation_path, num_notifies, notifies }

get_anim_sequence_infoA

Read a UAnimSequence without changing it: skeleton, play_length, frame_rate, num_frames, bone track and float curve counts from its data model, num_sync_markers, enable_root_motion, retarget_source and ref_pose_seq. Use get_anim_curve_names for the track and curve names.

Returns: { anim_sequence_path, skeleton, play_length, frame_rate, num_frames, num_bone_tracks, num_float_curves, num_sync_markers, enable_root_motion, success }

get_anim_state_machine_infoA

Read the nodes of one state machine of an Animation Blueprint without compiling or changing it: state_count counts the states, conduit_count the conduits and transition_count the transitions; states lists every state, conduit and alias node with its kind (class name) and graph position, transitions excluded.

Returns: { state_machine, state_count, conduit_count, transition_count, states:[{name,kind,x,y}] }

get_animation_blueprint_infoA

Find an Animation Blueprint in the Asset Registry and report its object path, class, package, is_loaded and the size and timestamp of its .uasset on disk. With load_full_data it also loads the asset and adds the target skeleton, its bone count, the generated class and is_abstract. Read-only. blueprint_name takes an object path, a package path or a short name searched under /Game (the first match when several share it); no match is an error. For parent class, graphs and state machines use get_anim_blueprint_info.

Returns: { blueprint_name: string, blueprint_path: string, blueprint_class: string, package_name: string, is_loaded: bool, file_size_bytes: number, file_size_kb: number, file_size_mb: number, last_modified: string, loaded_successfully: bool?, is_valid: bool?, target_skeleton: string?, skeleton_bone_count: number?, has_target_skeleton: bool?, generated_class: string?, is_abstract: bool?, load_error: string? }

get_blendspace_samplesA

Read every sample of a UBlendSpace or UBlendSpace1D in index order (animation path, blend_x/blend_y/blend_z, rate_scale) plus num_samples and the per-axis input smoothing under interpolation. Read-only; change samples with add_blendspace_sample, edit_blendspace_sample or remove_blendspace_sample.

Returns: { animation, blend_x, blend_y, blend_z, rate_scale, blendspace_path, num_samples, samples }

get_bone_transformA

Read the LOCAL reference-pose transform of a bone (parent-relative, not component space). Exact inverse of set_bone_transform: it reads the same raw ref-pose array that one writes, so a read-modify-write round trip is lossless.

Returns: { asset_path, bone_name, bone_index, found, location:[x,y,z], rotation:[p,y,r], scale:[x,y,z], bone_count, op: "get_bone_transform" }

get_ik_bone_settingsA

Get bone-specific settings for a bone within a solver. FullBodyIK returns snake_case keys (rotation/position stiffness, axis limits Free/Limited/Locked, min/max angles, preferred angles); StretchLimb (the only other solver with per-bone settings) is serialized generically (camelCase: squashDirection vector). Only FullBodyIK and StretchLimb support per-bone settings; others return a note.

Returns: { ik_rig_path: string, solver_index: int, bone_name: string, settings: object }

get_ik_goal_settingsA

Get goal-specific settings for a goal connected to a solver. FullBodyIK returns snake_case keys (chain_depth, strength_alpha, pull_chain_alpha, pin_rotation); BodyMover (the only other solver with per-goal settings) is serialized generically (camelCase: influenceMultiplier, boneName). The goal must be connected to the solver first (connect_ik_goal_to_solver), else a note explains that. Solvers without per-goal settings return a note.

Returns: { ik_rig_path: string, solver_index: int, goal_name: string, settings: object }

get_ik_retarget_chain_detailsB

Get detailed info about a retarget chain: start/end bones, goal name.

Returns: { asset_path: string, chain_name: string, found: bool, start_bone: string, end_bone: string, goal_name: string }

get_ik_retargeter_infoA

Read the global structure of an IK Retargeter via its controller: source/target IK Rigs, the op-stack, per-op chain mappings, and the current poses. Read-only. Chain mappings are per-op in 5.6+ (there is no global RootSettings on the UIKRetargeter in 5.8; detailed root/global settings live inside the ops themselves).

Returns: { asset_path: string, source_ik_rig: string, target_ik_rig: string, op_count: int, ops: [{ op_index, op_name, enabled, parent_op, op_type }], chain_mappings: [{ op_name, target_chain, source_chain }], source: { current_pose, pelvis_bone, root_offset: {x,y,z} }, target: { current_pose, pelvis_bone, root_offset: {x,y,z} } }

get_ik_rig_infoA

Read an IK Rig asset: its skeletal mesh, the number of solvers, and every goal and retarget chain. Read-only; solvers are counted, not listed: get_ik_solver_details reads one by index.

Returns: { asset_path: string, solver_count: int, goal_count: int, retarget_chain_count: int, skeletal_mesh: string, goals: [{ goal_name, bone_name }], chains: [{ chain_name, start_bone, end_bone, goal_name }] }

get_ik_solver_bonesA

Read the start and end bone of one solver in an IK Rig asset, chosen by its 0-based position in the solver stack. Read-only; an out-of-range solver_index or a rig that does not load is an error. A solver type without an end bone returns "None" as end_bone. get_ik_solver_details adds the type, enabled state and connected goals; set_ik_solver_bones writes the bones.

Returns: { asset_path: string, solver_index: int, start_bone: string, end_bone: string }

get_ik_solver_detailsA

Read one solver of an IK Rig asset by its 0-based stack index: solver_type (the solver struct name, e.g. "IKRigFullBodyIKSolver"), unique_name ("<index+1> - "), enabled, start and end bone, and the names of the goals connected to it. Read-only; an out-of-range solver_index or a rig that does not load is an error. Use get_ik_solver_bones for just the bones, get_ik_solver_settings for its tunables, get_ik_rig_info for the goals and chains of the whole rig.

Returns: { asset_path: string, solver_index: int, solver_type: string, unique_name: string, enabled: bool, start_bone: string, end_bone: string, connected_goal_count: int, connected_goals: [string] }

get_ik_solver_settingsA

Get detailed solver-specific settings for a solver in an IK Rig. Returns all solver-level parameters for the specified solver. FullBodyIK uses curated snake_case keys; every other solver type (Limb/Pole/BodyMover/SetTransform/StretchLimb) is serialized generically from its live settings struct (camelCase property names).

Returns: { ik_rig_path: string, solver_index: int, solver_type: string, settings: object }

get_montage_infoA

Read a UAnimMontage without changing it: skeleton_path, section, slot and notify counts with their name lists, blend_in/blend_out times, blend modes, enable_auto_blend_out, blend_out_trigger_time, sync_group and sync_slot_index. Change them with set_montage_blend_times or set_montage_properties.

Returns: { montage_path, skeleton_path, section_count, slot_count, notify_count, sections, slots, notifies, blend_in, blend_out, blend_mode_in, blend_mode_out, enable_auto_blend_out, blend_out_trigger_time, sync_group, sync_slot_index }

get_morph_target_deltasA

Read back the vertex deltas of a morph target on a specific LOD (inverse of set_morph_target_deltas).

Returns: { morph_target_name: string, lod_index: int, total_deltas: int, returned_deltas: int, truncated: bool, deltas: [{vertex_index, position_delta:{x,y,z}, normal_delta:{x,y,z}}] }

get_notify_track_namesA

List the notify track names of a UAnimSequence in track order (UAnimationBlueprintLibrary::GetAnimationNotifyTrackNames) without changing it; returns track_names and track_count. Use get_anim_notifies for the events and add_notify_track or remove_notify_track to edit tracks.

Returns: { animation_path, track_names, track_count }

get_pose_search_runtime_stateA

Read-only report of the live motion-matching state on a PIE/Game actor (why a chooser returns null): its AnimInstance, its MotionTrajectory samples, whether a PoseSearchHistoryCollector node named pose_history_name exists, and (optionally) the target database's schema/channels.

Returns: { world_mode, actor_name, actor_resolved, actor_resolved_by, skeletal_mesh_component, anim_instance_class, pose_history_name, pose_history_found, trajectory:{found,component,property,sample_count,is_trajectory_empty,samples[]}, is_trajectory_empty, database?:{database_path,schema_path,schema_cardinality,channel_count,channels[],animation_asset_count}, note, world_name, world_package, world_type, net_mode, pie_instance }

get_retarget_posesA

List every retarget pose (source and target) of an IK Retargeter with its root translation delta and per-bone rotation deltas. Read-only. Bone rotation deltas use the same quat keys as set_retarget_pose_bone_rotation (quat_x, quat_y, quat_z, quat_w).

Returns: { asset_path: string, source: [{ name, is_current, root_translation_offset: {x,y,z}, bone_rotations: [{ bone, quat_x, quat_y, quat_z, quat_w }] }], target: [ ... same shape ... ] }

get_retargeter_op_infoA

Read one retarget op's live settings struct from an IK Retargeter by op index. Read-only (no save). The settings keys are the op settings UPROPERTY names with only the first character lower-cased (FJsonObjectConverter convention), e.g. FK Chains op exposes lODThreshold, bEnabled, bDebugDraw, chainDrawSize, bDrawChainLines. op_type is the settings struct name (e.g. IKRetargetFKChainsOpSettings), which differs from get_ik_retargeter_info.ops[].op_type (the op struct name).

Returns: { asset_path: string, op_index: int, op_name: string, op_type: string, enabled: bool, settings: object }

get_rig_control_valueA

Read a Control Rig control's current value (typed per ERigControlType) and its limit min/max. Round-trips set_rig_control_value / set_rig_control_limits.

Returns: { asset_path: string, control_name: string, control_type: string, value: any, limit_enabled: bool, min: number?, max: number? }

get_rig_hierarchyA

Read every element of a Control Rig Blueprint hierarchy in traversal order as elements [{name, type}], plus bone_count, null_count, control_count, curve_count, other_count (sockets, connectors and the rest) and total. Read-only: nothing is compiled or saved.

Returns: { asset_path: string, bone_count: int, null_count: int, control_count: int, curve_count: int, other_count: int, total: int, elements: [{name, type}] }

get_rigvm_graphB

Read a Control Rig's RigVM solver graph nodes pins and links

Returns: { asset_path: string, nodes: [object], node_count: int, link_count: int }

get_skeletal_mesh_infoA

Get detailed info about a skeletal mesh: LODs, materials, morph targets, sockets, bones.

Returns: { skeletal_mesh_path: string, num_lods: int, num_materials: int, num_morph_targets: int, num_sockets: int, num_bones: int, bone_names: [string], lod_info: [{lod_index, num_verts, num_sections}] }

get_skeletal_mesh_lod_infoB

Get per-LOD build settings and screen size for a skeletal mesh.

Returns: { lod_index: int, screen_size: float, num_material_map_entries: int, allow_cpu_access: bool, build_settings: {...} }

get_skeletal_mesh_material_slotsB

Get all material slot info for a skeletal mesh: slot names, material paths.

Returns: { skeletal_mesh_path: string, num_material_slots: int, material_slots: [{slot_index, slot_name, material_path, overlay_material_path}] }

get_skeletal_mesh_morph_targetsA

Get all morph targets on a skeletal mesh with delta counts.

Returns: { skeletal_mesh_path: string, count: int, morph_targets: [{name, has_valid_data, num_deltas_lod0}] }

get_skeletal_mesh_section_infoA

Get section data for a LOD: material index, triangle count, vertex count, flags.

Returns: { skeletal_mesh_path: string, lod_index: int, num_sections: int, lod_num_vertices: int, sections: [{section_index, material_index, num_triangles, num_vertices, recompute_tangent, cast_shadow, visible_in_ray_tracing, disabled, bone_map_count}] }

get_skeleton_asset_infoA

Read a summary of a USkeleton asset: bone_count, the first 10 bone names only, every virtual bone with its source and target, slot_group_count and socket_count. Read-only; for up to 100 bone names use get_skeleton_info with load_full_data true.

Returns: { asset_path: string, bone_count: int, bones: [string], virtual_bone_count: int, virtual_bone_names: [string], virtual_bones: [{ name: string, source_bone: string, target_bone: string }], slot_group_count: int, socket_count: int }

get_skeleton_infoB

Retrieve metadata and optional full bone/socket/slot data for a Skeleton asset

Returns: { skeleton_name: string, skeleton_path: string, skeleton_class: string, package_name: string, is_loaded: bool, file_size_bytes: number, file_size_kb: number, file_size_mb: number, last_modified: string, loaded_successfully: bool?, is_valid: bool?, bone_count: number?, bones: [object]?, bones_truncated: bool?, socket_count: number?, slot_group_count: number?, load_error: string? }

inspect_motion_warping_componentA

Read the full data-layer state of a UMotionWarpingComponent: the b_search_for_windows_in_anims_within_montages flag, the warp target array (via GetWarpTargets()), the modifier count (via GetModifiers()), the runtime adapter class (GetOwnerAdapter()->GetClass()), and the protected switch-off-conditions array count (via reflection — FindFProperty + FScriptArrayHelper). Read-only, idempotent.

Returns: { actor_path: string, b_search_for_windows_in_anims_within_montages: bool, warp_target_count: int, modifier_count: int, owner_adapter_class: string, switch_off_condition_count: int, warp_targets: array }

inspect_pose_search_databaseA

Read-only walk of Schema, DatabaseAnimationAssets and Channels on a UPoseSearchDatabase

Returns: { database_path, schema_path, pose_search_mode, kd_tree_query_num_neighbors, number_of_principal_components, base_cost_bias, tags, schema_cardinality, animation_asset_count, animation_assets[], channel_count, channels[] }

inspect_pose_search_schemaA

Read-only walk of a UPoseSearchSchema's public fields + FinalizedChannels. An empty finalized_channels / is_finalized:false is NOT a bug in this tool: the schema only gets finalized by AddDefaultChannels() or by a PostEditChange() on it, so a freshly authored schema reports none until something triggers that.

Returns: { schema_path, sample_rate, schema_cardinality, number_of_permutations, permutations_sample_rate, permutations_time_offset, add_data_padding: bool, inject_additional_debug_channels: bool, draw_inject_additional_debug_channels: bool, roled_skeletons: [{ role_name, skeleton_path, mirror_table_path }], roled_skeleton_count, is_finalized: bool, channel_count, finalized_channels: [{ class, channel_name, weight }], note?: string } -- note only when is_finalized is false.

is_skeleton_sharedA

Find the skeletal mesh assets bound to a USkeleton asset through an Asset Registry query on their Skeleton tag, returning mesh_count, mesh_paths and shared (true when more than one mesh uses it). Read-only; only the skeleton itself is loaded.

Returns: { asset_path, mesh_count, shared, mesh_paths }

link_montage_sectionsA

Chain one montage section to the next by setting its NextSectionName. add_montage_section creates sections but never links them; this writes FCompositeSection::NextSectionName so playback flows section -> next. Pass next_section_name "" or "None" to clear the link. Done in an undo transaction, then saved. Idempotent: the link the section already has is a success with changed=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, section_name, next_section_name, linked, changed, section_count, sections, saved, save_error, message }

list_anim_state_machinesA

List the state machine nodes at the top level of every function graph of an Animation Blueprint (the AnimGraph included), read-only and without compiling: count and state_machines [{name, graph_name}]. Machines nested inside states are not listed.

Returns: { count, state_machines: [{name, graph_name}] }

list_warp_targets_on_componentA

List every FMotionWarpingTarget on an actor's UMotionWarpingComponent. Read-only: wraps GetWarpTargets() (TConstArrayView). Each entry reports the FName, the static location/rotation, the optional component reference (via path or null), the optional bone name, the b_follow_component flag, the location/rotation offsets, and the location_offset_direction enum integer.

Returns: { actor_path: string, warp_target_count: int, warp_targets: array }

move_ik_solver_in_stackA

Move the solver at from_index so that it ends up at to_index (both 0-based positions in the solver stack) of an IK Rig asset through the IK Rig controller (one undo transaction), then save the asset. An index outside the stack is an error and nothing moves; from_index equal to to_index is not an error but moved false, saved false and a note, with nothing saved. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, from_index: int, to_index: int, moved: bool, solver_count: int, saved: bool, save_error?: string, note?: string }

play_animationA

Play an AnimMontage on a skeletal mesh component with UAnimInstance::Montage_Play at play_rate, then jump to start_section if playback started. Editor world unless the world param says otherwise; the component needs an anim instance. playing/success mean Montage_Play returned a length above 0.

Returns: { component_name: string, montage_path: string, montage_name: string, playing: bool, play_rate: number, montage_length: number, return_value: number, success: bool, start_section: string?, world: string, world_name: string|null, world_package: string|null, world_type: string|null, net_mode: string|null, pie_instance: number }

refresh_anim_montage_cacheA

Refresh derived cache data on a UAnimMontage (NotifyTracks / SequenceLength / bone-cache). Idempotent. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, refreshed, sequence_length, slot_count, section_count, saved, save_error, message }

reimport_anim_sequenceA

Reimport a UAnimSequence, or any reimportable asset (the class is not checked), from source_file_path or its first recorded source via FReimportManager, automated (no dialogs) and unsaved. A missing source is refused before the reimport, which would crash the editor on it, and a reimport the handler reports as failed is a failure too: both make success false with reimported=false, and the missing source a note.

Returns: { anim_sequence_path, source_file_path, reimported, source_validated, note? }

remove_anim_blueprintA

Delete a UAnimBlueprint asset after verifying the asset is a UAnimBlueprint.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_anim_bone_trackA

Remove the animation track of one bone from a UAnimSequence through its data controller (IAnimationDataController::RemoveBoneTrack, one undo step) and save the package. No track with that bone name is a success with removed=false and nothing saved; a failed save makes success false, with saved=false and save_error. List tracks with get_anim_curve_names.

Returns: { sequence_path, bone_name, removed, saved, save_error }

remove_anim_compositeA

Delete a UAnimComposite asset after verifying the asset is a UAnimComposite.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_anim_composite_segmentA

Remove an FAnimSegment by index from a UAnimComposite's AnimationTrack, then recompute its length. A failed save makes success false, with saved=false and save_error.

Returns: { composite_path, index, num_segments, composite_length, segments, success, saved, save_error }

remove_anim_conduitA

Remove a conduit node (and its bound rule subgraph) from a state machine.

Returns: { anim_blueprint_path: string, machine_name: string, conduit_name: string, removed: bool, already_absent: bool, conduit_count: int, transition_count: int, cascaded_transitions_removed: int, saved: bool, save_error?: string }

remove_anim_curveA

Remove a float or transform curve by name from a UAnimSequence through its data controller (one undo step) and save the package. No such curve is a success with removed=false and nothing saved; a failed save makes success false, with saved=false and save_error. Any curve_type other than transform targets float curves.

Returns: { sequence_path, curve_name, curve_type, removed, saved, save_error }

remove_anim_curve_nameA

Remove a curve metadata entry (curve name) from a USkeleton (idempotent).

Returns: { asset_path, curve_name, removed, already_absent, present, curve_count, curve_names, saved }

remove_anim_montageA

Delete a UAnimMontage asset after verifying the asset is a UAnimMontage.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_anim_notifyA

Remove every notify event whose NotifyName matches notify_name from a UAnimSequence (UAnimationBlueprintLibrary::RemoveAnimationNotifyEventsByName) in an undo transaction and save it. A name no event has is a success with removed=false, already_absent=true and saved=false, and the sequence is neither dirtied nor saved; a failed save makes success false, with saved=false and save_error.

Returns: { animation_path, notify_name, removed, removed_count, already_absent, saved, save_error }

remove_anim_sequenceA

Delete a UAnimSequence asset after verifying the asset is a UAnimSequence.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_anim_slot_groupA

Remove an animation slot group from a skeleton (idempotent; guarded against missing group).

Returns: { asset_path: string, group_name: string, removed: bool, already_absent: bool, slot_group_count: int, slot_group_names: [string], saved: bool }

remove_anim_stateA

Remove a state node (and its bound animation subgraph) from a state machine.

Returns: { anim_blueprint_path: string, machine_name: string, state_name: string, removed: bool, already_absent: bool, state_count: int, transition_count: int, cascaded_transitions_removed: int, saved: bool, save_error?: string }

remove_anim_sync_markerA

Remove every authored sync marker with the given name from a UAnimSequence in an undo transaction and save the package. Returns markers_before, markers_after and removed; no marker with that name is a success with removed=false and nothing saved, and a failed save makes success false, with saved=false and save_error.

Returns: { sequence_path, marker_name, markers_before, markers_after, removed, saved, save_error }

remove_anim_transitionA

Remove a source->target transition (and its rule subgraph) from a state machine.

Returns: { anim_blueprint_path: string, machine_name: string, source_state: string, target_state: string, removed: bool, already_absent: bool, transition_count: int, saved: bool, save_error?: string }

remove_animation_asset_from_pose_search_databaseA

Remove one FPoseSearchDatabaseAnimationAsset entry from a UPoseSearchDatabase by 0-based index (inverse of add_animation_asset_to_pose_search_database). Idempotent: an out-of-range index returns removed:false + note, not an error. The database index is NOT rebuilt here -- run build_pose_search_database_index afterwards.

Returns: { database_path, animation_asset_index, removed, previous_count, new_count }

remove_blend_profileA

Remove a WHOLE UBlendProfile from a skeleton (idempotent). Inverse of set_blend_profile_bone, which is what implicitly CREATES a profile -- there is no separate create_blend_profile to undo.

Returns: { asset_path, profile_name, removed, already_absent, profile_count, profile_names, saved }

remove_blend_spaceA

Delete a UBlendSpace asset after verifying the asset is a UBlendSpace.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_blendspace_1dA

Delete a UBlendSpace1D asset after verifying the asset is a UBlendSpace1D.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_blendspace_sampleA

Remove a blend sample (by index) from a BlendSpace. WARNING: the remaining indices REORDER -- the engine removes with a swap, so the LAST sample lands in the deleted slot. Never remove a batch by descending index and assume the rest held still: the full post-op sample list is returned so the caller can re-sync before the next call. A failed save makes success false, with saved=false and save_error.

Returns: { blendspace_path, removed, num_samples, samples, saved, save_error, message }

remove_boneA

Remove a bone from a skeleton's reference skeleton (idempotent).

Returns: { asset_path, bone_name, removed, already_absent, remove_children, bone_count, saved, op: "remove_bone" }

remove_ik_goalA

Remove an IK goal from an IK Rig by name through the IK Rig controller (one undo transaction), then save the asset. Inverse of add_ik_goal: also detaches the goal from every solver's effector and clears it from any retarget chain that referenced it. Idempotent: removing a goal that isn't present is a success with removed:false, already_absent:true, saved:false and a note, and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, goal_name: string, removed: bool, already_absent: bool, goal_count: int, saved: bool, save_error?: string, note?: string }

remove_ik_retarget_chainA

Remove the retarget chain with that name from an IK Rig asset through the IK Rig controller (one undo transaction), then save the asset. A name no chain has is not an error but removed false, saved false and a note, with nothing saved. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, chain_name: string, removed: bool, chain_count: int, saved: bool, save_error?: string, note?: string }

remove_ik_solverA

Remove the solver at a 0-based index from the solver stack of an IK Rig asset through the IK Rig controller (one undo transaction), then save the asset. An out-of-range index is an error. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, removed_solver_index: int, solver_count: int, removed: bool, saved: bool, save_error?: string }

remove_montage_notifyA

Remove the notify event at a zero-based index from the Notifies array of a UAnimMontage and save it; an index past the end changes nothing and still returns success with removed=false. Returns removed_notify_name, notify_count_before, notify_count and the remaining notify names. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, notify_index, removed_notify_name?, notify_count_before, notify_count, notifies[], removed, saved, save_error, message }

remove_montage_slotA

Remove a slot animation track from a UAnimMontage by name or index. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, slot_name?, slot_index?, removed_index?, removed_slot_name?, slot_count, slots[], already_existed, removed, saved, save_error, message }

remove_motion_warping_componentA

Detach the UMotionWarpingComponent from an actor (mirror of add_motion_warping_component). Idempotent: an actor that has no such component returns already_existed:false + removed:false + note, not an error.

Returns: { actor_path: string, component_path?: string, removed: bool, already_existed: bool, note?: string }

remove_notify_trackA

Remove a named notify TRACK from an AnimSequence (deletes events on it + reindexes the rest). A failed save makes success false, with saved=false and save_error.

Returns: { animation_path, track_name, track_names, track_count, already_absent, saved, save_error, message }

remove_pose_assetA

Permanently delete one UPoseAsset after checking that the path loads as one: a force delete with no confirmation and no undo that nulls references to it. Idempotent: a path that no longer loads gives deleted=false with a note, not an error, and so does an asset of another class; during PIE the delete fails with deleted=false. Check get_asset_referencers first. To drop one pose or curve inside the asset use remove_pose_from_pose_asset or remove_pose_curve; delete_asset removes an asset of any type.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_pose_curveA

Delete the named curve from a UPoseAsset (UPoseAsset::DeleteCurves) in an undo transaction and save the asset; an absent curve is a success with removed=false, removed_count 0 and saved=false, and the asset is neither modified nor saved. Returns removed_count, removed and num_curves. A failed save makes success false, with saved=false and save_error.

Returns: { pose_asset_path, curve_name, removed_count, removed, num_curves, saved, save_error, message }

remove_pose_from_pose_assetA

Delete the named pose from a UPoseAsset (UPoseAsset::DeletePoses, which also fixes the base pose index) in an undo transaction and save the asset. An absent name is a success with removed=false and saved=false, and the asset is neither modified nor saved. Returns was_present, removed_count, contains_after, num_poses and the remaining pose_names. A failed save makes success false, with saved=false and save_error.

Returns: { pose_asset_path, pose_name, was_present, removed_count, removed, contains_after, num_poses, pose_names, saved, save_error, message }

remove_pose_search_channel_from_schemaA

Remove a UPoseSearchFeatureChannel_* from a UPoseSearchSchema by index or type (inverse of add_pose_search_channel_to_schema)

Returns: { schema_path, channel_index, channel_type, channel_class, schema_cardinality, channel_count, previous_count, removed, already_absent, saved, message }

remove_pose_search_databaseA

Destroy a UPoseSearchDatabase asset (mirror of create_pose_search_database). Typed-delete: it loads the asset and REFUSES to delete it if it is not a UPoseSearchDatabase, so it cannot wipe the wrong asset the way the generic delete_asset can. Idempotent on missing assets.

Returns: { database_path, deleted, already_existed, asset_class?, note? }

remove_pose_search_roled_skeletonA

Remove a roled FPoseSearchRoledSkeleton entry from a UPoseSearchSchema by role or by index (inverse of add_pose_search_roled_skeleton). Idempotent: no match = no write, reported as already_absent. The schema is re-finalized after the removal, so finalized_channels changes with it.

Returns: { asset_path, role, skeleton_index, removed_skeleton_path, roled_skeleton_count, previous_count, removed, already_absent, saved }

remove_pose_search_schemaA

Destroy a UPoseSearchSchema asset (mirror of create_pose_search_schema). Typed-delete: it loads the asset and REFUSES to delete it if it is not a UPoseSearchSchema, so it cannot wipe the wrong asset the way the generic delete_asset can. Idempotent on missing assets.

Returns: { schema_path, deleted, already_existed, asset_class?, note? }

remove_retarget_poseA

Remove a retarget pose from an IK Retargeter by name through its controller, then save the asset. Inverse of create_retarget_pose. If the removed pose was the current one, the retargeter falls back to the default pose. Idempotent: removing a pose that isn't present is a success with removed:false, already_absent:true, saved:false and a note, and nothing is saved. The engine's built-in default pose cannot be removed (honest error). A failed save makes success false, with saved=false and save_error.

Returns: { ik_retargeter_path: string, pose_name: string, source_or_target: string, removed: bool, already_absent: bool, success: bool, saved: bool, save_error?: string, note?: string }

remove_retargeter_opA

Remove the op at a 0-based index, with any child ops, from the op stack of an IK Retargeter asset through its controller (one undo transaction), then save the asset. An out-of-range index is an error. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, removed_op_index: int, removed: bool, op_count: int, saved: bool, save_error?: string }

remove_rig_elementA

Remove one element (by name and type) from a Control Rig Blueprint hierarchy with RemoveElement, then compile and save the blueprint. Errors on an unknown type or a missing element. Returns the per-type counts afterwards; refused while PIE runs unless force is set.

Returns: { asset_path: string, element_key: string, element_type: string, removed: bool, bone_count: int, null_count: int, control_count: int, curve_count: int, other_count: int, total: int, saved: bool, save_error: string }

remove_rigvm_nodeA

Remove a node from a Control Rig's RigVM solver graph, then compile and save the rig. A node that is not found, or that the controller fails to remove, is an error and nothing is compiled or saved.

Returns: { asset_path: string, node_name: string, removed: bool, node_count: int, saved: bool, save_error: string }

remove_skeletal_mesh_lodA

Remove one LOD from a skeletal mesh asset, with its source model and cached reduction data; higher LODs shift down one index. lod_index must be 1 or more and below the LOD count, otherwise an error (LOD 0 is never removed). Marks the mesh dirty without saving or rebuilding render data, so follow with save_asset. Use add_skeletal_mesh_lod to append a LOD, get_skeletal_mesh_lod_info to inspect them, set_skeletal_mesh_min_lod to skip the most detailed LODs while keeping them.

Returns: { skeletal_mesh_path: string, lod_index: int, lod_count: int, removed: bool }

remove_skeletal_mesh_morph_targetB

Remove a morph target from a skeletal mesh by name.

Returns: { morph_target_name: string, skeletal_mesh_path: string, removed: bool, remaining_morph_targets: int }

remove_skeletal_mesh_socketA

Remove a socket from a skeletal mesh (and its skeleton twin). Idempotent: re-running with an absent socket returns already_removed=true without mutating the asset.

Returns: { socket_name: string, skeletal_mesh_path: string, removed: bool, already_removed: bool, socket_count: int }

remove_socket_from_skeleton_assetA

Remove a socket from the socket list of a USkeleton asset and save it. Idempotent: a missing socket returns removed false and already_absent true without saving. Returns socket_count and the remaining socket_names; sockets that exist only on a skeletal mesh are untouched (use remove_skeletal_mesh_socket).

Returns: { asset_path: string, socket_name: string, removed: bool, already_absent: bool, socket_count: int, socket_names: [string], saved: bool }

remove_virtual_boneA

Remove a virtual bone from a USkeleton asset, named directly or found by its source and target bones, then save. Idempotent: no match returns removed false and already_absent true without saving. Returns the remaining virtual_bone_names; a failed save returns success false.

Returns: { asset_path: string, virtual_bone_name: string, removed: bool, already_absent: bool, virtual_bone_count: int, virtual_bone_names: [string], saved: bool }

remove_warp_targetA

Remove a FMotionWarpingTarget from a UMotionWarpingComponent by FName. Wraps UMotionWarpingComponent::RemoveWarpTarget(name) which returns the count of entries removed (0 or 1; the array is keyed by FName). Idempotent: removing a non-existent target returns count:0 without raising an error.

Returns: { actor_path: string, target_name: string, removed_count: int, warp_target_count: int }

rename_anim_curveA

Rename a float or transform curve on a UAnimSequence through its data controller (one undo step) and save it; errors when the source curve does not exist or the rename is refused. The same name for both is a success with renamed=false, saved=false and a note, and nothing is written or saved. Any curve_type other than transform means float. Returns renamed and saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, old_curve_name, new_curve_name, renamed, saved, save_error, note? }

rename_boneA

Rename a bone in the reference skeleton of a USkeleton asset and save it. Fails with an error when old_name is not a bone or new_name is already taken; skeletal meshes and animations that use the old name are not updated. A failed save returns success false.

Returns: { asset_path, old_name, new_name, renamed: true, not_found: false, already_used: false, bone_count, saved, save_error?, op: "rename_bone" }

rename_ik_retarget_chainA

Rename a retarget chain of an IK Rig asset through the IK Rig controller (one undo transaction) and save it. The engine makes the new name unique, so read new_name back; an unknown chain_name is not an error but returns renamed false, saved false and a note, with nothing saved. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, old_name: string, new_name: string, renamed: bool, saved: bool, save_error?: string, note?: string }

rename_montage_sectionA

Rename an existing FCompositeSection on a UAnimMontage by zero-based section_index, in an undo transaction, and save it. The name the section already has (FName match, case ignored) is a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, section_index, old_name, new_name, section_count, sections, applied, saved, save_error, message }

rename_pose_in_pose_assetA

Rename an existing named pose in a UPoseAsset (UPoseAsset::ModifyPoseName) in an undo transaction and save it; renamed is measured by reading the pose names back. An unknown old_pose_name, a new_pose_name another pose already has, or a rename the engine does not take is an error with nothing saved; the same name for both is a success with renamed=false and saved=false, and nothing is modified or saved. A failed save makes success false, with saved=false and save_error.

Returns: { pose_asset_path, old_pose_name, new_pose_name, renamed, contains_new, contains_old, num_poses, pose_names, saved, save_error, message }

rename_rig_elementA

Rename an element in a Control Rig's hierarchy. Idempotent: renaming to the current name is a no-op ({ renamed:false, already_named:true }). The engine disambiguates name collisions with a numeric suffix rather than failing, reported honestly via name_adjusted.

Returns: { asset_path: string, old_name: string, element_key: string, element_type: string, renamed: bool, already_named: bool, name_adjusted: bool, bone_count: int, null_count: int, control_count: int, curve_count: int, other_count: int, total: int, saved: bool, save_error: string }

rename_skeletal_mesh_morph_targetA

Rename a morph target on a skeletal mesh asset and save the mesh. Fails if old_name is not a morph target of the mesh or new_name already exists; a failed save also returns an error although the rename stays in memory. Returns old_name, new_name and renamed.

Returns: { old_name: string, new_name: string, skeletal_mesh_path: string, renamed: bool }

rename_skeletal_mesh_socketA

Rename a socket on a skeletal mesh (and its skeleton twin).

Returns: { old_name: string, new_name: string, skeletal_mesh_path: string, renamed: bool, already_renamed: bool, socket_count: int }

scaffold_aim_offset_blend_spaceA

Create a UAimOffsetBlendSpace for a skeleton at package_path/asset_name and save it, or re-save the one already there (already_existed=true); a failed save still succeeds with saved=false. Yaw/pitch ranges and grid counts are only echoed, not written: set axes with set_blendspace_properties.

Returns: { asset_path, skeleton_path, yaw_min, yaw_max, pitch_min, pitch_max, num_grid_points_yaw, num_grid_points_pitch, already_existed, saved, note? }

scaffold_blend_space_2dA

Create a UBlendSpace (2D) asset for parameter-driven animation blending (e.g. Speed x Direction). Idempotent on re-run; axis metadata left at engine defaults (set the protected axis fields afterwards with set_blendspace_properties).

Returns: { asset_path, skeleton_path, axis_x_label, axis_y_label, x_axis_range, y_axis_range, num_grid_points_x, num_grid_points_y, already_existed, saved, note? }

scaffold_locomotion_animbpA

Create or update a character Animation Blueprint with a "Locomotion" state machine + Idle/Walk/Run states + bidirectional transitions between them. Idempotent: re-running on an existing AnimBP returns the existing scaffold.

Returns: { anim_blueprint_path, package_path, skeleton_path, machine_name, state_count, transition_count, already_existed, saved }

scale_anim_curveA

Retime a FLOAT curve on a UAnimSequence through its data controller (one undo step), then save the package: every key TIME becomes (t - origin) * factor + origin, and the key VALUES are left untouched -- this stretches/compresses a curve in time, it does not scale its amplitude. FLOAT-CURVE ONLY: a name that is not a float curve of the sequence, a transform curve included, is an error and nothing is written. A retime that moves no key (factor 1, no keys, or every key at the origin) is a success with applied=false and saved=false, and nothing is written or saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, curve_name, origin, factor, num_keys, applied, saved, save_error, message }

set_anim_additive_settingsA

Set the additive-animation type and base pose on a UAnimSequence in an undo transaction and save it. Settings the sequence already has are a success with changed=false and saved=false, and the sequence is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, additive_anim_type, ref_pose_type, ref_frame_index, ref_pose_anim_set, changed, success, saved, save_error, message? }

set_anim_bone_track_keysA

Replace the keys of one bone track of a UAnimSequence with the given per-key transforms (translation, rotation, scale: real pose data, not identity), adding the track when it is missing, through its data controller as one undo step, then save the package; num_keys_readback and first_key are read back from the data model. A bone_name the sequence's skeleton does not have is an error and nothing is written; an omitted bone_name targets the root bone. A failed save makes success false, with saved=false and save_error. Identity keys: add_anim_bone_track.

Returns: { anim_sequence_path, bone_name, num_keys, num_keys_readback, num_bone_tracks, first_key:{translation,rotation_euler}, success, saved, save_error, message }

set_anim_curve_colorA

Set the editor display color of a FLOAT curve on a UAnimSequence through its data controller (one undo step), then save the package (cosmetic: it tints the curve in the editor, it does not affect evaluation). FLOAT-CURVE ONLY: a name that is not a float curve of the sequence, a transform curve included, is an error and nothing is written. The color the curve already has is a success with applied=false and saved=false, and nothing is written or saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, curve_name, color, applied, saved, save_error, message }

set_anim_curve_commentA

Set the author comment of a FLOAT curve on a UAnimSequence through its data controller (one undo step), then save the package (metadata only; it does not affect evaluation). FLOAT-CURVE ONLY: a name that is not a float curve of the sequence, a transform curve included, is an error and nothing is written. The comment the curve already has (case-sensitive) is a success with applied=false and saved=false, and nothing is written or saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, curve_name, comment, applied, saved, save_error, message }

set_anim_curve_interp_modeA

Replace the curve flags (the EAnimAssetCurveFlags bitmask) of an existing float or transform curve on a UAnimSequence with one flag, in an undo transaction, then save the package. Despite the name it changes no key interpolation or tangents: linear and editable both set Editable; metadata, drive_track and disabled set those flags. interp_mode is required; an unknown mode, curve or sequence is an error, and any curve_type other than transform means float. old_flags and new_flags are the bitmasks before and after; flags the curve already has are a success with applied=false, saved=false and a note, and nothing is written or saved; a failed save makes success false, with saved=false and save_error. get_anim_curve_data reads the flags.

Returns: { anim_sequence_path, curve_name, interp_mode, old_flags, new_flags, applied, saved, save_error, note? }

set_anim_curve_keysA

Replace every key of an existing float curve on a UAnimSequence with the given [time, value] pairs as linear keys with auto tangents, through its data controller in an undo transaction, then save the package; num_keys is read back. The curve must exist (add_anim_float_curve first) and keys needs at least one valid pair. A transform curve is refused, since its keys are transforms, not [time, value] pairs: rekey it with add_anim_transform_curve. Any other curve_type is an error, and so is a rekey the data controller rejects, with nothing saved. A curve that already holds exactly those keys is a success with applied=false, saved=false and a note, and nothing is written or saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, curve_name, curve_type, num_keys, applied, saved, save_error, note? }

set_anim_frame_rateA

Set the frame rate of the data model of a UAnimSequence (IAnimationDataController::SetFrameRate, one undo step) to fps rounded to whole frames per second, then save the package; fps, numerator and denominator are read back from the data model. The data controller only takes a rate that is a multiple or a factor of the current one, and the frame count must stay whole at the new rate: any other rate is an error and nothing changes. The rate the data model already has is a success with changed=false, saved=false and a note, and nothing is written or saved. A failed save makes success false, with saved=false and save_error. get_anim_sequence_info reads the rate.

Returns: { sequence_path, fps, numerator, denominator, changed, saved, save_error, note? }

set_anim_graph_node_pin_bindingA

Bind an AnimGraph node input pin to a variable or property path in the node property-binding map (the Details-panel bind chip), e.g. "TransformTrajectory" to "Trajectory"; set_anim_graph_node_property edits the FAnimNode struct instead. Returns applied and the stored binding; saves the AnimBP without recompiling (run compile_anim_blueprint).

Returns: { node_id, pin_name, binding_path, applied, binding:{property_name, property_path[], path_as_text, is_bound, is_promotion, binding_type, pin_category}, saved }

set_anim_graph_node_propertyA

Write a property of an AnimGraphNode's internal FAnimNode struct by (dotted) name. Saves the ABP but does NOT recompile it -- run compile_anim_blueprint after your edits for runtime effect.

Returns: { node_id, property, applied, new_value, saved }

set_anim_montage_preview_meshA

Set the editor preview USkeletalMesh of a UAnimMontage (SetPreviewMesh, one undo step) and save the montage; it only changes what the asset editor shows, and the mesh skeleton is not checked against the montage. Returns mesh_path, prev_mesh_path and applied; the preview mesh the montage already has is a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, mesh_path, prev_mesh_path, applied, saved, save_error, message }

set_anim_montage_rate_scaleA

Set the global RateScale (and optionally BlendOutTriggerTime) on a UAnimMontage in an undo transaction and save it. Values the montage already has, or none given, are a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, rate_scale, blend_out_trigger_time, applied, saved, save_error, message }

set_anim_montage_skeletonA

Rebind a UAnimMontage to a different USkeleton (clears existing source link + recomputes bone caches) in an undo transaction and save it. The skeleton the montage already uses is a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, skeleton_path, prev_skeleton_path, applied, saved, save_error, message }

set_anim_number_of_framesA

Set the number of frames of the data model of a UAnimSequence (IAnimationDataController::SetNumberOfFrames, one undo step), then save the package; frame_count is read back from the data model. When the data model rate differs from the sequence sampling rate (as after set_anim_frame_rate), a count that is not a whole number of frames at the sampling rate is an error naming the multiple to use, with nothing changed (only the default sampling rate is checked, not per-platform overrides of it). The current count gives saved=false and a note, with nothing saved. A count the data controller rejects is an error with nothing saved, and a failed save makes success false, with saved=false and save_error.

Returns: { sequence_path, frame_count, saved, save_error, note? }

set_anim_retarget_sourceA

Set a UAnimSequence's retarget source (and optionally its retarget reference-pose sequence) in an undo transaction and save it. A ref_pose_seq_path that does not load is an error before anything changes; values the sequence already has are a success with changed=false, applied_count 0, saved=false and a note, and nothing is modified or saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, retarget_source, ref_pose_seq, ref_pose_seq_set, ref_pose_seq_cleared, applied_count, notes, changed, success, saved, save_error, note? }

set_anim_root_motionA

Write the three root motion settings of a UAnimSequence (bEnableRootMotion, RootMotionRootLock, bForceRootLock) and save it. All three are written on every call, so an omitted one is reset to its default; an unknown root lock name applies RefPose while the reply echoes the given text. Settings the sequence already has are a success with changed=false and saved=false, and the sequence is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { anim_sequence_path, enable_root_motion, root_motion_root_lock, force_root_lock, changed, success, saved, save_error, message }

set_anim_transition_rule_automaticA

Set the automatic rule of one transition (source_state to target_state) in a state machine of an Animation Blueprint: bAutomaticRuleBasedOnSequencePlayerInState and AutomaticRuleTriggerTime, both written every call (omitted means false and 0). Marks it structurally modified and saves without compiling; refused while PIE runs unless force=true.

Returns: { anim_blueprint_path, machine_name, source_state, target_state, enabled, trigger_time, rule_graph_has_result_node, saved, save_error? }

set_anim_transition_rule_from_boolB

Wire a bool variable's getter as the rule of a transition.

Returns: { anim_blueprint_path, machine_name, source_state, target_state, variable_name, variable_kind, rule_set, sink_present, contributor_count, contributor_node_class, saved, save_error? }

set_anim_transition_rule_from_comparisonB

Wire a float comparison as the rule of a transition.

Returns: { anim_blueprint_path, machine_name, source_state, target_state, variable_name, operator, comparison_value, variable_kind, rule_set, sink_present, contributor_count, contributor_node_classes, saved, save_error? }

set_animation_speedA

Set the play rate of a skeletal mesh component, found by object name in the editor world (or the world the world param selects), and switch its component tick on. Only a component in Use Animation Asset (single node) mode takes it: in Animation Blueprint mode nothing changes and actual_speed reads 0, so check speed_set_successfully. Transient: nothing is saved or undoable. A speed outside 0-10 or no such component is an error. For montages use play_animation with play_rate, or set_anim_montage_rate_scale on the asset.

Returns: { component_name: string, requested_speed: number, previous_speed: number, actual_speed: number, speed_set_successfully: bool, previous_tick_enabled: bool, current_tick_enabled: bool, component_valid: bool, component_class: string, anim_instance_class: string?, has_anim_instance: bool, anim_instance_valid: bool?, warning: string?, world: string, world_name: string|null, world_package: string|null, world_type: string|null, net_mode: string|null, pie_instance: number }

set_blend_profile_boneA

Set a bone's blend scale on a UBlendProfile (creates profile if missing).

Returns: { asset_path, profile_name, bone_name, scale, updated, created_profile, profile_count, saved, op: "set_blend_profile_bone" }

set_blendspace_interpolationA

Set a blend space's INPUT-SMOOTHING (interpolation) per axis: smoothing time, damping ratio, max speed, smoothing type. Distinct from set_blendspace_properties (which only sets the BlendParameters axis name/min/max/grid). Writes UBlendSpace::InterpolationParam[axis] via reflection. 1D smooths axis 0 only; 2D smooths X (axis 0) and Y (axis 1). Only the supplied fields change, in one undo transaction, then the blend space is saved; an unknown smoothing type is an error before anything changes, and values the axes already have are a success with changed=false, applied_count 0, saved=false and a note, with nothing modified or saved. A failed save makes success false, with saved=false and save_error.

Returns: { blend_space_path, is_1d, x_axis: {interpolation_time, damping_ratio, max_speed, interpolation_type}, y_axis: {...}, applied_count, notes, changed, saved, save_error, note? }

set_blendspace_propertiesA

Configure an existing blend space's X and (for 2D) Y axis: name, min, max, grid divisions. create_blend_space only sets X; this sets the Y axis too (and can change X after creation). On a 1D blend space the y_axis_* params are reported as an honest note and ignored. Only the supplied fields change, in one undo transaction, then the blend space is saved; values the axes already have are a success with changed=false, applied_count 0, saved=false and a note, and nothing is modified or saved. A failed save makes success false, with saved=false and save_error.

Returns: { blend_space_path, is_1d, x_axis: {name, min, max, grid}, y_axis: {name, min, max, grid}, applied_count, notes, changed, saved, save_error, note? }

set_bone_parentA

Re-parent a bone (pass empty parent_name to make it a new root).

Returns: { asset_path, bone_name, parent_name, bone_index, parent_index, updated, not_found, bone_count, saved, op: "set_bone_parent" }

set_bone_transformB

Update the local reference-pose transform of an existing bone

Returns: { asset_path, bone_name, bone_index, updated, not_found, bone_count, saved, op: "set_bone_transform" }

set_ik_bone_settingsA

Set bone-specific settings for a bone within a solver, as one undo transaction, then save the IK Rig asset; a failed save makes success false, with saved=false and save_error. Partial update (idempotent): only fields present in settings are applied; bone settings are auto-created if absent (a bone the rig skeleton lacks is an error, with nothing changed), and existing settings that already have those values give changed false, saved false and a note, with nothing saved. FullBodyIK snake_case keys: rotation_stiffness (0-1), position_stiffness (0-1), limit_x/limit_y/limit_z ("Free"/"Limited"/"Locked"), min_x, max_x, min_y, max_y, min_z, max_z, use_preferred_angles (bool), preferred_x, preferred_y, preferred_z. StretchLimb uses its live bone struct's camelCase keys (squashDirection: {x,y,z}). Only FullBodyIK and StretchLimb support per-bone settings; others return an honest error.

Returns: { ik_rig_path: string, solver_index: int, bone_name: string, success: bool, changed: bool, saved: bool, save_error?: string, note?: string }

set_ik_goal_settingsA

Set goal-specific settings for a goal connected to a solver, as one undo transaction, then save the IK Rig asset. Partial update (idempotent): only fields present in settings are applied. FullBodyIK uses snake_case keys: bone_name, chain_depth (0+), strength_alpha (0-1), pull_chain_alpha (0-1), pin_rotation (0-1). BodyMover uses its live goal struct's camelCase keys (influenceMultiplier 0-10, clamped server-side). Connect the goal first with connect_ik_goal_to_solver. Solvers without per-goal settings return an honest error. Settings that already have those values give changed false, saved false and a note, with nothing saved. A failed save makes success false, with saved=false and save_error.

Returns: { ik_rig_path: string, solver_index: int, goal_name: string, success: bool, changed: bool, saved: bool, save_error?: string, note?: string }

set_ik_retarget_chain_bonesA

Change the start bone, end bone and/or IK goal of an existing retarget chain in an IK Rig asset through the IK Rig controller (each change an undo transaction), then save the asset. Pass at least one of the three, else an error. A missing chain, a bone not in the rig skeleton or a goal_name the rig has no goal for is not an error but start_bone_set, end_bone_set or goal_set false, and that field is left unchanged. A value the chain already has is left alone; when nothing changes, changed is false, saved is false, a note says why and nothing is saved. A failed save makes success false, with saved=false and save_error. Siblings: add_ik_retarget_chain, rename_ik_retarget_chain.

Returns: { asset_path: string, chain_name: string, start_bone: string, end_bone: string, goal_name: string, start_bone_set: bool, end_bone_set: bool, goal_set: bool, changed: bool, saved: bool, save_error?: string, note?: string }

set_ik_solver_bonesA

Set the start bone and/or end bone of one solver in an IK Rig asset (0-based stack index) through the IK Rig controller, which records each change as an undo transaction, then save the asset. Pass at least one bone, else an error. An out-of-range index, a bone missing from the rig skeleton, or a start or end bone on a solver type without one is not an error: start_bone_set or end_bone_set comes back false, next to the bones read back, and nothing is stored for it. A bone the solver already has is left alone; when nothing changes, changed is false, saved is false, a note says why and nothing is saved. A failed save makes success false, with saved=false and save_error. get_ik_solver_bones reads them.

Returns: { asset_path: string, solver_index: int, start_bone: string, end_bone: string, start_bone_set: bool, end_bone_set: bool, changed: bool, saved: bool, save_error?: string, note?: string }

set_ik_solver_enabledA

Enable or disable the solver at a 0-based index of an IK Rig asset through the IK Rig controller (one undo transaction), then save the asset; enabled is read back. An out-of-range index is not an error but set_ok false, and a solver already in the requested state gives changed false: in both cases saved is false, a note says why and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, solver_index: int, enabled: bool, set_ok: bool, changed: bool, saved: bool, save_error?: string, note?: string }

set_ik_solver_settingsA

Set detailed solver-specific settings on a solver in an IK Rig, as one undo transaction, then save the asset. Partial update: only fields present in settings are applied (idempotent). FullBodyIK uses snake_case keys: root_bone, iterations (0-1000), sub_iterations (0-1000), mass_multiplier (0-10), allow_stretch (bool), root_behavior (enum string), global_pull_chain_alpha (0-1), max_angle (0-45), over_relaxation (1-2). Other solver types (Limb/Pole/BodyMover/SetTransform/StretchLimb) accept the camelCase names of their live settings struct; ClampMin/ClampMax bounds are enforced server-side. Settings that already have those values give changed false, saved false and a note, with nothing saved. A failed save makes success false, with saved=false and save_error.

Returns: { ik_rig_path: string, solver_index: int, solver_type: string, success: bool, changed: bool, saved: bool, save_error?: string, note?: string }

set_montage_blend_timesA

Set the blend-in / blend-out times (clamped to >= 0) on a UAnimMontage in an undo transaction and save it. Times the montage already has, or none given, are a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, blend_in, blend_out, applied, saved, save_error, message }

set_montage_propertiesA

Set only the supplied blend modes, auto blend out, trigger time, sync group/slot and deprecated root motion fields of a UAnimMontage in one undo step and save it; bad enum names, or no field, are refused before any change, and supplied values the montage already has are a success with changed=false, applied_count 0 and saved=false, with nothing modified or saved. For blend times use set_montage_blend_times. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, blend_mode_in, blend_mode_out, enable_auto_blend_out, blend_out_trigger_time, sync_group, sync_slot_index, root_motion: {...}, applied_count, notes, changed, saved, save_error, message }

set_montage_section_start_timeA

Set the StartTime on an existing FCompositeSection by zero-based section_index, in an undo transaction, and save it. The start time the section already has is a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, section_index, start_time, applied, saved, save_error, message }

set_montage_segment_anim_sequenceA

Rebind an existing FAnimSegment on a slot track to a different UAnimSequence (resets segment start/end times to the new sequence's range, play rate and loop count to 1 and its start position to 0) in an undo transaction and save the montage. A segment that already references that sequence with those values is a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, slot_name, segment_index, anim_sequence_path, anim_start_time, anim_end_time, applied, saved, save_error, message }

set_montage_segment_start_timeA

Set the AnimStartTime on an existing FAnimSegment by (slot_name, segment_index), clamped to [0, AnimEndTime], in an undo transaction, and save the montage. AnimEndTime is left untouched. The (clamped) start time the segment already has is a success with applied=false and saved=false, and the montage is neither modified nor saved. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, slot_name, segment_index, start_time, anim_end_time, applied, saved, save_error, message, note? }

set_morph_target_deltasA

Set vertex deltas for a morph target on a specific LOD. Each delta is a dict with keys: vertex_index (int), position_delta ({x,y,z}), normal_delta ({x,y,z}).

Returns: { morph_target_name: string, lod_index: int, deltas_set: int, total_deltas_lod0: int, saved: bool }

set_morph_target_generated_by_engineA

Flag morph targets of a skeletal mesh asset as generated by engine tools rather than imported from a source file, on every LOD, then save the mesh (a failed save is an error). The flag is only ever set, never cleared; names not on the mesh are ignored, and an empty or missing list flags every morph. When any flag changes the engine runs PreEditChange/PostEditChange on the mesh, which rebuilds it. modified says whether anything changed; flagged lists every morph now marked on LOD 0. Names come from get_skeletal_mesh_morph_targets.

Returns: { skeletal_mesh_path: string, requested_count: int, named_list: bool, modified: bool, flagged: [string], note: string }

set_motion_warping_component_search_in_animsA

Set bSearchForWindowsInAnimsWithinMontages on the UMotionWarpingComponent of an editor-world actor found by internal name (not label): when true, warping windows are also searched in animations inside montages. Marks the level dirty, not saved; returns previous and new values and changed.

Returns: { actor_name, previous_search_in_anims: bool, new_search_in_anims: bool, changed: bool }

set_motion_warping_target_bone_nameA

Set the BoneName on an existing FMotionWarpingTarget (resolves the existing Component ref).

Returns: { actor_name, warp_target_name, previous_bone_name: string, new_bone_name: string, changed: bool }

set_motion_warping_target_follow_componentA

Set bFollowComponent on an existing component-based warp target of an editor-world actor found by internal name, keeping its Component, BoneName and offsets. A missing target, or one without a Component, is an error. WarpTargets is Transient, so the change is not saved with the level.

Returns: { actor_name, warp_target_name, previous_follow: bool, new_follow: bool, changed: bool }

set_motion_warping_target_locationA

Update an existing FMotionWarpingTarget's location (and optionally rotation) by FName -- an idempotent replace-in-place. Choose this over add_warp_target_to_component when the target already exists and you only want to nudge where it points; add_warp_target_to_component is the one that CREATES a target.

Returns: { actor_name, warp_target_name, location_set, previous_count, new_count }

set_motion_warping_target_location_offsetA

Set LocationOffset (FVector) on an existing FMotionWarpingTarget (keeps BoneName/follow/rotation-offset).

Returns: { actor_name, warp_target_name, previous_x, previous_y, previous_z, new_x, new_y, new_z, changed: bool }

set_motion_warping_target_rotationA

Set the rotation of an existing warp target of an editor-world actor (found by internal name), keeping its Location. The target is rebuilt as a plain transform target, so a component-based one loses its Component, BoneName, follow flag and offsets. WarpTargets is Transient: not saved.

Returns: { actor_name, warp_target_name, previous_pitch, previous_yaw, previous_roll, new_pitch, new_yaw, new_roll, changed: bool }

set_pose_asset_base_poseA

Set which named pose of a UPoseAsset is its base pose (UPoseAsset::SetBasePoseName) in an undo transaction, then save the asset; an empty or None base_pose_name goes back to the skeleton reference pose. A name the asset does not contain is an error before anything changes, and so is a base pose the engine does not take (read back from the asset), with nothing saved. The base pose the asset already has is a success with applied=false and saved=false, and nothing is modified or saved. A failed save makes success false, with saved=false and save_error. The base pose only drives evaluation of an additive pose asset, which additive and note report. Edit poses with add_pose_to_pose_asset, rename_pose_in_pose_asset and remove_pose_from_pose_asset.

Returns: { pose_asset_path, base_pose_name, requested_name, applied, base_pose_index, is_reference_pose, additive, note, saved, save_error, message }

set_pose_search_database_schemaA

Bind a UPoseSearchSchema to a UPoseSearchDatabase (assigns the Schema field). Use it right after creating a database with no schema, or to rebind an existing one; a database without a schema cannot be indexed.

Returns: { database_path, previous_schema_path, new_schema_path, changed: bool, saved: bool }

set_pose_search_schema_mirror_data_tableA

Bind (or rebind) the UMirrorDataTable of the schema's FPoseSearchRoledSkeleton entry under role (default role when omitted). Refused when no entry has that role.

Returns: { asset_path, role, previous_mirror_data_table_path, new_mirror_data_table_path, changed, saved }

set_pose_search_schema_propertiesA

Author UPoseSearchSchema scalar tunables via reflection (partial merge + clamp). Replaces the 8 former per-field set_pose_search_schema_* setters.

Returns: { asset_path, asset_class, settings, applied_keys, changed, saved }

set_pose_search_schema_roleA

Rename the role (FName) of the schema's FPoseSearchRoledSkeleton entry under role_from (default role when omitted). Refused when new_role is already taken by another entry.

Returns: { asset_path, previous_role, new_role, changed, saved }

set_pose_search_schema_skeletonA

Bind (or rebind) the USkeleton of the schema's FPoseSearchRoledSkeleton entry under role. Idempotent by role: if a skeleton is already bound under that role it is REPLACED; if no roled entry exists for that role yet, one is created. Use add_pose_search_roled_skeleton instead when you want to ADD a second character's role without disturbing the first.

Returns: { asset_path, role, previous_skeleton_path, new_skeleton_path, changed, saved }

set_retarget_pose_bone_rotationA

Set a bone's rotation offset in the current retarget pose (euler degrees) of an IK Retargeter asset, as one undo transaction, then save the asset; the offset is read back as quat_x..quat_w. Creates a default pose if none is current. bone_name is stored as given, not checked against the skeleton. When the pose to edit is already current and already holds exactly that offset for the bone, changed is false, saved is false, a note says so and nothing is saved. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, bone_name: string, source_or_target: string, retarget_pose: string, quat_x: number, quat_y: number, quat_z: number, quat_w: number, changed: bool, saved: bool, save_error?: string, note?: string }

set_retargeter_chain_mappingA

Make source_chain drive target_chain in an IK Retargeter asset, overwriting the previous mapping, on every op whose chain mapping lists target_chain (or only the op named op_name), in one undo transaction, then save the asset. source_chain is not validated, so a misspelled name is stored as given. set_ok is false when no op lists target_chain; mapped_source is read back from the first matching op. When no op lists target_chain, or every one already maps it to source_chain, changed is false, saved is false, a note says why and nothing is saved. A failed save makes success false, with saved=false and save_error. get_ik_retargeter_info shows the per-op mappings.

Returns: { asset_path: string, source_chain: string, target_chain: string, mapped_source: string, set_ok: bool, changed: bool, saved: bool, save_error?: string, note?: string }

set_retargeter_op_settingsA

Partial-merge a retarget op's live settings struct (only the JSON fields present are written -> idempotent), and optionally toggle the op enabled flag, as one undo transaction, then save the asset. Settings keys match get_retargeter_op_info (first char lower-cased, e.g. lODThreshold). Numeric ClampMin/ClampMax metadata is enforced after the merge. The optional enabled flag is applied via the controller. The payload echoes the read-back settings. When neither is given, or the op already has those settings and that enabled state, changed is false, saved is false, a note says why and nothing is saved. An out-of-range op_index is an error. A failed save makes success false, with saved=false and save_error.

Returns: { asset_path: string, op_index: int, op_name: string, op_type: string, enabled: bool, settings: object, changed: bool, saved: bool, save_error?: string, note?: string }

set_rig_control_limitsA

Set a scalar Control Rig control's min/max limits (Float/ScaleFloat/Integer). Enables the limit array for the control type and sets MinimumValue/MaximumValue type-correctly; once enabled, set_rig_control_value clamps via ApplyLimits. Verified read-back.

Returns: { asset_path: string, control_name: string, control_type: string, min: number, max: number, limit_enabled: bool, saved: bool, save_error?: string }

set_rig_control_settingsA

Edit an existing Control Rig control's shape/gizmo/color/limit-draw settings (the bits add_rig_control can't set afterwards). Read-modify-write: reads the control's FRigControlSettings, applies the provided fields, writes back via URigHierarchyController::SetControlSettings, recompiles + saves, and returns the verified read-back. Only the supplied fields change.

Returns: { asset_path: string, control_name: string, settings_applied: { display_name, shape_name, shape_color: [float], shape_visible, draw_limits }, applied_count: int, saved: bool, save_error?: string }

set_rig_control_shape_transformA

Set the local shape (gizmo) transform of an existing Control Rig control. Reads the current local shape transform, overrides only the supplied location/rotation/scale, writes back via URigHierarchy::SetControlShapeTransform, recompiles + saves, and returns the verified read-back. This positions the manipulator gizmo relative to the control, independent of the control's value.

Returns: { asset_path: string, control_name: string, shape_transform: { location: [float], rotation: [float], scale: [float] }, applied_count: int, saved: bool, save_error?: string }

set_rig_control_valueA

Set a Control Rig control's pose value (Initial + Current), type-correct per the control's ERigControlType. add_rig_control only seeds the identity value. SetControlValue applies the control's limits, so a value outside an enabled min/max is clamped (set limits first with set_rig_control_limits). Verified read-back.

Returns: { asset_path: string, control_name: string, control_type: string, value: any, saved: bool, save_error?: string }

set_rigvm_pin_defaultA

Set the default value of a pin in the main RigVM graph of a Control Rig Blueprint (URigVMController::SetPinDefaultValue, no undo entry), then compile and save it. success reflects the save even when the write failed: check set, pin_found and current_value, which is read back.

Returns: { asset_path: string, pin_path: string, value: string, set: bool, pin_found: bool, current_value: string, saved: bool, save_error: string }

set_skeletal_mesh_allow_cpu_accessA

Set bAllowCPUAccess on every LOD of a skeletal mesh. Used to keep vertex/skin data resident for FX sampling or other CPU work.

Returns: { skeletal_mesh_path: string, b_allow: bool, applied_lods: int, saved: bool }

set_skeletal_mesh_anim_classA

Repoint a Blueprint's skeletal mesh component AnimClass to a (fork) AnimBlueprint. Also handles the INHERITED native Character Mesh, which is not in the SCS and which the generic component-property setters cannot reach: it writes the CDO component archetype so spawned instances inherit the new AnimClass. Also sets AnimationMode=AnimationBlueprint.

Returns: { blueprint, component, anim_class, previous_anim_class, applied, wrote_cdo_archetype, saved }

set_skeletal_mesh_lod_build_settingsA

Change the stored build settings of one LOD of a skeletal mesh asset, only the fields you pass, and save the mesh. The mesh is not rebuilt here, so the settings take effect at its next build or reimport; a failed save returns an error. Returns settings_applied.

Returns: { lod_index: int, settings_applied: {...}, saved: bool }

set_skeletal_mesh_lod_reduction_settingsA

Author a LOD's FSkeletalMeshOptimizationSettings (ReductionSettings) — the data bake_skeletal_mesh_lod consumes, making the bake steerable instead of running with defaults. Partial update (idempotent): only fields present are written. Enums are by name (full "SMTC_NumOfTriangles" or short "NumOfTriangles"). termination_criterion (SMTC_*) and reduction_method (SMOT_*) are DISTINCT.

Returns: { lod_index: int, settings_applied: {...}, saved: bool }

set_skeletal_mesh_lod_screen_sizeA

Set ScreenSize.Default (the screen size at which this LOD switches in) of one LOD of a skeletal mesh asset. Marks the mesh dirty but does NOT save it, so follow with save_asset; per-platform overrides are left as they are. Returns old_screen_size and screen_size.

Returns: { skeletal_mesh_path: string, lod_index: int, old_screen_size: float, screen_size: float, applied: bool }

set_skeletal_mesh_lod_settingsA

Set the remaining flat per-LOD scalars/enums of FSkeletalMeshLODInfo that no other setter covers (hysteresis, CPU access, morph error tolerance, skin cache usage, mesh deformer, prioritization weight). Partial update (idempotent): only fields present are written.

Returns: { lod_index: int, settings_applied: {...}, saved: bool }

set_skeletal_mesh_material_slotA

Assign a material to an existing material slot of a skeletal mesh ASSET (writes FSkeletalMaterial.MaterialInterface in USkeletalMesh::GetMaterials()). Address the slot by slot_index OR slot_name (exactly one). Never auto-grows the slot array.

Returns: { skeletal_mesh_path: string, slot_index: int, slot_name: string, material_path: string, saved: bool }

set_skeletal_mesh_min_lodB

Set the platform-wide forced-min-LOD bias on a skeletal mesh.

Returns: { skeletal_mesh_path: string, old_min_lod: int, min_lod: int, lod_count: int, applied: bool }

set_skeletal_mesh_section_cast_shadowB

Set the cast shadow flag on a specific section of a skeletal mesh LOD.

Returns: { lod_index: int, section_index: int, cast_shadow: bool, saved: bool }

set_skeletal_mesh_section_recompute_tangentB

Set the recompute tangent flag on a specific section of a skeletal mesh LOD.

Returns: { lod_index: int, section_index: int, recompute_tangent: bool, saved: bool }

set_skeletal_mesh_section_visible_in_ray_tracingA

Toggle a section's bVisibleInRayTracing flag on a specific skeletal mesh LOD.

Returns: { lod_index: int, section_index: int, b_visible: bool, saved: bool }

set_skeletal_mesh_socket_parentA

Re-parent an existing socket on a skeletal mesh to a different bone. Validates the bone exists in the reference skeleton.

Returns: { socket_name: string, parent_bone_name: string, skeletal_mesh_path: string, reparented: bool }

set_skeletal_mesh_socket_transformA

Set the local transform (relative to parent bone) of a socket on a skeletal mesh. All three of location/rotation/scale are optional; only fields present are written.

Returns: { socket_name: string, skeletal_mesh_path: string, applied: {location, rotation, scale}, location_x: float, location_y: float, location_z: float, rotation_pitch: float, rotation_yaw: float, rotation_roll: float, scale_x: float, scale_y: float, scale_z: float }

setup_foot_ikA

Add a Leg IK node (UAnimGraphNode_LegIK) to the top-level AnimGraph of an Animation Blueprint, or reuse the first one already there, bind the feet into its LegsDefinition, then mark the blueprint structurally modified and save it without compiling. Leg 0 gets left_foot_bone and leg 1 right_foot_bone as the FK foot bone; a leg's IK target bone is set to the same bone when it is unset or the leg's foot changes, so the node compiles but has no effect until each IK target names an IK bone (set_anim_graph_node_property on LegsDefinition with the returned node_id); legs beyond the first two and the other leg settings are kept. Bones the target skeleton lacks are an error and nothing is written. The node is left unwired: connect it with connect_anim_graph_pins. Idempotent; refused while PIE runs unless force=true.

Returns: { anim_blueprint_path, node_id, left_foot_bone, right_foot_bone, legs: [{ fk_foot_bone, ik_foot_bone, num_bones_in_limb }], bones_checked_against, ik_node_count, already_existed, saved, save_error }

sort_montage_segmentsB

Sort a montage slot track's segments by start time ascending. A failed save makes success false, with saved=false and save_error.

Returns: { montage_path, slot_name, segment_count, applied, saved, save_error, message }

stop_animationA

Stop montage playback on a skeletal mesh component with Montage_Stop and a 0.25 s blend-out: only montage_path when given, otherwise every active montage. Editor world unless the world param says otherwise; an unknown montage_path is an error. was_playing and playing cover any montage.

Returns: { component_name: string, was_playing: bool, playing: bool, success: bool, montage_path: string?, montage_name: string?, world: string, world_name: string|null, world_package: string|null, world_type: string|null, net_mode: string|null, pie_instance: number }

validate_anim_state_machineA

Check a state machine of an Animation Blueprint by node counts, without compiling or changing it: no states is an error, one an info, several without transitions a warning. state_count counts states only (conduits and aliases excluded), transition_count the transition nodes; compile_anim_blueprint is the check that the machine compiles.

Returns: { is_valid, errors[], warnings[], info[], state_count, transition_count }

wire_aim_offsetB

Create a UBlendSpace1D asset for aim-offset blending (yaw or pitch axis). Idempotent on re-run.

Returns: { asset_path, axis_name, min_value, max_value, num_grid_points, already_existed, saved }

add_asset_to_collectionB

Adds an asset to an existing collection and reads back its object count. must match the share type the collection was created with.

Returns: { collection_name: string, share_type: string, asset_path: string, added: bool, verified: bool, object_count: number }

add_static_mesh_socketA

Add a new socket to a UStaticMesh asset (package or object path) with an optional relative location, rotation, scale and tag, then save the mesh; no undo transaction. A socket_name the mesh already has is an error, and so is a location, rotation or scale that is not three numbers; both are checked before the mesh is touched. A failed save is an error, yet the socket stays on the mesh in memory. Edit an existing socket with set_static_mesh_socket_transform or rename_static_mesh_socket; list them with get_static_mesh_sockets; skeletal meshes use add_skeletal_mesh_socket.

Returns: { socket_name, socket_count, location_x, location_y, location_z, scale_x, scale_y, scale_z, tag }

bulk_rename_assetsA

Rename/move multiple assets in one IAssetTools::RenameAssets batch, with per-item disk verification instead of the batch bool. Guards: refuses while PIE is active; refuses paths under readonly_roots (default: the project's Read Only Content Roots setting) on BOTH the source and the destination; pre-detects the native-CDO reference case that makes the engine's FMessageDialog auto-cancel the whole batch (would_block_on_modal) and does NOT call RenameAssets in that case. Also reports referencer packages left DIRTY -- PerformAssetRename discards its FailedPackages list unless UE source control is connected, so a referencer (typically OFPA) can be left unwritten while RenameAssets still returns true.

Returns: { dry_run: bool, readonly_roots: [string], readonly_roots_explicit: bool, planned_count: int, renamed_count: int, failed_count: int, skipped_count: int, batch_api_result: bool|null, would_block_on_modal: bool, cdo_references: [object], soft_scan_is_approximate: bool, referencer_packages_dirty: [object], results: [object] }

clear_and_fill_render_targetA

Fill an entire render target with a solid color via the canvas. drawn is false, and the call fails, when the canvas draws nothing (no white texture or a zero size).

Returns: { render_target_path: string, drawn: bool, canvas_width: number, canvas_height: number, fill_color: [number] }

clear_render_targetA

Clear a render target to a solid color via ClearRenderTarget2D. Render-target contents live on the GPU only, so nothing is saved or undoable. cleared is false, and the call fails, when the engine skips the clear: a render target without a resource, which is every render target in a process that cannot render (-nullrhi, a commandlet).

Returns: { render_target_path: string, cleared: bool, clear_color: [number] }

compare_asset_versionsA

Apply the binary ref-scan of scan_uasset_refs to the SAME asset (rel_path) across N external Content roots, reporting ref-count / size / mtime (and optional pattern-match count) per root so you can tell an incomplete (stub) copy from the complete one at a glance.

Returns: { rel_path: string, pattern: string, roots: [{root, full_path, exists, size_bytes, modified, ref_path_unique, ref_path_occurrences, match_unique, match_occurrences}], most_complete_root: string, likely_stub_root: string, message: string }

create_collectionB

Creates a static Content Browser collection (idempotent). Uses the UE 5.7 project ICollectionContainer. If the collection already exists a stable payload is returned (already_existed=True). "Private", or "Shared".

Returns: { collection_name: string, share_type: string, created: bool, already_existed: bool, exists: bool }

create_editable_static_meshA

Copy a UStaticMesh (default /Engine/BasicShapes/Cube) into a new asset at package_path/static_mesh_name with StaticDuplicateObject, creating the folder if needed, and save it, so an engine or other read-only mesh can be edited as a copy; the source is not modified and there is no undo. Idempotent: a static mesh already at that path is returned untouched with created=false, whatever its source. A source that does not load, a name taken by another asset class or a failed save is an error. duplicate_asset copies any asset type inside its own folder.

Returns: { asset_path, static_mesh_name, source_mesh, created }

create_render_target_2dA

Create a UTextureRenderTarget2D asset at package_path/name with the given size and format, black clear color, and save it. An existing one there is returned as is: width, height and format are then ignored (already_exists:true). Returns asset_path, width, height, format and pixel_format.

Returns: { render_target_name: string, asset_path: string, created: bool, already_exists: bool, saved: bool, width: int, height: int, format: string, pixel_format: string, format_warning: string, save_error: string }

create_render_target_2d_arrayA

Creates a persisted UTextureRenderTarget2DArray. Wraps UTextureRenderTarget2DArray::Init(SizeX, SizeY, Slices, Format) and saves the asset to disk. Re-running deletes and rebuilds the asset deterministically. format accepts one of "B8G8R8A8"/"BGRA8" (default), "FloatRGBA"/"RGBA16F", "RGBA32F", "R16F".

Returns: { render_target_name: string, asset_path: string, size_x: int, size_y: int, slices: int, format: string, created: bool, saved: bool, save_error?: string }

create_render_target_cubeA

Creates a persisted UTextureRenderTargetCube (6-face cube render target). Wraps UTextureRenderTargetCube::Init(SizeX, Format) when a format is given, or InitAutoFormat(SizeX) otherwise, and saves the asset to disk. Re-running deletes and rebuilds the asset deterministically. format accepts one of "B8G8R8A8"/"BGRA8", "FloatRGBA"/"RGBA16F", "RGBA32F". When omitted the format is auto-derived (InitAutoFormat).

Returns: { render_target_name: string, asset_path: string, size_x: int, format: string, created: bool, saved: bool, save_error?: string }

create_static_texture_from_render_targetA

Bakes a UTexture2D from an existing UTextureRenderTarget2D (editor only). Wraps UKismetRenderingLibrary::RenderTargetCreateStaticTexture2DEditorOnly and saves the resulting static texture to disk. Re-running deletes and rebuilds the asset deterministically. render_target_path accepts either short "/Game/MyGame/RT_Example" or fully-qualified "...RT_Example.RT_Example" asset paths.

Returns: { texture_name: string, asset_path: string, render_target_path: string, created: bool, saved: bool, width: int, height: int, format: string, save_error?: string }

create_texture_2d_arrayA

Creates a persisted UTexture2DArray from slices (no external file import). If source_texture_paths is given, those UTexture2D assets are loaded into the array's SourceTextures; otherwise slice_count small solid-color slices of size x size are generated. The array Source is then built via UTexture2DArray::UpdateSourceFromSourceTextures(true) and the asset is saved. source_texture_paths is an optional array of UTexture2D asset paths used as the array's slices. Each must have a valid editor source. If omitted, slices are generated. size is the per-slice pixel size (clamped 1..2048).

Returns: { texture_array_name: string, asset_path: string, width: int, height: int, num_slices: int, format: string, created: bool, saved: bool, save_error?: string }

create_texture_2d_from_dataA

Creates a persisted UTexture2D filled with a solid color (no external file). Allocates the editor source (FTextureSource::Init, BGRA8), fills every pixel with fill_color, calls UpdateResource, registers the asset and saves it to disk. Re-running deletes and rebuilds the asset deterministically. fill_color is an [R, G, B, A] array of 0-255 byte values (default = opaque white).

Returns: { texture_name: string, asset_path: string, created: bool, saved: bool, width: int, height: int, format: string, has_source: bool, fill_color: [int, int, int, int], save_error?: string }

delete_collectionA

Destroys a Content Browser collection (idempotent; inverse of create_collection). Uses the UE 5.7 project ICollectionContainer::DestroyCollection. If the collection is already absent a stable payload is returned (already_absent=True). "Private", or "Shared".

Returns: { collection_name: string, share_type: string, destroyed: bool, already_absent: bool, exists: bool }

diff_content_treesA

Compare two Content folders (project vs external, fork vs source) WITHOUT loading the editor: reports assets added/removed/changed keyed by relative path, using file size and (optionally) a whole-file MD5 content hash. Verifies a Migrate or audits a fork on disk. Each tree may be a disk directory OR a /Game|/Engine mount path.

Returns: { tree_a: string, tree_b: string, dir_a: string, dir_b: string, only_in_a: [string], only_in_b: [string], changed: [{rel, size_a, size_b, hash_a, hash_b, reason}], identical_count: int, only_in_a_count: int, only_in_b_count: int, changed_count: int, message: string }

draw_line_to_render_targetA

Draw a line into a render target via the canvas. drawn is false, and the call fails, when start and end are the same point (the canvas skips a zero-length line).

Returns: { render_target_path: string, drawn: bool, thickness: number, start: [number], end: [number] }

draw_material_to_render_targetA

Render a material full-screen quad into a render target. drawn is false, and the call fails, when the engine skips the draw: a process that cannot render (-nullrhi, a commandlet) or a render target without a resource.

Returns: { render_target_path: string, material_path: string, drawn: bool }

draw_material_to_render_target_regionA

Draw a material as a rectangle onto a UTextureRenderTarget2D asset in one canvas pass in the editor world: position and size in render-target pixels from the top-left (size defaults to the whole target), full 0-1 UVs. It composites over the existing pixels by the material's blend mode: nothing is cleared, saved or undoable, and render-target contents live on the GPU only, so keep them with create_static_texture_from_render_target or export_render_target. A missing render target or material is an error; drawn is false, and the call fails, when a width or height that is not positive draws nothing. For a full-target pass use draw_material_to_render_target; for a texture, draw_texture_to_render_target.

Returns: { render_target_path: string, material_path: string, drawn: bool, position: [number], size: [number] }

draw_text_to_render_targetA

Draw a string onto a UTextureRenderTarget2D asset in one canvas pass in the editor world, in the engine's medium font (no font choice), tinted by color and scaled by scale, with position the text's top-left in render-target pixels. The text blends over the existing pixels: nothing is cleared, saved or undoable, and render-target contents live on the GPU only, so keep them with create_static_texture_from_render_target or export_render_target. A missing render target is an error; drawn is false, and the call fails, when nothing was drawn (an empty text, or no engine font: font_resolved says whether one was found). Related: draw_texture_to_render_target, draw_line_to_render_target, clear_and_fill_render_target.

Returns: { render_target_path: string, text: string, drawn: bool, font_resolved: bool, position: [number] }

draw_texture_to_render_targetA

Draw a texture as a rectangle onto a UTextureRenderTarget2D asset in one canvas pass in the editor world: position and size in render-target pixels from the top-left (size defaults to the whole target), full 0-1 UVs, tinted by color. It alpha-blends over the existing pixels: nothing is cleared, saved or undoable, and render-target contents live on the GPU only, so keep them with create_static_texture_from_render_target or export_render_target. A missing render target or texture is an error; drawn is false, and the call fails, when a width or height that is not positive draws nothing. For a material use draw_material_to_render_target_region.

Returns: { render_target_path: string, texture_path: string, drawn: bool, position: [number], size: [number] }

evaluate_curve_at_timeA

Evaluate a curve asset at a given time. Loads a UCurveFloat / UCurveVector / UCurveLinearColor and evaluates it at the requested time. For multi-channel curves (Vector=3, LinearColor=4) the optional channel selects which component the scalar 'value' field reports; the full component array is always returned in 'values'.

Returns: { curve_path: string, curve_class: string, time: float, curve_type: string, num_channels: int, channel: int, value: float, values: [float], vector: {x,y,z}, color: {r,g,b,a} }

export_render_targetA

Export a render target to an image file on disk: PNG, except an RGBA16f or RGBA32f render target, which writes HDR when filename ends in .hdr and EXR otherwise. exported is measured on disk: the file must exist, hold bytes and have been written by this call. It is false, and the call fails saying why, for a render target without a resource (every render target in a process that cannot render: -nullrhi, a commandlet), an invalid path, a file that cannot be opened for writing, or an image that cannot be read back; an empty file left by a failed export is removed when the call created it.

Returns: { render_target_path: string, output_directory: string, filename: string, file_path: string, exported: bool, file_exists: bool, file_size_bytes: number }

generate_asset_thumbnailA

Render and cache an asset's thumbnail (or report the existing cached one). When the editor can render (FApp::CanEverRender() and the RHI is initialized), this generates a fresh thumbnail via ThumbnailTools and caches it into the package's thumbnail map. When rendering is unavailable, or the object type has no thumbnail renderer, it honestly reports the existing cached thumbnail state.

Returns: { asset_path: string, object_path: string, asset_class: string, rendered: bool, has_thumbnail: bool, width: int, height: int, compressed_bytes: int, message: string }

get_asset_by_nameA

Retrieve ONE asset by exact name and return its identity (name, class, object path, package, is_loaded, file size) plus, with load_full_data, type-specific detail: a Blueprint's parent class / compile status / generated class, a StaticMesh's section-vertex-LOD counts, whether a material is an instance. WARNING: When the name is ambiguous it still resolves to the FIRST match and merely lists the rest in ambiguous_matches -- check that field, or use resolve_asset_by_name, which refuses to pick for you. The fallback name scan only covers /Game, so an /Engine or plugin-mount asset must be addressed by its full package name. Use get_assets_by_names for a batch, get_asset_metadata for registry tags, and search_assets_by_pattern when you only know part of the name.

Returns: { name: string, class: string, path: string, package: string, is_loaded: bool, file_size_bytes?: int, file_size_kb?: number, parent_class?: string, is_compiled?: bool, is_valid?: bool, generated_class?: string, num_sections?: int, num_vertices?: int, num_lods?: int, is_material_instance?: bool, ambiguous_matches?: [string] }

get_asset_dependencies_recursiveA

Recursively walk an asset's package dependencies via the Asset Registry. Breadth-first, deduplicated, capped at max_depth (default 3). Each returned dependency records the depth at which it was first reached (1 == direct).

Returns: { asset_path: string, package_name: string, max_depth: int, dependency_type: string, dependencies: [{path, depth}], count: int }

get_asset_disk_sizeB

Get the on-disk file size of an asset's package (.uasset/.umap). Resolves the package filename via FPackageName::LongPackageNameToFilename and stats it with IFileManager::FileSize.

Returns: { asset_path: string, package_name: string, file_path: string, extension: string, size_bytes: number, size_kb: number, size_mb: number, exists_on_disk: bool, message: string }

get_asset_file_sizeA

Read the ON-DISK size of an asset's .uasset in bytes, KB and MB, plus the absolute file path it resolved to -- the measurement for a disk-budget question ("what is costing the 491 MB in this import?"). WARNING: Size is NOT a proxy for content or integrity: a DataTable that GREW by 5 KB had lost 46 of its 48 references. To measure content use get_data_table_info, read_data_table_row_complex or get_asset_dependencies; for in-memory cost use get_asset_memory_usage. Resolution matches get_asset_by_name (full package name first, then a /Game-only exact-name scan, first hit wins with the rest in ambiguous_matches).

Returns: { asset_name: string, asset_path: string, file_path: string, file_size_bytes: int, file_size_kb: number, file_size_mb: number, file_exists: bool, asset_class: string, ambiguous_matches?: [string] }

get_asset_import_dataB

Read an asset's UAssetImportData: source filename(s) and import timestamp. Returns has_import_data, source_file (first resolved filename), the full source_files list (relative + resolved filename + import_time), and source_file_count.

Returns: { asset_path: string, asset_class: string, has_import_data: bool, source_file: string, source_files: [{relative_filename, resolved_filename, import_time}], source_file_count: int, import_time: string }

get_asset_last_modifiedA

Read the .uasset file's last-modified timestamp (formatted string + Unix epoch) and how old it is in days and hours -- "was this asset actually written to disk when I saved it?", the disk-side oracle for a save whose return value claimed success. WARNING: It is a FILE timestamp: an asset edited in memory but not saved reports its old date, and Unreal does not distinguish creation from modification (the tool reads the same stamp for both). Use list_assets_modified_since to sweep a whole folder by date, and list_dirty_packages for unsaved-in-memory changes. Resolution matches get_asset_by_name (full package name first, then a /Game-only exact-name scan, first hit wins with the rest in ambiguous_matches).

Returns: { asset_name: string, asset_path: string, file_path: string, last_modified: string, last_modified_timestamp: int, file_exists: bool, asset_class: string, age_days: number, age_hours: number, ambiguous_matches?: [string] }

get_asset_metadataA

Read an asset's Asset Registry TAGS (the indexed key/value pairs an asset publishes -- parent class, mesh stats, fork-lineage tags, ...) together with its name, class, object path and package. WARNING: its asset_name is NOT a name: the tool literally prefixes "/Game/" to whatever you pass, so it must be a path RELATIVE TO /Game ("MyGame/Systems/Foo/BP_Foo.BP_Foo"), never a bare asset name and never an absolute "/Game/..." path -- and it LOADS the asset to resolve it. Use get_assets_metadata_batch for many paths at once, get_asset_by_name for identity from a bare name, and get_assets_by_tag to search BY a tag value instead of reading the tags of one asset.

Returns: { name: string, class: string, path: string, package: string, asset_class_path?: string, package_path?: string, tags?: [{ name, value }] }

get_asset_metadata_tagsA

Reads all editor metadata tags (UMetaData) of an asset. Wraps UEditorAssetLibrary::GetMetadataTagValues and returns each tag as a {key, value} pair. (Distinct from get_asset_metadata, which reads asset registry data instead of the asset's stored metadata tags.)

Returns: { asset_path: string, tags: [{ key: string, value: string }], tag_count: number }

get_asset_thumbnailA

Report whether an asset is of a type that CAN carry a thumbnail, alongside its resolved object path, class and loaded state. WARNING: has_thumbnail is a CLASS test, not a lookup of stored thumbnail bytes: it is true for any StaticMesh, Material, Texture, Blueprint, SkeletalMesh or Level and false for everything else, whether or not a thumbnail was ever rendered -- and it returns no image data at all. To actually see something rendered, use generate_asset_thumbnail or capture_viewport. Resolution matches get_asset_by_name (full package name first, then a /Game-only exact-name scan, first hit wins with the rest in ambiguous_matches).

Returns: { asset_name: string, asset_path: string, has_thumbnail: bool, asset_class: string, asset_loaded: bool, asset_class_name?: string, ambiguous_matches?: [string] }

get_assets_by_namesA

Batch variant of get_asset_by_name: resolve N asset names in ONE round-trip instead of N calls, returning per entry a found flag plus that asset's identity (class, object path, package, is_loaded) or the error that stopped it. Delegates to get_asset_by_name literally, so it inherits both its /Game-only fallback scan and its ambiguous_matches transparency -- an ambiguous name still resolves to the first hit, so check that field per entry. Use get_assets_metadata_batch when you want registry TAGS rather than identity.

Returns: { requested_count: int, resolved: [{ asset_name, found: bool, name?, class?, path?, package?, is_loaded?, ambiguous_matches?, ... (same fields as get_asset_by_name when found) }] }

get_assets_by_tagA

Search assets BY an Asset Registry tag (FARFilter::TagsAndValues), server-side and metadata-only -- it never force-loads anything. This is the only tool here that queries by tag rather than by name, path or type: "every asset carrying the fork-origin tag (mcp.forkOrigin by default)", "every Blueprint whose ParentClass tag is X". It is also the general-class search that get_assets_by_type cannot do, since class_filter resolves ANY class (with subclasses) instead of five hardcoded ones. Search by class alone by pairing class_filter with a tag every asset of that class publishes; use get_asset_metadata to read the tags OF one asset rather than search by them.

Returns: { tag_name: string, tag_value: string, folder_path: string, recursive: bool, class_filter: string, assets: [{ name, path, class, package }], count: int, total_found: int, max_results: int, results_truncated: bool }

get_assets_by_typeA

List every asset of a CLASS under a content path, with name, object path, class, package and is_loaded, plus total_found and results_truncated. Takes any resolvable class -- "DataTable", "NiagaraSystem", "LandscapeGrassType", a "/Script/Module.Class" path -- matched WITH its subclasses, plus five shortcuts kept for convenience: "Blueprint", "StaticMesh", "Texture" (Texture2D exactly), "Sound" (SoundWave exactly) and "Material", which is the one that earns its keep by grouping Material + MaterialInstanceConstant + MaterialInstanceDynamic. Searches /Game by default and any mount via package_path (/Engine, /Water, plugin content). Sister tools: get_assets_in_folder to enumerate a directory whatever the class, search_assets_by_pattern to search by NAME, get_assets_by_tag to search by an Asset Registry tag.

Returns: { assets: [{ name, path, class, package, is_loaded }], count: int, total_found: int, asset_type: string, package_path: string, max_results: int, results_truncated: bool }

get_assets_in_folderA

Enumerate every asset under a content FOLDER (recursively by default), each with name, object path, class, package and is_loaded, plus total_found so you can tell a truncated listing from a complete one. The "what is actually in this directory?" inventory -- metadata only, it never loads an asset. Reaches any mounted content root, not just /Game. Pick this over search_assets_by_pattern when you know WHERE to look rather than what the name contains, over get_assets_by_type when you want everything regardless of class, and over resolve_asset_by_name when you do not have an exact name at all.

Returns: { assets: [{ name, path, class, package, is_loaded }], count: int, total_found: int, folder_path: string, recursive: bool, max_results: int, results_truncated: bool }

get_assets_metadata_batchA

Batch variant of get_asset_metadata: read the Asset Registry tags of N assets in ONE round-trip instead of N calls, returning per entry a found flag plus the same fields get_asset_metadata emits (or an error string). It runs get_asset_metadata for each entry, so it inherits its path semantics exactly -- including the trap that each entry is prefixed with "/Game/", so entries must be paths RELATIVE to /Game, never bare names and never absolute "/Game/..." paths. Use get_assets_by_names for identity/type info from bare NAMES instead of tags.

Returns: { requested_count: int, processed_count: int, results_truncated: bool, results: [{ asset_path, found: bool, name?, class?, path?, package?, asset_class_path?, package_path?, tags?, error? }] }

get_collection_assetsA

List the object paths of the assets directly in one Content Browser collection (child collections are not included), without changing anything. The collection is looked up by collection_name within share_type, default Local; an unrecognized share_type also falls back to Local, and a name not found under that share type is an error. get_collections lists every collection with its share_type. Returns assets and asset_count; change membership with add_asset_to_collection or remove_asset_from_collection.

Returns: { collection_name: string, share_type: string, assets: [string], asset_count: number }

get_collectionsA

List every Content Browser collection of the project container, of every share type, without changing anything: name and share_type of each (the share_type that get_collection_assets and the other collection tools need), plus collection_count. Errors when the collection manager is unavailable.

Returns: { collections: [{ name: string, share_type: string }], collection_count: number }

get_reference_pathA

Find the shortest reference CHAIN through the AssetRegistry dependency graph: with from, the shortest from -> ... -> target (walking dependencies); without from, the shortest chain from a root (a package nothing references) DOWN to target (walking referencers) -- i.e. 'what keeps target alive / why is it undeletable'. get_asset_referencers gives the direct edges; this gives the PATH.

Returns: { target: string, target_package: string, from: string, dependency_type: string, found: bool, reached_root: bool, chain: [string], chain_length: int, direct_referencers: [string], direct_referencer_count: int, message: string }

get_render_target_2d_array_infoA

Read metadata for a UTextureRenderTarget2DArray asset (size, slice count, format). Metadata-only, no pixel readback.

Returns: { render_target_name: string, asset_path: string, width: int, height: int, slices: int, pixel_format: string, is_hdr: bool, is_srgb: bool }

get_render_target_cube_infoA

Read metadata for a UTextureRenderTargetCube asset (face size, mip count, format). Metadata-only, no pixel readback.

Returns: { render_target_name: string, asset_path: string, size: int, num_mips: int, pixel_format: string, is_hdr: bool, is_srgb: bool, auto_generate_mips: bool }

get_render_target_infoA

Read the metadata of a UTextureRenderTarget2D asset without reading pixels or changing it: width, height, format (RTF_*), pixel_format and is_srgb. For 2D-array or cube render targets use get_render_target_2d_array_info or get_render_target_cube_info; export_render_target writes the image to disk.

Returns: { render_target_name: string, asset_path: string, width: int, height: int, format: string, pixel_format: string, is_srgb: bool }

get_static_mesh_infoA

Get detailed info about a static mesh: LODs, verts, materials (with slots), sockets, nanite, collision, bounds.

Returns: { static_mesh_path, num_lods, num_verts_lod0, num_materials, num_sockets, materials: [{slot_index, slot_name, material_path}], collision_complexity, nanite_enabled, bounds_origin_x, bounds_origin_y, bounds_origin_z, bounds_extent_x, bounds_extent_y, bounds_extent_z, sphere_radius }

get_static_mesh_lightmapB

Read lightmap resolution and lightmap UV coordinate index of a static mesh.

Returns: { static_mesh_path, lightmap_resolution, lightmap_coordinate_index }

get_static_mesh_sectionsB

Get section-level info for all LODs of a static mesh (shadow, collision, ray tracing flags).

Returns: { lod_index, section_index, cast_shadow, collision_enabled, visible_in_ray_tracing, static_mesh_path, sections, total_sections }

get_static_mesh_socketsA

List all sockets of a static mesh with transform and tag.

Returns: { static_mesh_path, socket_count, sockets: [{name, location:{x,y,z}, rotation:{pitch,yaw,roll}, scale:{x,y,z}, tag}] }

get_texture_array_infoA

Reads metadata for a UTexture2DArray asset. texture_array_path accepts short "/Game/MyGame/T_Array" or fully-qualified "...T_Array.T_Array" asset paths.

Returns: { texture_array_name: string, asset_path: string, width: int, height: int, num_slices: int, format: string, has_source: bool, source_texture_count: int }

get_texture_infoA

Reads metadata for a UTexture2D asset. texture_path accepts short or fully-qualified "/Game/MyGame/T_Example.T_Example" asset paths.

Returns: { texture_name: string, asset_path: string, width: int, height: int, format: string, srgb: bool, compression: string, lod_group: string, has_source: bool, num_mips: int, mip_gen_settings: string }

import_sound_fileA

Import an external WAV file into a USoundWave asset. Uses the legacy USoundFactory (AudioEditor module) path, no Interchange. The new sound wave is saved to disk and verified by loading it back; the response reports the resulting asset_path, duration (seconds) and num_channels.

Returns: { file_path: string, package_path: string, asset_path: string, asset_name: string, duration: float, num_channels: int, imported: bool }

import_texture_fileA

Import an external image file (PNG/JPG/TGA/...) into a UTexture2D asset. Uses the legacy UTextureFactory path (no Interchange). The new texture is saved to disk and verified by loading it back; the response reports the resulting asset_path, width and height.

Returns: { file_path: string, package_path: string, asset_path: string, asset_name: string, width: int, height: int, imported: bool }

ingest_external_uassetsA

Copy .uasset/.uexp/.ubulk/.umap from an EXTERNAL Content tree into THIS project, preserving each file's path relative to its Content root, then register the new packages with IAssetRegistry::ScanPathsSynchronous(bForceRescan) and sweep object redirectors under the destination. Fills the gap that migrate_assets only EXPORTS and import_asset is FBX/PNG-only. HEAVY: touches project Content on disk + mutates the registry -- run with confirmation.

Returns: { source_dir: string, content_root: string, dest_root: string, dest_dir: string, files_copied: int, files_skipped: int, files_failed: int, scanned_paths: [string], redirectors_fixed: int, copied: [{src, dest, package_path}], message: string }

list_assets_modified_sinceA

List package files (.uasset/.umap) under a content path whose ON-DISK mtime is newer than a timestamp -- the find -newermt recipe for isolating an UE Migrate set or a session's changes, but returning /Game package names. Enumerates the filesystem (so it catches just-migrated assets the registry may not have indexed yet).

Returns: { path: string, dir: string, since: string, count: int, truncated: bool, total_matched: int, assets: [{package_name, file_path, modified, size_bytes}], message: string }

reimport_assetA

Reimport an asset from its recorded source file via FReimportManager (legacy). Works on any asset that carries UAssetImportData (e.g. a texture or sound that was imported from a file on disk). Runs fully automated (no dialogs). Returns can_reimport, reimported, and the recorded source_files.

Returns: { asset_path: string, can_reimport: bool, reimported: bool, source_files: [string] }

remove_asset_from_collectionA

Removes an asset from a collection and reads back its object count (idempotent; inverse of add_asset_to_collection). If the asset is already absent from the collection a stable payload is returned (already_absent=True). must match the share type the collection was created with.

Returns: { collection_name: string, share_type: string, asset_path: string, removed: bool, already_absent: bool, verified: bool, object_count: number }

remove_render_target_2dA

Delete a render target asset, but only after loading it and verifying it really is a UTextureRenderTarget2D -- the typed counterpart of create_render_target_2d, and what makes it safer than the generic delete_asset, which deletes whatever sits at that path. Wrong type or missing path returns deleted:false with a note explaining which, never an exception, so it is idempotent and safe to re-run. Sisters by type: remove_render_target_2d_array, remove_render_target_cube, remove_texture_2d_array, remove_static_texture_from_render_target.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_render_target_2d_arrayA

Delete a 2D-ARRAY render target, but only after loading it and verifying it really is a UTextureRenderTarget2DArray -- the typed counterpart of create_render_target_2d_array, and safer than the generic delete_asset, which deletes whatever sits at that path. Wrong type or missing path returns deleted:false with an explanatory note rather than raising, so it is idempotent. Use remove_render_target_2d for a plain 2D render target and remove_texture_2d_array for a static UTexture2DArray.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_render_target_cubeA

Delete a CUBE render target, but only after loading it and verifying it really is a UTextureRenderTargetCube -- the typed counterpart of create_render_target_cube, and safer than the generic delete_asset, which deletes whatever sits at that path. Wrong type or missing path returns deleted:false with an explanatory note rather than raising, so it is idempotent. Use remove_render_target_2d / remove_render_target_2d_array for the flat variants.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_static_mesh_socketB

Remove a socket from a static mesh by name (idempotent).

Returns: { static_mesh_path, socket_name, removed, socket_count }

remove_static_texture_from_render_targetA

Delete the static UTexture2D that create_static_texture_from_render_target baked out of a render target (it lives beside the render target as a sibling asset), verifying the target really is a UTexture2D first -- so it refuses to delete the RENDER TARGET itself, which is remove_render_target_2d's job. Safer than the generic delete_asset, which deletes whatever sits at that path; wrong type or missing path returns deleted:false with an explanatory note rather than raising, so it is idempotent.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

remove_texture_2d_arrayA

Delete a static TEXTURE array, but only after loading it and verifying it really is a UTexture2DArray -- the typed counterpart of create_texture_2d_array, and safer than the generic delete_asset, which deletes whatever sits at that path. Wrong type or missing path returns deleted:false with an explanatory note rather than raising, so it is idempotent. Do not confuse it with remove_render_target_2d_array, which deletes the RENDER TARGET array, not this static texture.

Returns: { asset_path, asset_class, package_name, deleted, already_existed, note? }

rename_static_mesh_socketA

Rename an existing static mesh socket (guards against name collisions; idempotent).

Returns: { static_mesh_path, old_name, new_name, renamed, socket_count, saved }

resolve_asset_by_nameA

Resolve an exact asset name (or path) to EVERY matching asset and report match_count + unambiguous, instead of silently picking the first one the way get_asset_by_name, get_blueprint_parent, get_graph_nodes and the rest of the by-name tools do. Run this FIRST whenever you are about to address an asset by bare name: a project can have hundreds of duplicate names (the same name in a vendored pack and in the game's own folders, plus dated backup copies), and unambiguous:false is the only warning you will get before another tool hands you a stale backup's contents as if they were the real asset. From there, pass the full path everywhere. match_count:0 with success:true is a valid, informative answer -- it means "no asset with this exact name", which is a real measurement of non-existence (unlike search_assets_by_pattern's count:0, which can just mean the pattern had a wildcard in it).

Returns: { asset_name: string, search_root: string, class_filter: string, match_count: int, unambiguous: bool, matches: [{ path, package, class }] }

scan_uasset_refsA

Lightweight BINARY scan of a .uasset/.umap on disk (NO editor load): tokenizes the raw package bytes and reports the referenced-asset-path tokens (/Game//Engine//Script) plus, optionally, tokens matching a regex pattern. A quick way to compare copies of one asset: an incomplete (stub) copy shows far fewer reference tokens than the complete one. Accepts a disk path OR a /Game|/Engine mount path.

Returns: { package_file: string, resolved_path: string, exists: bool, file_size_bytes: number, modified: string, pattern: string, ref_path_unique: int, ref_path_occurrences: number, ref_paths: [{token, count}], match_unique: int, match_occurrences: number, matches: [{token, count}] }

search_assets_by_patternA

Find assets by NAME, scanning every mounted content root (/Game, /Engine, /Water, plugin mounts, ...) and returning name, object path, class and package per hit. The broad "does anything called exist, and where?" search. It has TWO match modes and picks one automatically, reporting which in match_mode: a pattern WITHOUT */? is a case-insensitive SUBSTRING test (FString::Contains) -- pass the bare token, this is the common case; a pattern WITH * or ? is a real glob (FString::MatchesWildcard). WARNING: The glob is ANCHORED AT BOTH ENDS -- it matches the WHOLE name, not a substring -- so Grass* means "starts with Grass" and *Grass* is what reproduces substring behaviour. It only ever looks at the asset NAME, so it cannot find an asset by its folder or by a class it belongs to: use resolve_asset_by_name to check ONE exact name and get every homonym, get_assets_in_folder to enumerate a directory, get_assets_by_type for the 5 built-in type filters, and get_assets_by_tag for an Asset Registry tag.

Returns: { assets: [{ name, path, class, package, is_loaded }], count: int, total_scanned: int, scan_was_pending: bool, search_pattern: string, match_mode: "substring"|"wildcard", case_sensitive: bool, max_results: int, results_truncated: bool }

set_asset_metadata_tagA

Sets (or overwrites) a string metadata tag on an asset and saves it. The asset is loaded, UEditorAssetLibrary::SetMetadataTag is applied, the owning package is saved, and the value is read back to verify.

Returns: { asset_path: string, key: string, value: string, read_back: string, tag_set: bool, verified: bool, saved: bool }

set_static_mesh_collision_complexityA

Set the collision complexity (BodySetup CollisionTraceFlag) of a UStaticMesh asset, creating its BodySetup when missing, then save it; a failed save is an error. An unrecognized complexity silently becomes default, so check collision_complexity, which is read back.

Returns: { static_mesh_path, collision_complexity, saved }

set_static_mesh_lightmapA

Set lightmap resolution and/or lightmap UV coordinate index on a static mesh (no rebuild).

Returns: { static_mesh_path, lightmap_resolution, lightmap_coordinate_index, applied_count, saved, save_error? }

set_static_mesh_material_slotA

Assign a material to an existing material slot of a static mesh.

Returns: { static_mesh_path, material_index, material_path, saved }

set_static_mesh_naniteA

Set the Nanite settings of a UStaticMesh asset through the StaticMeshEditor subsystem, which rebuilds the mesh, then save it; a failed save is an error. Both fields are always written: omitting enabled disables Nanite and omitting keep_percent_triangles resets it to 1.0. Returns nanite_enabled read back.

Returns: { static_mesh_path, nanite_enabled, saved }

set_static_mesh_socket_transformA

Update the relative transform of an existing static mesh socket (only the provided fields). A location, rotation or scale that is not three numbers is an error.

Returns: { static_mesh_path, socket_name, updated, location:{x,y,z}, rotation:{pitch,yaw,roll}, scale:{x,y,z}, saved }

set_texture_sampler_settingsA

Sets sampler/LOD settings on an existing UTexture2D and saves it. Applies the requested fields, then PostEditChange + UpdateResource + save (no shader recompile), reading the resulting values back. Enum params accept the name with or without prefix: address_x/address_y in {Wrap,Clamp,Mirror}; filter in {Nearest,Bilinear,Trilinear,Default}; mip_gen_settings in {FromTextureGroup,SimpleAverage,NoMipmaps,LeaveExistingMips,Sharpen0..10,Blur1..5,Unfiltered,Angular}.

Returns: { texture_name, asset_path, address_x, address_y, filter, mip_gen_settings, lod_bias, max_texture_size, flip_green, changed: bool, saved: bool, *_warning?: string, save_error?: string }

set_texture_settingsA

Sets the given sRGB, compression and LOD group of a UTexture2D asset, rebuilds its resource when one changed and saves it in every case, returning the values read back. An unknown compression or LOD group name is still applied, as TC_Default or TEXTUREGROUP_World, with a compression_warning or lod_group_warning.

Returns: { texture_name: string, asset_path: string, changed: bool, saved: bool, srgb: bool, compression: string, lod_group: string, compression_warning?: string, lod_group_warning?: string, save_error?: string }

add_bus_to_mixA

Adds a USoundControlBus to a USoundControlBusMix asset as a new stage whose target value is default_value, and saves the mix. A bus already in the mix is left unchanged (already_in_mix true, not saved); edit a stage with set_control_bus_mix_stage_value. Returns mix_path, bus_path, bus_count, added, saved.

Returns: { mix_path, bus_path, bus_count, added, already_in_mix, saved, default_value }

add_metasound_graph_inputA

Add a graph input of data_type (default Float) to an existing MetaSound Source through the MetaSound builder, inside an undo transaction, then save the asset. Optionally bakes a typed default into the new input; give at most one of default_value, int_value, bool_value or string_value (bool_value wins, then int_value, string_value, default_value). An unregistered data_type or a source that does not load is an error. A name already used by an input is left untouched: with the same data_type the call succeeds with added=false and already_exists=true, saves nothing and does not apply a supplied default (note says so; use metasound_set_input_default); with another data_type it is an error. success is false, with save_error, when the save fails (during PIE, for one). Inverse: remove_metasound_graph_input.

Returns: { asset_path: string, input_name: string, data_type: string, added: bool, already_exists?: bool, has_default: bool, note?: string, saved: bool, save_error: string? }

add_metasound_graph_outputA

Add a graph output of data_type (default Audio; others include Float, Int32, Bool, String and Trigger) to an existing MetaSound Source through the MetaSound builder, inside an undo transaction, then save the asset. An unregistered data_type or a source that does not load is an error. A name already used by an output is left untouched: with the same data_type the call succeeds with added=false and already_exists=true and saves nothing; with another data_type it is an error. success is false, with save_error, when the save fails (during PIE, for one). Inverse: remove_metasound_graph_output.

Returns: { asset_path: string, output_name: string, data_type: string, added: bool, already_exists?: bool, saved: bool, save_error: string? }

add_modulation_input_to_patchA

Appends a USoundControlBus as an input of a USoundModulationPatch asset and saves the patch. A bus whose asset name is already among the inputs is skipped (added false, already_present true, not saved). input_name is not stored. Returns patch_path, bus_path, input_count, added, already_present, saved.

Returns: { patch_path, bus_path, input_count, added, already_present, saved }

add_sound_cue_nodeB

Construct a USoundNode inside a Sound Cue and return its node_id

Returns: { cue_path: string, node_id: int, node_type: string, node_class: string, max_child_nodes: int, child_count: int, sound_wave_set: bool, sound_wave_path: string, node_count: int, saved: bool }

add_soundfield_effect_to_submixA

Append a new effect of a concrete USoundfieldEffectBase class to a USoundfieldSubmix effect chain and save it; an addition succeeds only when the submix reaches disk. A class already in the chain is skipped (added false, already_present true, not saved). When no concrete subclass is loaded (stock UE 5.8 ships none) nothing changes and the call fails, with added false and a note.

Returns: { submix_path, effect_path, effect_class, chain_length, added, already_present, saved, note? }

add_submix_effect_to_chainB

Append a submix effect preset to a USoundSubmix effect chain

Returns: { submix_path: string, effect_name: string, effect_class: string, resolved_from: string, effect_added: bool, chain_length: int, saved: bool }

add_subtitle_cueA

Appends a subtitle cue (FSubtitleAssetData) to a USubtitleAssetUserData. Builds the cue from the supplied text/timing/priority/type/comment, dedupes by FSubtitleAssetData::operator== (text, duration, start_offset, priority, subtitle_type), and either appends or returns the existing cue's index with already_existed: true.

Returns: { asset_path: string, cue_index: int, text: string, success: bool, already_existed: bool, cue_count: int, saved: bool }

configure_audio_3dA

Applies a 3D audio preset to an audio component of the editor world: spatialization (bAllowSpatialization) and an attenuation override, a sphere whose inner radius is attenuation_radius and whose falloff distance is attenuation_distance ('Disabled' turns both off). audio_3d_configured is read back from the component. attenuation_falloff and the cone numbers only describe the preset (a sphere has no cone).

Returns: { audio_component_name: string, audio_3d_settings: string, audio_3d_configured: bool, audio_3d_message: string, old_3d_enabled: bool, new_3d_enabled: bool, attenuation_override: bool, applied_attenuation_radius?: number, applied_falloff_distance?: number, 3d_enabled: bool, spatialization_enabled: bool, attenuation_distance: number, attenuation_radius: number, attenuation_falloff: number, attenuation_cone_angle: number, attenuation_cone_feather: number, audio_3d_recommendations: [string] }

connect_metasound_nodesA

Connects a graph input node's output to a graph output node's input. Resolves the source handle from a graph INPUT node by name (FindGraphInputNode -> the input node's output handle) and the destination handle from a graph OUTPUT node by name (FindGraphOutputNode -> the output node's input handle), then calls UMetaSoundBuilderBase::ConnectNodes and verifies via NodesAreConnected. The connection is real where the two data types match (e.g. a Float graph input connected to a Float graph output). Saves the asset.

Returns: { asset_path: string, from_node_output_name: string, to_node_input_name: string, from_data_type: string, to_data_type: string, connected: bool, result: string, verified: bool, saved: bool, save_error: string? }

connect_sound_cue_nodesB

Wire a child node into a parent node's input slot

Returns: { cue_path: string, parent_node_id: int, child_node_id: int, input_index: int, parent_class: string, child_class: string, parent_child_count: int, connected: bool, saved: bool }

create_audio_busA

Creates a UAudioBus asset at package_path/name and saves it, or loads the one already there (already_exists true) and saves it again; another asset class at that path is an error. channels, when given, sets the channel layout, overwriting an existing bus's layout; when omitted a new bus gets Stereo and an existing one keeps its own. An invalid channels value is refused before any asset is created or loaded. Change the layout later with set_audio_bus_channels and read it with get_audio_bus; create_sound_source_bus makes a source bus that plays this bus's audio.

Returns: { name: string, package_path: string, asset_path: string, asset_class: string, channels: string, channels_int: int, num_channels: int, applied_channels: bool (this call wrote the layout: channels given, or the Stereo default on a new bus), created: bool, already_exists: bool, saved: bool, save_error?: string }

create_control_busA

Creates a USoundControlBus asset at package_path/bus_name, or loads the one already there, and saves it. initial_value is only echoed back as value, never written to the bus; push a runtime value with set_control_bus_value. Returns bus_path, default_value, created, already_existed, saved.

Returns: { bus_path, bus_name, value, default_value, created, already_existed, saved }

create_control_bus_mixA

Creates a USoundControlBusMix asset at package_path/mix_name, or loads the one already there, and saves it. A new mix has no stages; add buses with add_bus_to_mix. Returns mix_path, mix_name, bus_count (its stage count), created, saved.

Returns: { mix_path, mix_name, bus_count, created, saved }

create_dialogue_voiceA

Create a UDialogueVoice asset (idempotent). Populate Gender/Plurality afterwards via set_properties on object_path.

Returns: { name: string, package_path: string, asset_path: string, object_path: string, asset_class: string, gender: string, plurality: string, already_existed: bool, saved: bool }

create_dialogue_waveA

Create a UDialogueWave asset (idempotent). Populate ContextMappings afterwards via set_properties on object_path.

Returns: { name: string, package_path: string, asset_path: string, object_path: string, asset_class: string, context_mapping_count: int, already_existed: bool, saved: bool }

create_metasound_presetA

Creates a MetaSound preset from an existing source or patch asset. Uses UMetaSoundBuilderSubsystem::CreateSourcePresetBuilder (or CreatePatchPresetBuilder) to create a transient preset builder referencing the source, then BuildToAsset to persist it as a new /Game asset.

Returns: { preset_path: string, preset_type: string, success: bool, saved: bool, already_exists: bool }

create_metasound_sourceA

Creates (or loads, idempotently) a UMetaSoundSource asset and saves it. Uses UMetaSoundBuilderSubsystem::CreateSourceBuilder to build a source graph (pre-populated with the source interface: OnPlay input + audio output +, for one-shots, OnFinished output), then UMetaSoundEditorSubsystem::BuildToAsset to persist it as a real /Game asset (headless-safe; no modal picker).

Returns: { source_name: string, asset_path: string, created: bool, already_exists: bool, saved: bool, output_format: string, class_name: string, input_count: number, output_count: number, save_error: string? }

create_modulation_generatorA

Creates a modulation generator asset of class LFO, ADEnvelope or EnvelopeFollower at generator_path, with engine default settings, and saves it. An existing generator there is returned untouched with its own class (not saved). Returns generator_path, generator_name, generator_class, created, already_existed, saved. Configure it with set_modulation_generator_settings.

Returns: { generator_path, generator_name, generator_class, created, already_existed, saved }

create_modulation_generator_lfoA

Creates a USoundModulationGeneratorLFO asset at package_path/generator_name (or loads the one there), writes waveform, frequency, amplitude and offset, enables looping and saves it, overwriting an existing LFO. An unknown waveform silently becomes Sine but is echoed as sent. Returns generator_path, the written values, created, saved.

Returns: { generator_path, generator_name, waveform, frequency, amplitude, offset, created, saved }

create_modulation_parameterA

Creates a USoundModulationParameter asset of the chosen concrete class at parameter_path and saves it. An existing parameter there is returned untouched with its real class (not saved). Returns parameter_path, parameter_name, parameter_class, created, already_existed, saved. Tune it with set_modulation_parameter_settings.

Returns: { parameter_path, parameter_name, parameter_class, created, already_existed, saved }

create_sound_attenuationA

Create a USoundAttenuation asset at package_path/name, or load the one already there, then force bAttenuate on, apply the optional falloff_distance and sphere radius, and save it (re-running edits the existing asset). Returns the values read back; set_sound_attenuation_properties edits every other field.

Returns: { name: string, package_path: string, asset_path: string, asset_class: string, attenuate: bool, falloff_distance: number, radius: number, shape_extent_x: number, shape_extent_y: number, shape_extent_z: number, applied_falloff_distance: bool, applied_radius: bool, created: bool, already_exists: bool, saved: bool }

create_sound_classB

Create a USoundClass asset and optionally set its volume/pitch

Returns: { name: string, package_path: string, asset_path: string, asset_class: string, volume: number, pitch: number, applied_volume: bool, applied_pitch: bool, created: bool, already_exists: bool, saved: bool }

create_sound_concurrencyA

Create a USoundConcurrency asset at package_path/name, or load the one already there, optionally set MaxCount, and save it. Returns max_count read back, created, already_exists and saved; set_sound_concurrency_properties edits the other concurrency settings.

Returns: { name: string, package_path: string, asset_path: string, asset_class: string, max_count: int, applied_max_count: bool, created: bool, already_exists: bool, saved: bool }

create_sound_cueA

Create an empty USoundCue (no nodes, no first node) at package_path/name and save it; an existing cue there is returned unchanged (already_existed:true). Returns cue_path, asset_path, node_count and saved. Build the graph with add_sound_cue_node, connect_sound_cue_nodes and set_sound_cue_first_node.

Returns: { name: string, package_path: string, asset_path: string, cue_path: string, created: bool, already_existed: bool, node_count: int, saved: bool, message: string }

create_sound_mixA

Create a USoundMix asset at package_path/name (package_path defaults to /Game/Audio) and save it; a sound mix already there is loaded instead (already_exists true) and the eq_enabled and duration you pass overwrite its values before it is saved. Omitted fields keep their current values; the reply reads eq_enabled and duration back from the asset. An invalid path, or an asset of another class there, is an error; a failed save is an error with the change kept in memory. Idempotent. Add per-class volume and pitch adjusters with set_sound_mix_class_override; create the classes with create_sound_class.

Returns: { name: string, package_path: string, asset_path: string, asset_class: string, eq_enabled: bool, duration: number, applied_eq_enabled: bool, applied_duration: bool, created: bool, already_exists: bool, saved: bool }

create_sound_modulation_patchA

Creates a USoundModulationPatch asset at package_path/patch_name with no inputs or output, bypassed by default (bBypass true), and saves it; a patch already there is returned untouched, not re-saved. Returns patch_path, bBypass, input_count, output_parameter_path, created, already_existed, saved. Fill it with add_modulation_input_to_patch and set_modulation_patch_output_parameter.

Returns: { patch_path, patch_name, bBypass, input_count, output_parameter_path, created, already_existed, saved }

create_sound_source_busA

Creates a USoundSourceBus asset at package_path/name, or loads the one already there, writes its routing fields and saves it; another asset class at the path is an error. source_bus_channels and duration, when omitted, take the defaults (Stereo, 1.0 s) on a new asset and keep their value on an existing one, whose fields the given values overwrite. Every value is validated before any asset is created or loaded, so an invalid one leaves nothing behind. audio_bus_path, when given, must load as a UAudioBus and becomes the bus whose audio this source bus plays; when omitted that field is left as is. Edit later with set_sound_source_bus_audio_bus or set_sound_source_bus_send_info; read with get_sound_source_bus.

Returns: { name: string, package_path: string, asset_path: string, asset_class: string, source_bus_channels: string, duration: float, audio_bus_path: string, audio_bus_class: string, applied_channels: bool, applied_duration: bool (each true when this call wrote the field: given, or the default on a new asset), applied_audio_bus: bool, created: bool, already_exists: bool, saved: bool, save_error?: string }

create_sound_submixA

Create an empty USoundSubmix asset at package_path/name, or load the one already there, and save it. Returns asset_path, created, already_exists and saved; add effects with add_submix_effect_to_chain and read them with get_submix_effect_chain.

Returns: { name: string, package_path: string, asset_path: string, asset_class: string, created: bool, already_exists: bool, saved: bool }

create_soundfield_submixA

Create a USoundfieldSubmix asset at submix_path and save it, with its default encoding format and an empty effect chain; a new one succeeds only when it reaches disk. An existing one there is returned unchanged and not re-saved (already_existed true, saved false). Returns soundfield_encoding_format, effect_chain_length and saved; inspect it with get_soundfield_submix_info.

Returns: { submix_path, asset_path, soundfield_encoding_format, encoding_settings_class, created, already_existed, saved }

create_subtitles_assetA

Creates a USubtitleAssetUserData asset (the UE 5.8 subtitle authoring asset). Creates a new package under /Game and NewObject into it, then saves. Idempotent: if the asset already exists, returns it with already_existed: true.

Returns: { asset_path: string, success: bool, already_existed: bool, cue_count: int, saved: bool }

delete_meta_soundA

Delete a UMetaSoundSource asset from the project. Idempotent — deleting a non-existent asset is a no-op. Destructive — requires confirm=true.

Returns: { metasound_path, deleted, already_existed, note }

disconnect_metasound_node_from_graph_outputA

Disconnects whatever node output currently drives a named graph output, clearing the edge (inverse of metasound_connect_node_to_graph_output). Resolves the graph output node's input handle by name (FindGraphOutputNode) and queries NodeInputIsConnected first: if the input is already unconnected it returns already_disconnected without error (idempotent), otherwise it calls UMetaSoundBuilderBase::DisconnectNodeInput and reports the result. Saves the asset.

Returns: { asset_path: string, graph_output_name: string, data_type: string, disconnected: bool, already_disconnected: bool, result: string, saved: bool, save_error: string? }

disconnect_metasound_nodesA

Disconnects a graph input node's output from a graph output node's input (inverse of connect_metasound_nodes). Resolves the source handle from a graph INPUT node by name (FindGraphInputNode -> the input node's output handle) and the destination handle from a graph OUTPUT node by name (FindGraphOutputNode -> the output node's input handle), then queries NodesAreConnected first: if the edge is already absent it returns already_disconnected without error (idempotent), otherwise it calls UMetaSoundBuilderBase::DisconnectNodes and reports the result. Saves the asset.

Returns: { asset_path: string, from_node_output_name: string, to_node_input_name: string, from_data_type: string, to_data_type: string, disconnected: bool, already_disconnected: bool, result: string, saved: bool, save_error: string?, note: string? }

disconnect_sound_cue_nodesA

Clear a wired child out of a parent node's input slot (inverse of connect_sound_cue_nodes)

Returns: { cue_path: string, parent_node_id: int, child_node_id: int, input_index: int, parent_class: string, child_class: string, parent_child_count: int, disconnected: bool, already_disconnected: bool, saved: bool }

get_audio_busA

Read the channel layout of a UAudioBus asset: channels (Mono, Stereo, Quad, FivePointOne or SevenPointOne), channels_int and num_channels. Read-only. is_active is always false because no audio device is queried. Change the layout with set_audio_bus_channels.

Returns: { bus_path: string, asset_class: string, channels: string, channels_int: int, num_channels: int, is_active: bool (always false: headless — no audio device) }

get_audio_component_propertiesA

Retrieves comprehensive properties of an audio component including volume, pitch, position, rotation, scale, and sound details.

Returns: { audio_component_name: string, audio_component_found: bool, audio_component_message: string, component_class: string, component_type: string, audio_volume: number, audio_pitch: number, audio_position: { x, y, z }, audio_rotation: { pitch, yaw, roll }, audio_scale: { x, y, z }, audio_enabled: bool, audio_auto_activate: bool, audio_sound_name: string, audio_sound_class: string, audio_sound_path: string, audio_sound_duration: number, audio_3d_enabled: bool, audio_3d_attenuation_radius: number, audio_mobility: string, audio_owner_name: string, audio_level: string, audio_world: string }

get_audio_settingsA

Retrieves comprehensive audio settings and statistics including all audio components in the world, audio device capabilities, and quality metrics.

Returns: { audio_settings_found: bool, audio_quality: string, audio_api: string, audio_enabled: bool, audio_mode: string, world_name?: string, audio_component_count: int, active_audio_component_count: int, spatialized_audio_component_count: int, average_volume: number, max_volume: number, max_pitch: number, engine_version: string, platform_name: string, audio_max_channels: int, audio_3d_enabled: bool, audio_reverb_enabled: bool, audio_occlusion_enabled: bool, audio_recommendations: [string], audio_complexity_score: number, audio_complexity_rating: string }

get_control_bus_mix_infoA

Reads the stages of a USoundControlBusMix asset without changing it. Returns mix_path, stage_count and stages, one per stage with bus_path (empty when the bus reference is cleared), target_value, attack_time and release_time. Edit a stage with set_control_bus_mix_stage_value.

Returns: { mix_path, stage_count, stages: [{ bus_path, target_value, attack_time, release_time }] }

get_meta_sound_node_infoA

Read one node of the default graph of a MetaSound Source by GUID: its name, class name, input/output/environment vertices (name, type_name, vertex_id), input literal defaults and Configuration struct class. Read-only; get node ids from list_meta_sound_nodes.

Returns: { metasound_path, node_id, name, class_name, inputs: [{name, type_name}], outputs: [...], environment: [...], input_defaults: [{vertex_id, value, type}], configuration_class }

get_meta_sound_node_input_defaultA

Read the default literal stored on one input of a MetaSound Source node: vertex type, has_value, literal_type and value; has_value false means no literal is set. An unknown input name fails and lists the valid ones. Write it with metasound_set_node_input_default.

Returns: { metasound_path, node_id, input_name, type, has_value, literal_type?, value? }

get_meta_sound_node_propertyA

Read one field of the Configuration struct of a MetaSound Source node by property name, returning its C++ type, has_value and value as JSON. Fails when the node has no Configuration struct or the struct has no such property. Read-only; write it with set_meta_sound_node_property.

Returns: { metasound_path, node_id, property, type, has_value, value? }

get_metasound_graph_infoB

Reads the MetaSound Source document graph: node/connection counts + I/O. Reads the document's RootGraph default page (node + connection/edge counts) and the graph's declared interface inputs/outputs (names + types). "/Game/MetaSounds/MS_Example" or fully-qualified ".MS_Example").

Returns: { asset_path: string, graph_class_name: string, node_count: number, connection_count: number, variable_count: number, input_count: number, output_count: number, inputs: [{ name: string, type: string }], outputs: [{ name: string, type: string }] }

get_metasound_infoA

Read the top-level metadata of a MetaSound Source asset, loading it if needed: its class, the root graph class name, the graph inputs and outputs (name and type) with their counts, and interface_count, the number of interfaces the document declares. Read-only; a path that does not resolve to a UMetaSoundSource is an error. For node and connection counts use get_metasound_graph_info; list_meta_sound_nodes lists the nodes and list_meta_sounds finds sources.

Returns: { source_name: string, asset_path: string, class_name: string, graph_class_name: string, input_count: number, output_count: number, interface_count: number, inputs: [{ name: string, type: string }], outputs: [{ name: string, type: string }] }

get_metasound_preset_parametersA

Gets all parameter defaults from a MetaSound preset. Loads the preset, obtains a builder, iterates GetGraphInputNames, and reads each default value along with its type from the document interface.

Returns: { preset_path: string, parameters: [{name, type, value}], parameter_count: int }

get_modulation_generator_infoA

Reads a USoundModulationGenerator asset without changing it. Returns generator_path, generator_class and settings by class: LFO shape, frequency, amplitude, offset, phase; ADEnvelope attack_time, decay_time; EnvelopeFollower attack_time, release_time, gain, audio_bus_path; empty for any other class.

Returns: { generator_path, generator_class, settings: {...} }

get_modulation_infoB

Reads a USoundControlBus asset and its live value in the editor world, without changing anything. Returns bus_path, default_value, current_value (the live modulator value; the engine returns 1.0 for a bus that is not active) and subsystem_active (whether the editor world has a modulation manager).

Returns: { bus_path, default_value, current_value, subsystem_active }

get_modulation_parameter_infoA

Reads a USoundModulationParameter asset without changing it. Returns parameter_path, parameter_class (the concrete class, e.g. SoundModulationParameterVolume) and its settings value_normalized, clamp_to_normalized_range and value_unit. Change them with set_modulation_parameter_settings.

Returns: { parameter_path, parameter_class, value_normalized, clamp_to_normalized_range, value_unit }

get_sound_attenuation_propertiesA

Read every FSoundAttenuationSettings field (shape, falloff, spatialization, LPF, occlusion, reverb send) of a USoundAttenuation asset as one settings object, with the keys set_sound_attenuation_properties takes, plus asset_class. Read-only.

Returns: { attenuation_path: string, asset_class: string, settings: object }

get_sound_class_hierarchyA

Read one level of the hierarchy of a USoundClass asset: its parent and parent_path (parent "None" for a root), the names of its direct children and child_count. Call it again on a parent or child to walk further. Read-only.

Returns: { name: string, sound_class_path: string, parent: string, parent_path: string, children: [string], child_count: int }

get_sound_class_propertiesA

Read a USoundClass asset: every FSoundClassProperties field that set_sound_class_properties writes (volume, pitch, filters, reverb and routing flags, output_target, loading_behavior) plus its direct parent and direct children by name and path; parent_class is "None" for a root class, and child_count is the number of children listed (null references are skipped). One level only: walk further with get_sound_class_hierarchy on a parent or child. Read-only; it loads the asset by object or package path, and one that does not load as a USoundClass is an error.

Returns: { sound_class_path: string, volume: float, pitch: float, low_pass_frequency: float, attenuation_distance_scale: float, lfe_bleed: float, voice_center_channel_volume: float, radio_filter_volume: float, radio_filter_volume_threshold: float, default_2d_reverb_send_amount: float, apply_effects: bool, always_play: bool, is_ui_sound: bool, is_music: bool, center_channel_only: bool, apply_ambient_volumes: bool, reverb: bool, output_target: string, loading_behavior: string, parent_class: string, parent_class_path: string, child_classes: [{name, path}], child_count: int }

get_sound_concurrency_propertiesA

Read every FSoundConcurrencySettings field (maxCount, bLimitToOwner, resolutionRule, retriggerTime, volume scaling, voice stealing) of a USoundConcurrency asset as one settings object, with the keys set_sound_concurrency_properties takes, plus asset_class. Read-only.

Returns: { concurrency_path: string, asset_class: string, settings: object }

get_sound_cue_graphA

Read the node graph of a USoundCue without changing it: every node in AllNodes with its id (the node_id other sound cue tools take), class, child_ids (-1 for an empty slot), max_child_nodes and editable properties, plus first_node_id (-1 when unset) and node_count.

Returns: { cue_path: string, asset_path: string, nodes: [object], node_count: int, first_node_id: int, has_first_node: bool }

get_sound_modulation_patch_infoB

Reads a USoundModulationPatch asset without changing it. Returns patch_path, bBypass, output_parameter ({ path, class }, or null when unset), inputs (one { bus: { path }, name } per input; name is always empty) and input_count.

Returns: { patch_path, bBypass, output_parameter: { path, class } | null, inputs: [{ bus: { path } }], input_count }

get_sound_source_busA

Read the routing fields of a USoundSourceBus asset: source_bus_channels (Mono or Stereo), duration in seconds (0 plays indefinitely) and the UAudioBus it outputs to (audio_bus_path and audio_bus_class, empty when none). Read-only. Writer: set_sound_source_bus_audio_bus.

Returns: { ssb_path: string, asset_class: string, source_bus_channels: string, duration: float, audio_bus_path: string, audio_bus_class: string }

get_sound_wave_propertiesB

Read USoundWave tunables (the object's own UPROPERTY fields) from an imported sound wave.

Returns: { sound_wave_path: string, asset_class: string, settings: object, looping: bool }

get_soundfield_submix_infoA

Read a USoundfieldSubmix asset without changing it: its soundfield_encoding_format and resolved_format, encoding_settings {class, path}, and effect_chain entries {index, class, path, settings_class, settings_path} with chain_length. Adds a note when no concrete soundfield effect class is loaded.

Returns: { submix_path, soundfield_encoding_format, resolved_format, encoding_settings_class, encoding_settings: { class, path }, effect_chain: [{ index, class, path, settings_class, settings_path }], chain_length, note? }

get_submix_effect_chainA

Read the effect chain of a USoundSubmix asset in order: one entry per slot with the name, class and path of its USoundEffectSubmixPreset ("None" for an empty slot), plus chain_length. Read-only; add_submix_effect_to_chain appends to it.

Returns: { submix_path: string, effects: [object], chain_length: int }

list_meta_sound_node_typesA

Enumerate all MetaSound node classes registered with the engine (via Metasound::Frontend::ISearchEngine). Editor-only because ISearchEngine::FindAllClasses is gated by WITH_EDITORONLY_DATA.

Returns: { count, types: [{ class_name, class_path, type, version, is_native }] }

list_meta_sound_nodesA

List every node in the default graph of a MetaSound Source asset with its GUID id, name, class name and input/output counts, plus count. Read-only; pass the id to get_meta_sound_node_info and the other node tools.

Returns: { metasound_path, count, nodes: [{ id, name, class_name, input_count, output_count }] }

list_meta_sound_referencesA

List the packages that reference a MetaSound Source asset, hard or soft, from the Asset Registry, with their count. Read-only; the source is loaded to resolve its package. For assets of any type use get_asset_referencers.

Returns: { metasound_path, count, references: [{ package_name }] }

list_meta_soundsA

List all UMetaSoundSource assets under a content path (default /Game).

Returns: { package_path, count, sounds: [{ path, name, class }] }

list_subtitle_cuesA

Lists all subtitle cues on a USubtitleAssetUserData. Read-only walk of the Subtitles array, returning cue_count, max_duration (from USubtitleAssetUserData::GetMaximumDuration), and per-cue fields (index, text, start_offset, duration, duration_type, priority, subtitle_type, comment).

Returns: { asset_path: string, success: bool, count: int, max_duration: float, cues: [{index, text, start_offset, duration, duration_type, priority, subtitle_type, comment}] }

metasound_add_interfaceA

Adds a registered interface to an existing MetaSound Source's graph. Obtains a builder for the saved asset via the editor subsystem's FindOrBeginBuilding (the reliable headless path), validates the interface via IsInterfaceRegistered, then calls UMetaSoundBuilderBase::AddInterface (which adds the interface's input/output nodes). The asset is saved after the edit.

Returns: { asset_path: string, node_kind: string, interface_name: string, added: bool, saved: bool }

metasound_add_node_by_classnameA

Add a real process node to a MetaSound Source graph by its registered class name (e.g. UE/Sine/Audio). Unlike add_metasound_graph_input (which adds a graph input node), this instantiates a DSP node so you can author a real signal patch headless. Returns the node's GUID (node_id) and its enumerated input/output pins (name + data_type) for follow-up set/connect calls. The asset is saved. NOT idempotent: each call adds a new node instance (delete + recreate the source for a clean run).

Returns: { asset_path: string, node_id: string, class_namespace: string, class_name: string, class_variant: string, inputs: [{name,data_type}], outputs: [{name,data_type}], added: bool, saved: bool }

metasound_connect_node_to_graph_outputA

Connect a concrete node's output pin to a named graph output, completing a signal patch (e.g. Sine.Audio -> the source's audio output). Uses ConnectNodeOutputToGraphOutput (idempotent: replaces any existing edge). Reports the honest EMetaSoundBuilderResult.

Returns: { asset_path: string, node_id: string, node_output_name: string, graph_output_name: string, connected: bool, result: string, saved: bool }

metasound_set_input_defaultA

Sets the default literal value of a MetaSound Source graph input. Obtains a builder for the existing asset (FindOrBeginBuilding) and calls SetGraphInputDefault with an FMetasoundFrontendLiteral built from the supplied value, then reads the value back to verify and saves the asset. Provide exactly one of value (float, default), int_value, bool_value or string_value.

Returns: { asset_path: string, input_name: string, value_type: string, value_set: bool, verified: bool, value_read_back: string, saved: bool }

metasound_set_node_input_defaultA

Set the default literal of a named input pin on a concrete node (by node_id from metasound_add_node_by_classname). Reads the value back to verify and saves. Provide exactly one of value (float, default), int_value, bool_value or string_value.

Returns: { asset_path: string, node_id: string, input_name: string, value_type: string, value_set: bool, verified: bool, value_read_back: string, saved: bool }

play_soundA

Starts the sound already assigned to an audio component of the editor world, matched by object name (case-insensitive) against the first audio component of each actor; components in a running PIE world are not reached. start_time is an offset in seconds into the sound. A component without a sound is an error: assign one with set_audio_sound. Transient: nothing is saved, marked dirty or undoable. was_playing and playing are read just before and just after the call. Stop with stop_sound; to play an asset at a location without a component use play_sound_at_location.

Returns: { audio_component_name: string, playing: bool, was_playing: bool, sound_name: string, start_time: number, success: bool }

play_sound_at_locationA

Plays a sound asset at a specific world location without requiring an audio component.

Returns: { sound_path: string, sound_name: string, location: { x, y, z }, rotation: { pitch, yaw, roll }, volume: number, pitch: number, success: bool }

remove_bus_from_mixA

Removes every stage that uses a USoundControlBus from a USoundControlBusMix asset and saves the mix; a removal succeeds only when the mix reaches disk. A bus that is not in the mix is already the state asked for: the call succeeds with removed false and already_absent true, and saves nothing. Returns mix_path, bus_path, removed, already_absent, stage_count, saved.

Returns: { mix_path, bus_path, removed, already_absent, stage_count, saved }

remove_metasound_graph_inputA

Removes a graph INPUT (and its node) from a MetaSound Source by name (inverse of add_metasound_graph_input). Queries GetGraphInputNames first: if the input is already absent it returns already_absent without error (idempotent), otherwise it calls UMetaSoundBuilderBase::RemoveGraphInput and reports the result. Saves the asset.

Returns: { asset_path: string, input_name: string, removed: bool, already_absent: bool, saved: bool, save_error: string?, note: string? }

remove_metasound_graph_outputA

Removes a graph OUTPUT (and its node) from a MetaSound Source by name (inverse of add_metasound_graph_output). Queries GetGraphOutputNames first: if the output is already absent it returns already_absent without error (idempotent), otherwise it calls UMetaSoundBuilderBase::RemoveGraphOutput and reports the result. Saves the asset.

Returns: { asset_path: string, output_name: string, removed: bool, already_absent: bool, saved: bool, save_error: string?, note: string? }

remove_metasound_nodeA

Removes a node from a MetaSound Source graph by its node_id GUID (inverse of metasound_add_node_by_classname). Parses the node_id into a node handle and queries ContainsNode first: if the node is already absent it returns already_absent without error (idempotent), otherwise it calls UMetaSoundBuilderBase::RemoveNode (pruning unused dependencies) and reports the result. Saves the asset.

Returns: { asset_path: string, node_id: string, removed: bool, already_absent: bool, saved: bool, save_error: string?, note: string? }

remove_modulation_input_from_patchA

Removes every input of a USoundModulationPatch asset whose bus has the same asset name as bus_path, then saves the patch; a removal succeeds only when the patch reaches disk. When no input matches, the patch is already the state asked for: the call succeeds with removed false and already_removed true, and saves nothing. Returns patch_path, bus_path, removed, already_removed, input_count, saved.

Returns: { patch_path, bus_path, removed, already_removed, input_count, saved }

remove_soundfield_effectA

Detach the effect at effect_index from a USoundfieldSubmix effect chain (undoable) and save; the effect object stays in the package, an out-of-range index is an error, and a removal succeeds only when the submix reaches disk. Returns removed_effect_class, removed_effect_path and chain_length. With no concrete effect class loaded nothing changes and the call fails, with removed false and a note.

Returns: { submix_path, effect_index, removed_effect_class, removed_effect_path, removed: true, already_absent: false, chain_length, saved, save_error? } -- success only when saved; with no concrete effect class loaded the call fails with { submix_path, effect_index, removed: false, saved: false, note } and the chain is not touched.

remove_subtitle_cueA

Remove a single FSubtitleAssetData cue by index. Inverse of add_subtitle_cue; use remove_subtitles_asset to destroy the whole asset instead. Idempotent: an out-of-range index returns removed:false + note, not an error.

Returns: { asset_path, cue_index, removed, previous_count, new_count }

remove_subtitles_assetA

Destroy a USubtitleAssetUserData asset (mirror of create_subtitles_asset). Typed-delete: it loads the asset and REFUSES to delete it if it is not a USubtitleAssetUserData, so it cannot wipe the wrong asset the way the generic delete_asset can. Idempotent on missing assets.

Returns: { asset_path, deleted, already_existed, asset_class?, note? }

set_audio_bus_channelsA

Change the channel layout (AudioBusChannels) of an existing UAudioBus asset and save it; success requires the save. Returns channels, channels_int and num_channels read back from the asset. To make a new bus use create_audio_bus.

Returns: { bus_path: string, asset_class: string, channels: string, channels_int: int, num_channels: int, saved: bool }

set_audio_soundA

Sets the sound asset of an audio component of the editor world, matched by object name (case-insensitive) against the first audio component of each actor; components in a running PIE world are not reached. A component that is playing restarts with the new sound unless it allows multiple instances. The change is not saved, marked dirty or undoable. A missing component or a sound that does not load is an error. previous_sound_name names the sound it replaced (None when there was none). Start playback with play_sound.

Returns: { audio_component_name: string, sound_path: string, sound_name: string, previous_sound_name: string, sound_duration: number, success: bool }

set_audio_volumeA

Set VolumeMultiplier (0 to 10, else an error; also resets VolumeModulationMin/Max to 1) on an audio component of the editor world, matched by object name against the first audio component of each actor. No undo, no dirty mark. Returns old_volume, new_volume and volume_set.

Returns: { audio_component_name: string, old_volume: number, new_volume: number, requested_volume: number, volume_set: bool, volume_message: string, audio_enabled: bool, audio_pitch: number, audio_mobility: string, audio_sound_name: string, audio_3d_attenuation_radius: number, audio_position: { x, y, z }, audio_owner_name: string }

set_control_bus_mix_stage_valueA

Sets the stored target value, and optionally the attack and release fade times in seconds, of the stage a USoundControlBus has in a USoundControlBusMix asset, then saves the mix; success requires the save. Only that bus's first stage is edited, inside an undo transaction; a bus that is not in the mix is an error (add it with add_bus_to_mix). It edits the asset, not a live value: push a runtime value with set_control_bus_value. Read the stages with get_control_bus_mix_info.

Returns: { mix_path, bus_path, target_value, attack_time, release_time, updated, saved }

set_control_bus_valueA

Pushes a runtime value into a USoundControlBus through a global bus mix of the editor world (UAudioModulationStatics::SetGlobalBusMixValue), fading over fade_time. Transient: the asset is not modified or saved, and applied is always true, not read back; read the live value with get_modulation_info.

Returns: { bus_path, value, fade_time, applied }

set_meta_sound_node_propertyA

Write one field of a MetaSound Source node's Configuration struct by reflection, directly in the document (not through the MetaSound builder), then save the asset. Re-applying a value returns value_changed false but still saves. Succeeds only when the asset reaches disk; a failed save leaves the value in memory only (saved false, save_error).

Returns: { metasound_path, node_id, property, set, value_changed, new_value?, saved, save_error? }

set_metasound_preset_parameterB

Sets a parameter default value on a MetaSound preset. Loads the preset, obtains a builder via FindOrBeginBuilding, calls SetGraphInputDefault with the appropriate literal type, then BuildAndOverwriteMetaSound to persist.

Returns: { preset_path: string, parameter_name: string, success: bool, verified: bool, value_read_back: string, saved: bool }

set_modulation_generator_settingsA

Writes the settings that match the class of a USoundModulationGenerator asset (LFO, ADEnvelope or EnvelopeFollower) and saves it; params of another class are ignored, other generator classes are refused, and the LFO shape cannot be set here. Returns generator_path, generator_class, settings as stored, updated, saved.

Returns: { generator_path, generator_class, settings: {...}, updated, saved }

set_modulation_parameter_settingsA

Writes the given Settings fields (value_normalized, clamp_to_normalized_range, value_unit) of a USoundModulationParameter asset and saves it; omitted fields keep their value, and the asset is saved even when none is given. Returns parameter_path, the three settings as stored, updated, saved.

Returns: { parameter_path, value_normalized, clamp_to_normalized_range, value_unit, updated, saved }

set_modulation_patch_bypassA

Sets the bBypass flag of a USoundModulationPatch asset and saves it. A bypassed patch stays active but outputs the default value of its output parameter; new patches start bypassed. Returns patch_path, bBypass as stored, updated, saved.

Returns: { patch_path, bBypass, updated, saved }

set_modulation_patch_output_parameterA

Sets the output USoundModulationParameter of a USoundModulationPatch asset, or clears it when parameter_path is an empty string, and saves the patch. Returns patch_path, parameter_path and parameter_class as stored (empty after a clear), updated, cleared, saved. Create a parameter with create_modulation_parameter.

Returns: { patch_path, parameter_path, parameter_class, updated, cleared, saved }

set_sound_attenuation_propertiesA

Author FSoundAttenuationSettings on a USoundAttenuation via reflection (partial merge + clamp).

Returns: { attenuation_path: string, asset_class: string, settings: object, applied_keys: [string], saved: bool }

set_sound_class_parentA

Make one USoundClass the child of another, wiring ParentClass and ChildClasses, and save both packages. A previous parent loses the child in memory but is not saved; only self-parenting is refused, not cycles. Returns child_count, saved_parent and saved_child, succeeding even when a save fails.

Returns: { child: string, parent: string, child_path: string, parent_path: string, child_count: int, saved_parent: bool, saved_child: bool }

set_sound_class_propertiesA

Write the given FSoundClassProperties fields of a USoundClass asset (volume, pitch, filters, routing and loading flags) in one undoable transaction, then save it. Only fields you pass change; values are not range-checked and unknown enum names are skipped. Returns every current value plus applied_ flags and saved.

Returns: { sound_class_path: string, success: bool, volume: float, pitch: float, low_pass_frequency: float, attenuation_distance_scale: float, lfe_bleed: float, voice_center_channel_volume: float, radio_filter_volume: float, radio_filter_volume_threshold: float, default_2d_reverb_send_amount: float, apply_effects: bool, always_play: bool, is_ui_sound: bool, is_music: bool, center_channel_only: bool, apply_ambient_volumes: bool, reverb: bool, output_target: string, loading_behavior: string, applied_volume: bool, applied_pitch: bool, applied_low_pass_frequency: bool, applied_attenuation_distance_scale: bool, applied_lfe_bleed: bool, applied_voice_center_channel_volume: bool, applied_radio_filter_volume: bool, applied_radio_filter_volume_threshold: bool, applied_default_2d_reverb_send_amount: bool, applied_apply_effects: bool, applied_always_play: bool, applied_is_ui_sound: bool, applied_is_music: bool, applied_center_channel_only: bool, applied_apply_ambient_volumes: bool, applied_reverb: bool, applied_output_target: bool, applied_loading_behavior: bool, saved: bool }

set_sound_concurrency_propertiesA

Author FSoundConcurrencySettings on a USoundConcurrency via reflection (partial merge + clamp).

Returns: { concurrency_path: string, asset_class: string, settings: object, applied_keys: [string], saved: bool }

set_sound_cue_first_nodeA

Make the node at node_id the root (FirstNode, the output) of a USoundCue graph, undoably, and save the asset. Returns first_node_class, first_node_set and saved; an out-of-range node_id is an error. Get node ids from add_sound_cue_node or get_sound_cue_graph.

Returns: { cue_path: string, node_id: int, first_node_class: string, first_node_set: bool, saved: bool }

set_sound_cue_node_propertiesA

Set the EditAnywhere properties of a Sound Cue node (located by node_id) via reflection. The writer twin of get_sound_cue_graph, which reads them. Partial update (idempotent): only keys present in properties are written, and only editable (CPF_Edit) props are touched (ChildNodes/graph wiring are unreachable here — use connect_sound_cue_nodes). Keys are the camelCase UPROPERTY names, the same ones get_sound_cue_graph reports under each node's properties (e.g. a Modulator: pitchMin/pitchMax/volumeMin/volumeMax; a Delay: delayMin/delayMax).

Returns: { cue_path: string, node_id: int, node_class: string, applied_keys: [string], saved: bool }

set_sound_mix_class_overrideA

Sets a sound class adjuster override in a USoundMix. Loads the USoundMix and USoundClass, adds or updates an FSoundClassAdjuster in the mix's SoundClassEffects array, then saves.

Returns: { sound_mix_path: string, sound_class_path: string, success: bool, volume_adjuster: float, pitch_adjuster: float, apply_to_children: bool, total_adjusters: int, saved: bool }

set_sound_source_bus_audio_busA

Point the AudioBus output of a USoundSourceBus asset at a UAudioBus, or clear it when audio_bus_path is empty or omitted, then save; success requires the save. Returns audio_bus_path and audio_bus_class read back, plus cleared. A bus path that does not load is an error, not a clear.

Returns: { ssb_path: string, audio_bus_path: string, audio_bus_class: string, cleared: bool, saved: bool }

set_sound_source_bus_send_infoA

Author a single FSoundSourceBusSendInfo entry on USoundBase::BusSends via reflection (partial merge + clamp).

Returns: { ssb_path: string, send_index: int, bus_sends_count: int, send_info: object, applied_keys: [string], saved: bool }

set_sound_source_bus_send_level_curveA

Merge a FRuntimeFloatCurve JSON into BusSends[send_index].CustomSendLevelCurve of a USoundSourceBus asset (BusSends grows with default entries past its end) and save it; success requires the save. Returns the curve read back. The curve only takes effect when that send uses the CustomCurve control method: see set_sound_source_bus_send_info.

Returns: { ssb_path: string, send_index: int, bus_sends_count: int, distance_curve: object, applied_keys: [string], saved: bool }

set_sound_wave_propertiesA

Author USoundWave tunables on an imported sound wave via reflection (partial merge + clamp).

Returns: { sound_wave_path: string, asset_class: string, settings: object, applied_keys: [string], applied_looping: bool, looping: bool, saved: bool }

set_soundfield_effect_settingsA

Cannot write soundfield effect settings in this engine version, so every call fails and nothing is changed: USoundfieldEffectBase::GetSettingsClass is protected, so the settings class an effect needs cannot be found. The submix and the effect slot are still checked first (a missing submix or an out-of-range effect_index gets its own error); a valid slot fails with applied_count 0 and a note.

Returns: { success: false, error, data: { submix_path, effect_index, settings_class, applied_count, applied_fields, saved, note } }

set_submix_effect_settingsA

Configure a submix effect preset's Settings struct (by chain index) via reflection (partial merge + clamp).

Returns: { submix_path: string, effect_index: int, preset_class: string, settings: object, saved: bool }

set_subtitle_cue_textA

Sets the text on an existing subtitle cue. Loads the USubtitleAssetUserData, verifies cue_index is in range, sets Subtitles[cue_index].Text, and saves.

Returns: { asset_path: string, cue_index: int, text: string, success: bool, saved: bool }

set_subtitle_cue_timingA

Updates the timing fields on an existing subtitle cue. Loads the USubtitleAssetUserData, applies any combination of start_offset / duration / duration_type to Subtitles[cue_index], and saves. Fields not provided are left untouched.

Returns: { asset_path: string, cue_index: int, success: bool, applied_start_offset: bool, applied_duration: bool, applied_duration_type: bool, start_offset: float, duration: float, duration_type: string, saved: bool }

stop_soundA

Stop playback on an audio component of the editor world (UAudioComponent::Stop), matched by object name against the first audio component of each actor; components in a running PIE world are not reached. Returns was_playing and playing; success is always true. Start playback with play_sound.

Returns: { audio_component_name: string, playing: bool, was_playing: bool, success: bool }

audit_asset_referencesA

Project-wide reference audit under folder_path: assets with zero referencers ("orphans") and dependencies pointing at a package no longer on disk ("broken"). Metadata-only through the AssetRegistry -- it never LOADS the assets, so it scales to a large project without spiking memory. It returns only a summary plus a report path; read the detail back with read_mcp_audit_file. For one asset rather than a sweep, use get_asset_referencers / get_asset_dependencies; for unused assets only, find_unused_assets.

Returns: { path: string, summary: { asset_count: int, orphan_count: int, broken_reference_count: int, dependency_type: string } }

audit_blueprint_healthA

Project-wide compile-sweep: RECOMPILES every Blueprint under folder_path and records error/warning counts. By far the heaviest audit here (it compiles, it does not just read metadata) and it runs synchronously in the editor -- ALWAYS scope it with folder_path on a large project, and lean on max_results, which is a hard cap. It returns only a summary plus a report path; read the detail back with read_mcp_audit_file. To find already-broken Blueprints WITHOUT recompiling anything, use find_erroring_blueprints instead.

Returns: { path: string, summary: { blueprint_count: int, clean_count: int, error_count: int, warning_count: int } }

audit_collision_profilesA

Aggregate report of every project collision profile AND every collision channel (built-in + custom), including which custom ECC_GameTraceChannelN slots are already taken -- the question to ask before add_collision_channel. Cheap: it reads the collision settings in memory, with no AssetRegistry scan and no asset loading, so unlike the other audit_* sweeps it takes no folder_path and no max_results. Returns a summary + a report path (read the detail with read_mcp_audit_file).

Returns: { path: string, summary: { profile_count: int, channel_count: int, custom_channels_in_use: int } }

audit_replicationA

Project-wide replication audit: for every Blueprint under folder_path, which variables are Replicated (CPF_Net), whether the class itself replicates (AActor::GetIsReplicated on the GeneratedClass CDO), and which UFUNCTIONs are RPCs (FUNC_NetFuncFlags). It returns only a SUMMARY plus a report path -- the full per-Blueprint detail is written to Saved/MCPAudits/ and must be read back with read_mcp_audit_file. For one actor rather than a sweep, use get_replication_info / get_actor_replication_info.

Returns: { path: string, summary: { blueprint_count: int, replicated_class_count: int, replicated_variable_count: int, rpc_count: int } }

audit_widget_accessibilityA

Sweep Widget Blueprints for the accessibility problems that are measurable from what was AUTHORED: text/background contrast against the WCAG 2.x threshold, text smaller than a legible minimum, interactive widgets with no accessible label for a screen reader, and buttons below a minimum touch/focus size. On console this is a CERTIFICATION requirement, not a nicety. READ THE LIMITS BEFORE TRUSTING A PASS: contrast is computed against the FIRST ancestor holding a solid colour -- a UBorder's brush, a UButton's WidgetStyle.Normal, or a flat UImage -- so a background painted by a texture, a material, a video or a sibling drawn underneath is INVISIBLE to this, and those cases come back as background_source:"none" rather than quietly passing, because "could not judge" and "fine" are different answers. A brush only counts when it has no ResourceObject, its TintColor is UseColor_Specified, and its DrawAs actually FILLS the middle: Box, Image or RoundedBox. DrawAs=Border is excluded on purpose (it tiles the sides and leaves the centre empty, which is exactly where the text sits). Colours coming from a CommonUI style asset or a property binding are equally invisible: only authored values are read. What IS exact is the maths -- relative luminance 0.2126R+0.7152G+0.0722B over LINEAR values (which is what an FLinearColor already is) and ratio (Llight+0.05)/(Ldark+0.05), straight from WCAG.

Returns: { folder_path, widget_blueprints_scanned, widgets_examined, issue_count, issues_by_kind: {low_contrast, contrast_unknown, small_text, missing_accessible_text, small_touch_target}, entries: [{ widget_bp_path, widget_name, widget_class, kind, detail, contrast_ratio?, required_ratio?, text_color?, background_color?, background_source?, font_size?, width?, height? }], truncated }

audit_widget_styleA

Sweep Widget Blueprints and report every widget whose style DEVIATES from a reference widget -- the "who is off-theme" question, which is the one that scales badly by hand once there are more than a couple of screens. You designate one widget as the truth (reference_bp_path + reference_widget_name), list the property paths that define the style (dotted paths work: "WidgetStyle.Normal.TintColor"), and this reports, per matching widget, which of those paths differ and what each side holds. Comparison is on the property's exported text, so it is type-agnostic and reports a real difference rather than a formatting one. Pair it with apply_widget_style_preset, which can copy those same paths off that same reference widget to FIX what this finds.

Returns: { reference, property_paths, widget_blueprints_scanned, widgets_compared, deviating_count, matching_count, entries: [{ widget_bp_path, widget_name, widget_class, deviations: [{path, actual, expected}], unresolved_paths: [string], matches: bool }], truncated }

audit_widget_textA

Sweep Widget Blueprints and report which player-visible texts are typed INLINE rather than coming from a String Table -- the localization-maintainability question. NOTE: this corrects the intuition most people start with: a text written as a bare string is NOT lost to localization. Unreal assigns it a stable key when the package is saved, and FTextInspector::ShouldGatherForLocalization returns true, so it DOES get collected and translated. What it lacks is a MEANINGFUL identity: the namespace comes out empty and the key is an opaque GUID like 971E3B3B436AEE91028BA1ADB97B3046. That still costs -- translators see no context, and re-authoring the text churns the key, orphaning the translation. So this reports identity_kind per text: string_table (best), explicit (an author-given namespace/key), auto_key (typed inline, key generated on save) and none (never saved, no identity yet). Default output is everything that is NOT string_table or explicit.

Returns: { folder_path, widget_blueprints_scanned, texts_examined, counts_by_identity: {string_table, explicit, auto_key, none}, not_gathered_count, entries: [{ widget_bp_path, widget_name, widget_class, property_name, text, identity_kind, will_be_gathered, namespace, key, string_table }], truncated } -- not_gathered_count is the engine's own ShouldGatherForLocalization saying a text will NOT be collected at all; in a saved asset that is normally 0, and anything above it is a real alarm.

capture_pie_stateA

Snapshot of every actor in the ACTIVE PIE world, with every property flagged Replicated or SaveGame (generic -- no judgment call about what is "relevant"). It requires a live PIE session: with none running for pie_client_index it errors cleanly instead of silently snapshotting the EDITOR world, which is what makes it usable as co-op evidence -- point it at a client index to prove a value really replicated. On a large world ALWAYS pass class_filter and/or max_actors. Returns a summary plus a report path; read the detail with read_mcp_audit_file.

Returns: { path: string, truncated: bool, summary: { actor_count: int, actors_seen: int, total_matching_actors: int, max_actors: int, truncated: bool, class_filter: [string], replicated_property_count: int, savegame_property_count: int, savegame_filter_status: "active"|"dead_in_this_run" }, report_size_bytes: int, verification: {...}, verification_checks: [...] } -- class_filter lists the resolved class paths; success is false when the report is missing or empty on disk.

read_mcp_audit_fileA

Read back the FULL report that an audit_* or capture_pie_state command wrote to disk. Those commands return only a summary plus a path, so this is the second half of every one of them -- without it you never see the per-Blueprint / per-asset / per-actor detail. Restricted to Saved/MCPAudits/: it is not a general file reader.

Returns: the full parsed JSON report object

add_blackboard_keyA

Append a key to a UBlackboardData asset and save it.

Returns: { blackboard_path: string, key_name: string, key_type: string, key_count: number, verified: bool, saved: bool, already_exists: bool?, save_error: string?, keys: [{ name, type, instance_synced }] }

add_bt_composite_childA

Add a child composite (Selector/Sequence/SimpleParallel) under a BehaviorTree composite. The child is appended to the parent's Children (array order = execution order). Authoring is data-only: ParentNode/ExecutionIndex are assigned by the BT runtime at load (run_behavior_tree). Idempotent by child_name within the parent. The returned child_name is how you address this composite as a parent for further children.

Returns: { behavior_tree_path: string, parent_name: string, child_name: string, child_class: string, child_kind: string, already_exists: bool, child_count: int, saved: bool, save_error?: string }

add_bt_decoratorA

Attach a decorator (execution condition) to a specific child-edge of a BehaviorTree composite. The decorator is appended to that child's Decorators array and gates whether the child may run. Authoring is data-only: ParentNode/ExecutionIndex are assigned by the BT runtime at load (run_behavior_tree). Idempotent by decorator_name within the child-edge.

Returns: { behavior_tree_path: string, parent_name: string, child_name: string, decorator_name: string, decorator_class: string, already_exists: bool, decorator_count: int, saved: bool, save_error?: string }

add_bt_serviceA

Attach a service (background tick) to a BehaviorTree composite. The service is appended to the composite's Services array and ticks while that composite branch is active. Authoring is data-only: ParentNode/ExecutionIndex are assigned by the BT runtime at load (run_behavior_tree). Idempotent by service_name within the composite.

Returns: { behavior_tree_path: string, parent_name: string, service_name: string, service_class: string, already_exists: bool, service_count: int, saved: bool, save_error?: string }

add_bt_task_childA

Add a leaf task node (Wait/MoveTo/PlaySound/RunBehavior/...) under a BehaviorTree composite. The task is appended to the parent's Children (array order = execution order). Authoring is data-only: ParentNode/ExecutionIndex are assigned by the BT runtime at load. Idempotent by child_name within the parent.

Returns: { behavior_tree_path: string, parent_name: string, child_name: string, child_class: string, child_kind: string, already_exists: bool, child_count: int, saved: bool, save_error?: string }

create_behavior_treeA

Create and save a new UBehaviorTree asset, optionally binding a blackboard.

Returns: { name: string, package_path: string, behavior_tree_path: string, asset_path: string, blackboard_asset: string?, already_exists: bool, saved: bool, save_error: string? }

create_blackboard_dataA

Create an empty UBlackboardData asset at package_path/name and save it; success requires the save. Idempotent: an existing blackboard there is returned with already_exists=true and is not re-saved. Returns blackboard_path and key_count; add keys with add_blackboard_key.

Returns: { name: string, package_path: string, blackboard_path: string, asset_path: string, key_count: number, already_exists: bool, saved: bool, save_error: string? }

get_behavior_tree_infoB

Get information about a behavior tree's structure and properties

Returns: { behavior_tree_path: string, name: string, blackboard_asset: string|null, blackboard_keys: [{ name: string, type: string, instance_synced: bool }], root_node: object|null }

get_behavior_tree_statusA

Reader: runtime BT status + active task name (if any) on an AI pawn.

Returns: { actor_name, run_status, run_status_name, active_task_name, bt_asset_name }

get_blackboard_componentA

Read the UBlackboardComponent of an editor-world actor (its AIController blackboard, else one on the actor): component_name, has_valid_asset, num_keys and the key list. Read-only. Editor world only, never PIE, where pawns are not auto-possessed; for asset keys use get_blackboard_keys_asset.

Returns: { actor_name: string, component_name: string, has_valid_asset: bool, num_keys: number, blackboard_asset: string?, keys: [{ name: string, type: string, instance_synced: bool }]? }

get_blackboard_dataB

Retrieve all key-value pairs and complete data from an actor's blackboard

Returns: { actor_name: string?, blackboard_asset: string?, name: string?, parent: string?, keys: [{ name, type, instance_synced }]?, entries: [{ name, type, value }]?, key_count: number }

get_blackboard_keysA

List blackboard key definitions (name, type, instance_synced, base_class or enum subsettings): of the running blackboard of an editor-world actor when actor_name is given, else of the UBlackboardData asset at blackboard_path. Read-only; returns keys and key_count. Editor world only, never PIE.

Returns: { actor_name: string?, blackboard_asset: string?, keys: [{ name: string, type: string, instance_synced: bool }], key_count: number }

get_blackboard_keys_assetA

Read key definitions from a UBlackboardData asset (no live component needed).

Returns: { blackboard_path: string, name: string, parent: string?, keys: [{ name: string, type: string, instance_synced: bool }], key_count: number }

get_blackboard_valueA

Read one key of the running blackboard of an editor-world actor (its AIController blackboard, else one on the actor). value is a number for Int, Float and Enum keys, a bool for Bool, else a string (objects as paths). Read-only; editor world only, never PIE.

Returns: { actor_name: string, key_name: string, key_type: string, value: number|string|bool }

pause_behavior_treeA

Pause the behavior tree of an editor-world actor (its AIController brain component, else a UBehaviorTreeComponent on the actor) with PauseLogic. paused is always true, not read back; was_running is measured. Editor world only, never PIE. Continue it with resume_behavior_tree.

Returns: { actor_name, paused, was_running }

remove_blackboard_keyA

Remove a key from a UBlackboardData asset and save it. Inverse of add_blackboard_key: drops the matching FBlackboardEntry from UBlackboardData::Keys (then UpdateKeyIDs to re-index). Addresses the key by key_name (as add_blackboard_key created it) or by index into the asset's own Keys array (parent-chain keys are not touched). Idempotent: a missing key returns removed:false / already_absent:true.

Returns: { blackboard_path: string, key_name: string, key_type: string?, removed: bool, already_absent: bool, key_count: number, saved: bool, save_error?: string, keys: [{ name, type, instance_synced }] }

remove_bt_composite_childA

Remove a child composite (Selector/Sequence/...) from a BehaviorTree composite. Inverse of add_bt_composite_child: drops the matching entry from the parent's Children array. Only composite child-edges are considered, so a task with the same name is untouched. Idempotent: a missing child returns removed:false / already_absent:true.

Returns: { behavior_tree_path: string, parent_name: string, child_name: string, child_kind: string, removed: bool, already_absent: bool, child_count: int, saved: bool, save_error?: string }

remove_bt_decoratorA

Remove a decorator (execution condition) from a specific child-edge of a BehaviorTree composite. Inverse of add_bt_decorator: drops the matching entry from that child's Decorators array (FBTCompositeChild::Decorators). Idempotent: a missing decorator returns removed:false / already_absent:true.

Returns: { behavior_tree_path: string, parent_name: string, child_name: string, decorator_name: string, removed: bool, already_absent: bool, decorator_count: int, saved: bool, save_error?: string }

remove_bt_serviceA

Remove a service (background tick) from a BehaviorTree composite. Inverse of add_bt_service: drops the matching entry from the composite's Services array (UBTCompositeNode::Services). Idempotent: a missing service returns removed:false / already_absent:true.

Returns: { behavior_tree_path: string, parent_name: string, service_name: string, removed: bool, already_absent: bool, service_count: int, saved: bool, save_error?: string }

remove_bt_task_childA

Remove a leaf task node (Wait/MoveTo/...) from a BehaviorTree composite. Inverse of add_bt_task_child: drops the matching entry from the parent's Children array. Only task child-edges are considered, so a composite with the same name is untouched. Idempotent: a missing child returns removed:false / already_absent:true.

Returns: { behavior_tree_path: string, parent_name: string, child_name: string, child_kind: string, removed: bool, already_absent: bool, child_count: int, saved: bool, save_error?: string }

restart_behavior_treeA

Restart the current behavior tree of an editor-world actor from its root (RestartTree), through its AIController brain component or a UBehaviorTreeComponent on the actor. restarted is always true, not measured: check get_behavior_tree_status. Editor world only, never PIE.

resume_behavior_treeA

Resume a behavior tree paused by pause_behavior_tree (ResumeLogic) on an editor-world actor, through its AIController brain component or a UBehaviorTreeComponent on the actor. Returns was_paused and is_paused, both read from the component. Editor world only, never PIE.

run_behavior_treeA

Start a BehaviorTree asset with AAIController::RunBehaviorTree on an AIController or the pawn it possesses. The actor is searched in the editor world only, never PIE, where pawns are not auto-possessed, so it usually errors with no AIController. Returns started and ai_controller; nothing is saved.

Returns: { actor_name: string, behavior_tree_path: string, started: bool, ai_controller: string }

set_behavior_tree_rootA

Set a BehaviorTree's RootNode to a new composite (Selector or Sequence) and save.

Returns: { behavior_tree_path: string, composite: string, has_root_node: bool, root_node_class: string, saved: bool, save_error: string? }

set_blackboard_key_subsettingsA

Constrain an existing blackboard key's subsettings on a UBlackboardData asset and save. This is the SECOND HALF of add_blackboard_key, which only sets EntryName/KeyType/bInstanceSynced: it fills the per-type filter the editor would otherwise make you pick by hand -- BaseClass for an Object/Class key, EnumType for an Enum key. At least one of base_class / enum_type is required, and the one you supply must match the key's type.

Returns: { blackboard_path: string, key_name: string, key_type: string, base_class: string?, enum_type: string?, enum_name: string?, already_set: bool, saved: bool, save_error: string?, keys: [...] }

set_blackboard_valueA

Write one key of the running blackboard of an editor-world actor, converting the value string by key type. Not read back: set is always true, and an unparsable number or vector is written as 0. Runtime state only, nothing saved; editor world only, never PIE. Verify with get_blackboard_value.

Returns: { actor_name: string, key_name: string, key_type: string, value: string, set: bool }

stop_behavior_treeA

Stop the behavior tree of an editor-world actor with StopTree (Safe mode), through its AIController brain component or else a UBehaviorTreeComponent on the actor. Runtime state only, nothing saved; editor world only, never PIE. was_running is read before the stop (running and not paused); stopped is true when a started tree, running or paused, is no longer started afterwards. A tree that was not started is not an error: success with stopped false and a note. A tree still started after the call (a task still aborting) is an error. An unknown actor, or one with no behavior tree component, is an error. Unlike pause_behavior_tree it cannot be continued with resume_behavior_tree: start again with restart_behavior_tree (the last tree) or run_behavior_tree.

Returns: { actor_name: string, was_running: bool, stopped: bool, note?: string }

add_actor_begin_overlap_eventA

Add a real AActor event OVERRIDE node (bOverrideFunction set, so it is not an eclipsed stub) -- ReceiveActorBeginOverlap by default, or any other AActor event via event_name (ReceiveActorEndOverlap, ReceiveHit, ReceiveBeginPlay...) -- and compile. Idempotent: an existing override of that event in the graph is returned with already_exists:true. It only reaches events declared on the ACTOR; for a component's delegate use add_component_bound_event, and for an interface member use override_interface_member.

Returns: { node_id, class, title, pins:[...the event's output params...], blueprint_name, graph_name, event_name, is_override, already_exists? } -- is_override:true is what distinguishes a live override from a dead look-alike; already_exists is only present when an existing node was reused.

add_ai_perception_senseA

Configure a sight or hearing sense on an AIPerceptionComponent TEMPLATE of a Blueprint, creating the config as an Instanced subobject of the template so it persists with the asset, and saving the package. Idempotent: ConfigureSense dedups by config class, so re-calling with the same sense_type UPDATES the existing config in place instead of stacking a second one. Only "sight" and "hearing" are supported (no damage, touch or team senses). It authors the TEMPLATE only -- whether the AI actually perceives anything is a live-PIE question this cannot answer; read the authored result back with get_ai_perception_senses.

Returns: { blueprint_name, component_name, sense_type, config_class, , note }

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.2/5.0

Scored across 2097 tools

Disambiguation2/5

Despite descriptions that frequently police each other ('prefer X over Y', 'use this instead of...'), the set is riddled with near-duplicates: get_actor_components vs get_actor_references, get_blueprint_components vs get_blueprint_components_list vs get_blueprint_scs_tree, configure_gravity vs set_world_gravity vs set_physics_gravity, get_undo_state vs can_undo vs can_redo, and four DataTable row readers with subtly different fidelity. An agent can usually stumble onto the right one because the prose is extremely explicit, but selection is a real cost, not a non-issue, across 2000 tools. Overlapping purposes are pervasive rather than occasional.

Naming Consistency3/5

The dominant pattern is snake_case verb_noun (get_actor_label, set_actor_folder, add_light), but it is layered with many domain prefixes (interchange_, niagara_, pcg_, usd_, metasound_, anim_, rig_, hlod_, eqs_) and abbreviations (bp_, gc_, rvt_, bt_, ism_, mid_, mcp_). A few names are bare words with no verb (batch, region_start, bookmark), and reading-direction pairs like get_ vs has_ vs list_ vs read_ are used inconsistently for the same question. Readable, but a mixed convention rather than a single predictable one.

Tool Count1/5

2097 tools is an extreme mismatch under any reading of the server's scope; even accounting for Unreal's breadth, dozens of near-duplicate readers/writers per subsystem inflate the surface far beyond what is needed. This is well past the '50+ tools' ceiling, and the count itself is the primary coherence problem.

Completeness4/5

Coverage is close to total: CRUD, lifecycle, read-back oracles and edge-case handling exist for actors, Blueprints, materials, Niagara, PCG, StateTree, Sequencer, USD and more, including deliberate honest gates where the engine has no headless path. A handful of genuinely acknowledged dead ends exist (set_preserve_scale_ratio does nothing, list_mass_signals always empty, several delegate/drag-drop gaps), but these are documented rather than surprising.

Maintenance

ActivityMaintained
ResponsivenessNo issues