Manifests & Batch Assets

A manifest is a .mhajson file that captures the complete state of a batch queue — global settings, every job and its options, and the artifact records written after processing. Manifests auto-save on completion and can be exported, shared, and reloaded. The same state can also be saved as a batch asset that lives in the project.

Auto-save location

After every batch run the active manifest is written automatically to:

YourProject/Saved/MHAManager/batch.mhajson

This file is overwritten each run. To preserve a specific queue, save it as a batch asset from the toolbar, or write a named copy with the save_manifest MCP tool (anywhere inside the project's Saved folder).

Top-level structure

{
  "schema_version": 1,
  "plugin_version": "2.12.0",
  "settings": { ... },
  "jobs": [ ... ]
}
schema_version Int Used by the loader to detect incompatible manifests from future versions.
plugin_version String VersionName of the MHA Manager plugin that wrote the file, for diagnosing manifests produced by a different build.
settings Object Snapshot of all Global Settings at the time the manifest was saved, including the per-category solve default templates. Restored on load.
jobs Array Ordered list of job objects. Processed top to bottom.

Settings block

"settings": {
  "use_custom_output_path": false,
  "output_path": "/Game/CaptureManager/Export",
  "ue_export_flat": true,
  "skip_if_already_solved": true,
  "export_anim_sequence": true,
  "reduce_control_rig_keys": true,
  "export_level_sequence": true,
  "bind_face_to_audio_level_sequence": true,
  "level_sequence_lighting_environment": "Portrait",
  "performance_viewport_lighting_environment": "Portrait",
  "performance_viewport_hair": false,
  "custom_lighting_environment_folder": "/Game/LightingEnvironments",
  "export_for_dcc": false,
  "export_dcc_audio": true,
  "dcc_export_directory": "",
  "dcc_export_layout": "PerTake",
  "overwrite_existing": true,
  "force_export_animation": false,
  "auto_open_after_export": false,
  "use_metahuman_id_for_output_mesh": true,
  "target_skeleton_or_skeletal_mesh": "",
  "add_skeleton_compatibility": true,
  "body_target_skeletal_mesh_global": "/MetaHumanBodyTracker/SKM_Body.SKM_Body",
  "retargeter_output_path": "/Game/CaptureManager/BodyTrackerTargets",
  "board_pattern_width": 11,
  "board_pattern_height": 16,
  "board_square_size": 0.75,
  "override_default_board": false,
  "calibration_sharpness_threshold": 5.0,
  "calibration_board_presets": [],
  "max_calibration_rms_error": 1.0,
  "min_calibration_diagnostics_score": 0.5,
  "rejected_calibration_paths": [],
  "export_calibration_json": false,
  "clean_depth": false,
  "prefer_depth_solve_for_depth_takes": true,
  "auto_queue_ingested_takes": true,
  "auto_run_ingested_takes": false,
  "auto_categorize_stereo_takes_by_name": true,
  "stereo_calibration_name_patterns": ["*grid*", "*calibration*", "*calib*"],
  "stereo_identity_name_patterns": ["*identity*", "*dna*"],
  "enable_mcp_toolset": true,
  "linked_batch_asset": "/Game/Batches/ShootDay1.ShootDay1",
  "timing_calibration": [ ... ],
  "default_job_options_by_category": {
    "mono":   { ... },
    "depth":  { ... },
    "audio":  { ... }
  },
  "default_job_options": { ... },
  "column_layout": [
    { "id": "SolveType", "visible": true, "width": 96 },
    ...
  ]
}

rejected_calibration_paths keeps calibrations judged too poor to trust out of every lookup; calibration_sharpness_threshold and the board pattern fields are learned state (the auto-tuned winner from the last solve) unless override_default_board is on, in which case the board fields are your pinned dimensions. timing_calibration holds the four per-job-type ETA samples. linked_batch_asset is written only while a batch asset is linked. default_control_rig_class is read from older manifests but no longer written.

default_job_options_by_category holds the per-category solve default templates — one sub-object per category (Mono / Depth / Audio) using the same keys as a job's options block. The depth template was written as "stereo" before 2026-09 and either key still loads. default_job_options is the legacy single-template key, kept so older plugin builds can still read the manifest; a manifest that has only the legacy key seeds all three categories from it on load.

column_layout stores which columns are visible, their order, and widths in the queue view. Restoring a manifest on a different machine applies the same column layout.

Job object

{
  "id": "A1B2C3D4-E5F6-...",
  "name": "Scene_01_Take_03",
  "input_type": "Mono",
  "type_pinned": true,
  "footage_capture_data": "/Game/Captures/Scene01/Take03.Take03",
  "identity": "",
  "status": "pending",
  "processing_time_secs": 142.5,
  "footage_framing": "FullBody",
  "framing_detail": "frame 0001.png: face 0.82 / hips 0.71 / ...",
  "body_coverage_pct": 0.97,
  "options": { ... },
  "depth_sequences": [ ... ],
  "artifacts": [ ... ]
}
id String (GUID) Unique identifier generated per job. Stable across re-saves — used to correlate artifact records.
name String Display name shown in the queue row. Defaults to the Capture Data asset name.
input_type "Mono" | "Stereo" | "Depth" | "Other" | "Audio" | "Calibrate" | "Identity" Determines the pipeline and which solve options are used. "CalibrateStereo" and "IdentityCreate" are accepted on load as pre-rename aliases but are never written.
type_pinned Bool Set when a person picked the Type by hand; omitted when false. A pinned job keeps its type through auto-classification and through Retry.
footage_capture_data String (object path) Object path to the UFootageCaptureData asset.
identity String Object path to the UMetaHumanIdentity. Used by the depth family (Stereo, Depth, Other) and written by an Identity job; empty for Mono, Audio, and Calibration jobs.
status "pending" | "done" | "failed" | "skipped" Job outcome from the last run. Running jobs are saved as pending.
processing_time_secs Number Wall-clock solve time from the last run. Stereo jobs additionally record depth_generation_time_secs and depth_cleaning_time_secs.
footage_framing "FullBody" | "UpperBody" | "Headshot" Framing probe verdict, with framing_detail holding the per-joint confidence summary. Omitted until the take has been probed — persisting it means re-loaded queues don't re-probe.
body_coverage_pct Number (0-1) Post-solve body detection coverage for body-tracked jobs. Omitted until measured. Calibration jobs record calibration_rms_error and calibration_selected_frames instead.
options Object All per-job solve options for this take. See Per-Job Options for the full list.
depth_sequences Array Per-depth-sequence metadata for Stereo jobs — sequence path, frame range, depth scale, generation source, and camera name. Empty or absent for other job types.
artifacts Array Records of assets generated by this job. Written after processing completes.

Artifact records

"artifacts": [
  {
    "asset_path": "/Game/CaptureManager/Export/Scene01_Take03_Performance.Scene01_Take03_Performance",
    "type": "Performance",
    "state": "Complete",
    "stage_created_by": "ProcessPerformance",
    "created_at": "2026-07-08T09:32:11Z",
    "disk_path": ""
  },
  {
    "asset_path": "/Game/CaptureManager/Export/Scene01_Take03_Anim.Scene01_Take03_Anim",
    "type": "AnimSequence",
    "state": "Complete",
    "stage_created_by": "ExportOutputs",
    "created_at": "2026-07-08T09:34:02Z",
    "disk_path": ""
  }
]
type String "Performance", "AnimSequence", "LevelSequence", "Identity", "CaptureData", "CameraCalibration", "ControlRigFBX", "DCCFBX", "AudioWav", "Log", or "Other".
asset_path String Object path where the asset was written. FBX artifacts use disk_path for their filesystem location instead.
state "Complete" | "Partial" | "Failed" | "Unknown" Outcome of this specific artifact. A job can be Complete overall while an optional export is Partial.
stage_created_by String Which pipeline stage produced the artifact.
created_at ISO 8601 timestamp UTC time when the asset was written.

Batch assets

A batch asset is the same data wearing a different coat: the recipe (global settings plus every job definition) and whatever the last run produced, captured as an asset in the content tree instead of a file under Saved/.

It does not replace the manifest. The .mhajson file stays the persistence layer — crash-recovery autosave, the headless commandlet, and MCP polling all run on it. The asset is the shareable face of the same state: it lives in /Game, so it commits to source control, diffs, and travels with the project. That is what puts a job's provenance — a Wwise sound id and its event, say — next to the Performance it produced, instead of in a gitignored file on one machine.

Action Where What it does
Save Queue As Batch Asset... Batch Asset menu Writes the whole queue and its global settings to a new asset in the Content Browser.
Save Batch Asset Batch Asset menu Writes the queue back to the asset it was loaded from. Enabled only while there are unsaved changes.
Load Queue From Batch Asset... Batch Asset menu Replaces the current queue and global settings with a saved asset. Unavailable while a batch is running.

Once a queue is linked to an asset, the toolbar button shows its name, with a trailing * for unsaved changes — the same convention the rest of the editor uses. Batch assets are editor-only and never cook into a build.

Use a manifest for machine-to-machine handoff and automation; use a batch asset when a queue is part of the project — a shot's standing setup that everyone should get on checkout.

Sharing manifests across machines

All asset paths in a manifest are content-relative (/Game/...), not filesystem paths, so manifests are portable between machines that share the same project structure. Before loading a manifest on a different machine, verify that:

  • All referenced Capture Data, Identity, and Calibration assets exist at the same content paths
  • The output path in Settings points to a valid location for the receiving machine
  • The same engine plugin versions are installed — the manifest records the MHA Manager version that wrote it, but not the engine plugins it depended on