Management¶
23 tools. Back to the index.
add_primary_asset_rule¶
Destructive, idempotent.
Add a PrimaryAssetTypesToScan rule to the Asset Manager project settings, or update the rule of that type, then write DefaultGame.ini (no undo); a failed write makes success false. An update always resets the base class (to UObject when base_class_path is omitted), appends directory unless already listed and sets priority only when given; idempotent. Nothing is rescanned: run scan_primary_assets so the running Asset Manager registers the assets. Cook rules: set_primary_asset_cook_rule; inverse: remove_primary_asset_rule; list rules: get_primary_asset_types.
| Parameter | Type | Required | Description |
|---|---|---|---|
primary_asset_type |
string | yes | Logical type name, e.g. "Item" |
base_class_path |
string | no | Asset base class path (defaults to UObject) |
directory |
string | no | Content directory to scan for this type |
priority |
number | no | Scan rule priority (optional) |
Returns: { type, base_class, saved, updated_existing, directory_count, type_count }
audit_class_purity¶
Read-only.
Project-wide "fork purity" audit of INHERITANCE lineage (complements audit_fork_refs, which audits a fork's INTERNAL refs). Walks every Blueprint UClass under class_root, ascends each parent chain to the point where it leaves class_root, and flags any project class whose chain crosses DIRECTLY into an upstream base library (base_libraries, e.g. /Game/VendorPack) WITHOUT going through a declared thin fork -- a class carrying the fork-origin metadata tag (project setting Fork Origin Tag) that fork_class_chain writes. Catches a new asset that inherits straight from a vendored library instead of via a project fork. Read-only: classes are loaded to resolve the chain (like audit_replication) but never saved. Returns a summary plus the full per-class classification and the actionable violation list inline. NOTE: matches exact UBlueprint assets (as audit_replication/audit_fork_refs do); Widget/Anim blueprints are out of scope for v1. A legit fork created without the fork-origin tag reports as a violation -- back-fill it with set_asset_metadata_tag. The tag is also CHECKED FOR TRUTH, not just for presence: the class it names must really be in the fork point's ancestor chain (the full chain, so declaring a grandparent is fine). A class that declares a fork origin it does not actually descend from -- a copy-sibling rather than a child, or a stale tag left behind by a re-parent -- reports verdict fork_origin_mismatch, whatever its boundary looks like; that also catches copies parented straight to a native class, which the boundary check alone would wave through as native_rooted.
| Parameter | Type | Required | Description |
|---|---|---|---|
class_root |
string | no | Own content tree to audit. Defaults to the project setting Project Content Root ("/Game" unless configured). |
base_libraries |
array | no | Array of upstream roots a project class must not inherit from directly. Defaults to the project's Read Only Content Roots. |
recursive |
boolean | no | Optional bool (default true). Recurse into subfolders. |
max_results |
number | no | Cap on classes processed (clamped 1..100000). Defaults to 5000. |
max_depth |
number | no | Max parent-chain steps to ascend within class_root (clamped 1..256). Defaults to 32. |
Returns: { class_root: string, base_libraries: [string], summary: { class_count: int, pure_fork_count: int, native_rooted_count: int, other_parent_count: int, violation_count: int (missing_fork_tag + fork_origin_mismatch; == violations.length), missing_fork_tag_count: int, fork_origin_mismatch_count: int, distinct_impure_fork_points: int }, classes: [{ class, package, immediate_parent, fork_point, boundary_parent, boundary_kind, boundary_library, is_declared_fork, fork_origin, fork_origin_in_chain: bool, fork_origin_matched_ancestor: string, fork_origin_exists: bool, verdict: "pure_fork"|"native_rooted"|"other_parent"|"violation"|"fork_origin_mismatch" }], violations: [{ class, kind: "missing_fork_tag"|"fork_origin_mismatch", fork_point, boundary_parent, boundary_library, declared_fork_origin?, actual_immediate_parent?, fork_origin_exists?, actual_ancestor_chain?: [string], detail? }], message: string }
audit_fork_refs¶
Destructive.
Audit a fork subtree for references that still point at the SOURCE tree it was copied from (duplicate_asset / duplicate_directory by script do NOT remap internal refs, so a copy keeps pointing at the original -- e.g. a MaterialInstance Parent still under /Game/VendorPack). Reports, per fork asset, the source dependencies (authoritative, from the AssetRegistry) and, best-effort, the exact PROPERTY holding each source object ref. With fix=true it FArchiveReplaceObjectRefs each source object to a same-named counterpart found inside the fork and saves the asset.
| Parameter | Type | Required | Description |
|---|---|---|---|
fork_root |
string | yes | Fork content path to audit, e.g. '/Game/MyGame/Environment/AutoLandscape'. |
source_root |
string | no | Origin tree the refs should not point at (optional; defaults to the project's Read Only Content Root when exactly one is configured). |
include_properties |
boolean | no | Optional bool (default true). Load each offending asset and report which property holds each source ref (best-effort; the dependency list is authoritative). |
fix |
boolean | no | Optional bool (default false). Remap source object refs to a same-named fork counterpart via FArchiveReplaceObjectRef and save the asset. |
max_assets |
number | no | Max fork assets to scan (optional, default 2000; clamped 1..20000). |
dependency_type |
string | no | Optional string, one of "hard"|"soft"|"all" (case-insensitive, default "all"). Scopes the per-asset dependency scan: "hard" surfaces only load-bearing refs into source_root (e.g. a MaterialInstance Parent, a hard object property) -- the correctness-critical case this audit exists for; "soft" surfaces only soft/lazy refs (TSoftObjectPtr, FSoftObjectPath); "all" (default) leaves the scan unscoped. |
Returns: { fork_root: string, source_root: string, fix: bool, dependency_type: string, assets_scanned: int, offending_count: int, total_source_dependencies: int, offenders: [{asset, package, source_dependencies:[string], properties:[{property, ref}], remapped:int}], fixed_assets: int, refs_remapped: int, unresolved_counterparts: [string], message: string }
configure_plugin_setting¶
Destructive, idempotent.
Write one key=value under a plugin config section through GConfig into GEngineIni (the Saved/Config user layer, not the versioned Config/DefaultEngine.ini), then read it back from the GConfig cache. Succeeds only when the read-back value matches; an unknown plugin fails without writing anything. For versioned settings use set_project_settings_value.
| Parameter | Type | Required | Description |
|---|---|---|---|
plugin_name |
string | yes | Name of the plugin to configure |
setting_name |
string | yes | Name of the plugin setting to configure |
setting_value |
string | yes | Value to set for the plugin setting |
section |
string | no | INI section name without brackets (optional, default "/Script/<Plugin>.<Plugin>") |
Returns: { plugin_name: string, setting_name: string, setting_value: string, plugin_path: string, plugin_status: string, plugin_version: string, plugin_loaded: bool, plugin_enabled: bool, readback_value: string, config_file_path: string?, section: string, configuration_success: bool, configuration_message: string, config_file_used: string, plugin_description: string, plugin_author: string, plugin_category: string, plugin_file: string, configuration_timestamp: string }
delete_asset¶
Destructive.
Force-delete one asset with no confirmation or undo: references to it are nulled, the object is purged and its .uasset/.umap file removed from disk. Check get_asset_referencers first. Succeeds only when the file is gone from disk and the object from memory: a file left behind (read-only, or held open by another process) fails the call with file_still_exists true, and the asset comes back when the editor restarts.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_path |
string | yes | Asset to delete, as an object path ("/Game/Props/SM_Box.SM_Box") or a bare package path ("/Game/Props/SM_Box") |
Returns: { asset_path: string, object_path: string, asset_class: string, package_name: string, original_file_size_bytes: number, original_file_size_mb: number, delete_success: bool, delete_message: string, asset_verified_deleted: bool, file_still_exists: bool, deletion_timestamp: string? }
duplicate_asset¶
Additive.
Duplicates an asset to a new name in the same directory, then PERSISTS the copy to disk immediately (unless Play-In-Editor is active -- see the "saved"/"save_error" note on the save step below; a duplicate is very often used AS a safety net before a risky edit, so leaving it memory-only defeats the point). By default (remap_internal_refs absent/false) this is otherwise a plain copy: like EditorAssetLibrary.duplicate_asset, any internal references the copy holds still point at the ORIGINAL (not remapped). Set remap_internal_refs=true to run the SAME 2nd-pass reference remap that duplicate_directory uses (FArchiveReplaceObjectRef mapping original->copy) so the copy's own self-references point at the copy, before that save. repoint_parents_within additionally re-applies a MaterialInstance parent via SetParentEditorOnly when the parent maps into the copied set (for a single asset this only fires if the copy's parent is the original itself).
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_path |
string | yes | Full asset path to duplicate (e.g. /Game/Assets/MyAsset) |
new_asset_name |
string | yes | Name for the duplicated asset |
remap_internal_refs |
boolean | no | Optional bool (default false). When true, remap the copy's internal refs (original->copy) before the save; adds { new_path, refs_remapped } to the result. |
repoint_parents_within |
boolean | no | Optional bool (default false). When true (and remap_internal_refs true), also re-apply MaterialInstanceConstant parents that map into the copied set via SetParentEditorOnly. |
Returns: { original_asset_path: string, new_asset_name: string, new_asset_path: string, duplication_success: bool, duplication_message: string, new_asset_class: string, new_package_name: string, asset_verified: bool, new_file_size_bytes: number?, new_file_size_mb: number?, original_asset_class: string, original_package_name: string, new_path: string?, refs_remapped: int?, saved: bool?, save_error: string? }
duplicate_directory¶
Destructive.
Recursively copy a content folder to a new path, REMAPPING references among the copied assets so the new subtree points at its own copies (true graph isolation) while references to assets OUTSIDE the set stay shared with the originals (the "copy what you modify, share the rest" policy). Unlike EditorAssetLibrary.DuplicateDirectory / duplicate_asset (which copy without remapping, so copies keep pointing at the originals), this duplicates every asset then runs a second reference-replacement pass with the full old->new map, and saves the copies. Intended for material/instance/texture/data-asset libraries; Blueprints may need a recompile and maps (UWorld) are not handled specially.
| Parameter | Type | Required | Description |
|---|---|---|---|
source_path |
string | yes | Source content folder, e.g. /Game/VendorPack/Environment/AutoLandscape |
dest_path |
string | yes | Destination content folder, e.g. /Game/MyGame/Environment/AutoLandscape |
Returns: { source_path: string, dest_path: string, source_asset_count: int, duplicated_count: int, remapped: bool, new_asset_paths: [string] }
get_all_primary_asset_types¶
Read-only.
Get all registered primary asset types from the Asset Manager.
No parameters.
Returns: { name, asset_class, num_assets, types, count }
get_asset_bundle_data¶
Read-only.
Read the AssetBundles tag of one asset from the Asset Registry without loading it: each bundle with bundle_name, asset_paths and num_assets, plus bundle_count and asset_found. An asset with no bundles, or not found, returns an empty list rather than an error. Read-only.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_path |
string | yes | Full object path including the object name, e.g. /Game/MyGame/M_Example.M_Example; a package-only path does not resolve to the asset. |
Returns: { bundle_name, asset_paths, num_assets, asset_path, asset_found, bundles, bundle_count }
get_asset_bundle_entry¶
Read-only.
Read one named asset bundle of a primary asset from the running Asset Manager's bundle cache (UAssetManager::GetAssetBundleEntry), loading nothing: bundle_objects lists the asset paths in it. Only scanned primary assets are cached, so an unscanned asset, an unknown bundle, a malformed id or an empty bundle all give found=false with an empty list, not an error. For every bundle of one asset by object path, read from the Asset Registry, use get_asset_bundle_data; get_primary_asset_id turns a path into the id.
| Parameter | Type | Required | Description |
|---|---|---|---|
primary_asset_id |
string | yes | Primary asset ID in "Type:Name" format |
bundle_name |
string | yes | Name of the asset bundle |
Returns: { primary_asset_id, bundle_name, bundle_objects, found }
get_plugin_status¶
Read-only.
Read one plugin by name, read-only: Enabled or Disabled, version, author, category, base dir, .uplugin file, dependencies and modules. An unknown name returns plugin_status "Not Found" with "N/A" fields, not an error. plugin_loaded only mirrors plugin_enabled, and plugin_created_date holds the CreatedByURL.
| Parameter | Type | Required | Description |
|---|---|---|---|
plugin_name |
string | yes | Name of the plugin to query, as its .uplugin file is named (e.g. "UEAgent") |
Returns: { plugin_name: string, plugin_status: string, plugin_version: string, plugin_description: string, plugin_author: string, plugin_created_date: string, plugin_category: string, plugin_loaded: bool, plugin_enabled: bool, plugin_path: string, plugin_file: string, plugin_dependencies: [{ name: string, enabled: bool, optional: bool, version: string }], plugin_modules: [{ name: string, type: string, loading_phase: bool }], plugin_message: string, plugin_manager_version: string, plugin_search_paths: string, plugin_status_timestamp: string }
get_primary_asset_cook_rules¶
Read-only.
Read the Priority / ChunkId / bApplyRecursively / CookRule for a single primary asset type.
| Parameter | Type | Required | Description |
|---|---|---|---|
primary_asset_type |
string | yes | Name of the primary asset type (e.g. "Item"). |
Returns: { primary_asset_type, cook_rule, priority, chunk_id, apply_recursively }
get_primary_asset_id¶
Read-only.
Look up the registered Primary Asset Id ("Type:Name") of an asset path: primary_asset_id, is_valid and, when valid, primary_asset_type and primary_asset_name. A non-primary or unscanned asset gives is_valid=false, not an error. get_primary_asset_id_from_path is the same lookup without the split fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_path |
string | yes | Full object path including the object name, e.g. /Game/MyGame/M_Example.M_Example; a package-only path does not match. |
Returns: { asset_path, primary_asset_id, is_valid, primary_asset_type, primary_asset_name }
get_primary_asset_id_from_path¶
Read-only.
Get the primary asset ID for a given object path.
| Parameter | Type | Required | Description |
|---|---|---|---|
object_path |
string | yes | Full object path (e.g. /Game/MyAsset.MyAsset) |
Returns: { object_path, primary_asset_id, is_valid }
get_primary_asset_ids_by_type¶
Read-only.
List the Primary Asset Ids the running Asset Manager has registered for one type: asset_ids entries with type, name and full_id, plus count; success is false when none are found, unknown type included. Only scanned assets appear (see scan_primary_assets). Read-only.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_type_name |
string | yes | Name of the primary asset type, e.g. "Item". |
filter |
string | no | "unloaded_only" keeps only assets with no current or pending bundle state (not loaded through the Asset Manager); omitted or any other value lists all. |
Returns: { type, name, full_id, asset_type_name, success, asset_ids, count }
get_primary_asset_type_info¶
Read-only.
Read what the running Asset Manager holds for one primary asset type: asset_class, has_blueprint_classes, is_editor_only, num_assets from the last scan and its directories. found=false for a type it does not know, not an error; get_primary_asset_types reads the configured rules instead.
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_type_name |
string | yes | Name of the primary asset type (e.g. "Item") |
Returns: { asset_type_name, found, asset_class, has_blueprint_classes, is_editor_only, num_assets, directories }
get_primary_asset_types¶
Read-only.
Read the configured Primary Asset Types from the Asset Manager settings.
No parameters.
Returns: { types, type_count }
move_asset¶
Destructive.
Moves an asset to a new folder while keeping its name. GUARDED exactly like rename_asset (it reaches the same FAssetRenameManager through UEditorAssetLibrary::RenameAsset): (1) read-only roots are refused -- and here BOTH ends are checked, source and destination, since a move can also drop an asset INTO the upstream tree; (2) a native CDO hard-reference makes it refuse before the engine can open its blocking modal; (3) the outcome is read back from memory+disk instead of trusting the returned bool, which stays true even when the new package failed to save (the engine only reacts to that when UE source control is connected).
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_path |
string | yes | Full asset path to move |
new_folder_path |
string | yes | Destination folder path (e.g. /Game/NewFolder) |
readonly_roots |
array | no | Optional array of content roots that must never be written (checked on source AND destination). Absent => the project's Read Only Content Roots. An EXPLICIT [] disables the guard. (Read through mcp_common::ParseReadonlyRoots, so the type hint is what puts it in the catalog.) |
check_cdo_references |
boolean | no | Optional bool (default true). Scan native CDOs for a hard reference to the asset and refuse instead of letting the engine open a modal. |
Returns: { original_asset_path: string, new_folder_path: string, new_asset_path: string, move_success: bool, move_message: string, new_asset_class: string, new_package_name: string, asset_verified: bool, new_file_size_bytes: number?, new_file_size_mb: number?, original_file_exists: bool?, original_asset_class: string, original_package_name: string, new_object_resolves: bool?, new_file_on_disk: bool?, new_file_path: string?, redirector_left: bool?, verification: object?, verification_checks: [object]?, would_block_on_modal: bool?, cdo_referencing_class: string?, cdo_soft_reference_check: string? }
remove_primary_asset_rule¶
Destructive.
Remove every PrimaryAssetTypesToScan entry of one type from the Asset Manager project settings and write DefaultGame.ini; an unknown type is an error. Returns removed_count, type_count_after and saved. The running Asset Manager is not refreshed, so its scanned data for the type remains.
| Parameter | Type | Required | Description |
|---|---|---|---|
primary_asset_type |
string | yes | Name of the primary asset type to remove, e.g. "Item". |
Returns: { primary_asset_type, removed_count, type_count_after, saved }
rename_asset¶
Destructive.
Renames an asset to a new name in its current directory. GUARDED (both guards are shared with move_asset, and both come from the AssetRenameManager source -- see the comment block on AnyNativeCdoHardReferences): (1) refuses to touch anything under a read-only root (readonly_roots, default: the project's Read Only Content Roots -- the upstream tree is never mutated in place); (2) refuses BEFORE calling the engine when a native class' CDO hard-references the asset, because FAssetRenameManager would open an FMessageDialog there and block the game thread (which kills the MCP session). And it does not trust IAssetTools::RenameAssets' return value: the result is READ BACK (new object resolves + new package on disk + redirector left at the original path), because the engine silently drops packages that failed to save unless UE source control is connected (with plain git it never is).
| Parameter | Type | Required | Description |
|---|---|---|---|
asset_path |
string | yes | Full asset path to rename |
new_asset_name |
string | yes | New name for the asset |
readonly_roots |
array | no | Optional array of content roots that must never be written. Absent => the project's Read Only Content Roots. An EXPLICIT [] disables the guard. (Read through mcp_common::ParseReadonlyRoots, so the type hint is what puts it in the catalog.) |
check_cdo_references |
boolean | no | Optional bool (default true). Scan native CDOs for a hard reference to the asset and refuse instead of letting the engine open a modal. Set false to skip the scan (faster, but a modal can then hang the editor). |
Returns: { original_asset_path: string, new_asset_name: string, new_asset_path: string, rename_success: bool, rename_message: string, new_asset_class: string, new_package_name: string, asset_verified: bool, new_file_size_bytes: number?, new_file_size_mb: number?, original_file_exists: bool?, original_asset_class: string, original_package_name: string, new_object_resolves: bool?, new_file_on_disk: bool?, new_file_path: string?, redirector_left: bool?, verification: object?, verification_checks: [object]?, would_block_on_modal: bool?, cdo_referencing_class: string?, cdo_soft_reference_check: string? }
run_external_project_script¶
Destructive.
Spawn a SEPARATE headless UnrealEditor-Cmd.exe to run a python script against an EXTERNAL project and capture its stdout. Needed because another project's /Game packages collide with the live project's (they cannot be loaded side by side), so reading data from content outside this project needs an isolated editor. Give it an existing .uproject OR a module_dir (a minimal engine-only .uproject is cloned in place, with any 'disable_plugins' turned off, then deleted); it launches <uproject> -run=pythonscript -script=<script> -unattended -nullrhi -NoLiveCoding -stdout, blocks until exit or timeout, and returns stdout. HEAVY: spawns a full editor process (tens of seconds) and BLOCKS the editor for the duration -- run with confirmation. The engine binary is resolved from THIS editor's install (FPaths::EngineDir); no path is assumed.
| Parameter | Type | Required | Description |
|---|---|---|---|
script |
string | yes | Absolute path to the .py file to run (the -script argument). |
uproject |
string | no | Path to an existing external .uproject to run against (optional; provide this OR module_dir). |
module_dir |
string | no | Directory of a content folder or project whose Content to load; a temporary engine-only .uproject is cloned here and cleaned up (optional; provide this OR uproject). |
disable_plugins |
array | no | Optional list of plugin names to disable in the CLONED .uproject (e.g. custom plugins that hang headless startup). Only applies when module_dir is used. |
extra_args |
array | no | Optional list of extra command-line tokens appended to the launch. |
timeout_seconds |
number | no | Max seconds to wait before terminating the child (optional, default 300; clamped 30..3600). |
Returns: { exe: string, uproject_used: string, cloned: bool, script: string, params: string, launched: bool, exit_code: int, success: bool, timed_out: bool, duration_seconds: number, stdout: string, stdout_length: int, stdout_file: string, cleaned_up: bool, message: string }
scan_primary_assets¶
Read-only.
Synchronously rescan the directories and specific assets of every PrimaryAssetTypesToScan rule (or only primary_asset_type) so the Asset Manager registers their primary assets; rules without paths are skipped. Returns num_assets_found, types_scanned and per-type scanned_types. Run it after add_primary_asset_rule.
| Parameter | Type | Required | Description |
|---|---|---|---|
primary_asset_type |
string | no | Configured type name to scan alone, e.g. "Item"; omitted or empty scans every rule, and an unknown name scans nothing (types_scanned=0). |
Returns: { type, num_assets_found, num_paths, scanned, types_scanned, scanned_types }
set_primary_asset_cook_rule¶
Destructive, idempotent.
Set the CookRule of an existing PrimaryAssetTypesToScan rule in the Asset Manager project settings, plus ChunkId and bApplyRecursively when given, then write DefaultGame.ini (no undo); a failed write makes success false. An unknown type (add it with add_primary_asset_rule) or cook_rule is an error before any change. Priority is not touched here; add_primary_asset_rule sets it. Nothing is rescanned. Read the rules back with get_primary_asset_cook_rules; the reply's cook_rule is the short name of the stored rule.
| Parameter | Type | Required | Description |
|---|---|---|---|
primary_asset_type |
string | yes | Name of the primary asset type (e.g. "Item"). |
cook_rule |
string | yes | One of "Unknown" / "Never" / "Development" / "DevelopmentAlways" / "Always", case-insensitive; "Development" stores ProductionNeverCook, and the EPrimaryAssetCookRule names (e.g. "AlwaysCook", "DevelopmentAlwaysProductionUnknownCook") are accepted too. |
chunk_id |
number | no | Optional chunk ID override for the rule |
apply_recursively |
boolean | no | Optional flag to apply the rule recursively |
Returns: { primary_asset_type, cook_rule, priority, chunk_id, apply_recursively, saved }