Mod manifest guide
A mod package is a ZIP archive containing exactly one manifest.json. The manifest describes mod metadata, the target game, payload files to copy, and changes to Unity .assets files.
Quick start
Section titled “Quick start”Editor validation
Section titled “Editor validation”Every manifest must contain the project’s JSON Schema URL at the top level:
{ "$schema": "https://uap.cnbarrier.com/schema-v1.json"}Editors with JSON Schema support can then provide completion and structural validation. Runtime validation still enforces path safety, operation combinations, file existence, unique asset matches, and optional-content conflicts.
Package layout
Section titled “Package layout”Mod.zip manifest.json resources/ modassets.assets modassets.resourceThe manifest may be at the ZIP root or in a subdirectory, although the root is recommended. Payloads that must be installed, including .resource files used by replacement assets, must be declared explicitly in copyFiles.
Complete example
Section titled “Complete example”{ "$schema": "https://uap.cnbarrier.com/schema-v1.json", "name": "Camera Tweak", "author": "Example", "version": "1.0.0", "description": "Adjusts the camera and installs mod resources.", "game": "GameName", "copyFiles": [ { "source": "resources/modassets.resource" } ], "targets": [ { "file": "resources.assets", "patches": [ { "type": "Camera", "match": { "field of view": 60.0 }, "set": { "field of view": { "from": 60.0, "to": 90.0 } } }, { "type": "Material", "match": { "m_Name": "TargetMaterial" }, "add": { "m_ValidKeywords.Array": ["_EMISSION"] } } ] }, { "file": "sharedassets4.assets", "patches": [ { "type": "AudioClip", "match": { "m_Name": "CrazySound" }, "replaceAsset": { "fromFile": "resources/modassets.assets", "matchField": "m_Name" } } ] } ]}Check before publishing
Section titled “Check before publishing”Validate the manifest in an editor with JSON Schema support, then load the ZIP in Install Mod. Loading the package validates the manifest and prepares an installation preview without modifying game files.
Review the mod information and target game directory, then select any optional content to validate the selected combination. The initial preview resolves a Steam installation using game; once the preview opens, Change lets you select another game directory.
Use UABEA to check asset matches and field values, and verify installation results on a test copy of the game before publishing. Click Start install to apply the mod, or Choose another to return to package selection.
Top-level fields
Section titled “Top-level fields”| Field | Required | Description |
|---|---|---|
$schema |
Yes | Must be https://uap.cnbarrier.com/schema-v1.json. |
name |
Yes | Mod name. |
author |
Yes | Mod author. |
version |
Yes | Mod version; semantic versioning is recommended. |
description |
No | Short description. |
game |
No | Game name used when resolving a Steam installation. |
copyFiles |
No | Payload files copied beside the target assets files. |
targets |
Yes | Groups of target .assets files and patches. |
optional |
No | Independently selectable optional-content groups. |
The old top-level schemaVersion: 1 may remain in existing manifests, but the current runtime does not use it. New manifests do not need this field.
Payload files
Section titled “Payload files”"copyFiles": [ { "source": "resources/modassets.resource" }]source must be a safe relative path inside the mod ZIP. Only its file name is used at the destination, and the file is copied beside the target assets files. If copyFiles is present, all targets must reside in one directory. Existing destination files are never overwritten.
Targets and patches
Section titled “Targets and patches”Each target identifies an assets file by file name and contains at least one patch:
{ "file": "sharedassets0.assets", "patches": [ { "type": "Camera", "match": { "m_Name": "Main Camera" }, "set": { "field of view": { "from": 60.0, "to": 75.0 } } } ]}file cannot contain a directory. The installer searches the game directory recursively and stops if the file is missing or ambiguous.
type is a Unity asset type such as Camera, Material, AudioClip, or GameObject. All fields in match use AND semantics and must match. Use multiple patches to express OR conditions. Field-level changes can affect all matching assets; operations that copy or replace whole assets impose additional uniqueness requirements.
Component patches
Section titled “Component patches”Set type to GameObject and use componentType to modify an attached component:
{ "type": "GameObject", "match": { "m_Name": "_Equipment_Items" }, "componentType": "Transform", "set": { "m_LocalPosition.x": { "from": 0, "to": 12.5 } }}The match applies to the GameObject, while set and add paths apply to the component. The installer stops if more than one component of the requested type is attached. componentType cannot be combined with replaceAsset or copyAsset.
Change operations
Section titled “Change operations”set replaces field values. Every entry requires both the expected current value and the new value:
"set": { "field of view": { "from": 90.0, "to": 75.0 }, "near clip plane": { "from": 0.3, "to": 0.1 }}The current field must equal from. Values are not implicitly converted between strings, numbers, and booleans. to may also contain a scalar array or an object representing the target field’s direct children.
add appends scalar values to an array without creating duplicates:
"add": { "m_ValidKeywords.Array": ["_EMISSION"]}set and add may appear in the same patch.
replaceAsset
Section titled “replaceAsset”replaceAsset replaces a complete target asset with an asset from a packaged source file:
"replaceAsset": { "fromFile": "resources/modassets.assets", "matchField": "m_Name"}The source and target types must match. For each target, matchField must uniquely identify one source asset of the same type. It cannot be combined with set, add, componentType, or copyAsset. If a target assets file contains a replacement, that file cannot also contain field-level changes.
copyAsset
Section titled “copyAsset”copyAsset copies another asset in the same target file after ordinary field patches have run:
{ "type": "Material", "match": { "m_Name": "DiningChair_mtl" }, "copyAsset": { "from": { "type": "Material", "match": { "m_Name": "DiningTable_mtl" } } }}The source and target must each be unique, distinct assets of the same type. The target keeps its Path ID and scalar string m_Name; the remaining field tree comes from the patched source. Copy chains, cycles, and combinations with other operations in the same patch are rejected.
Field paths
Section titled “Field paths”Paths follow names in the Unity asset field tree:
m_Namem_CullingMask.m_Bitsm_ValidKeywords.Arraym_SavedProperties.m_TexEnvs.Array.data[first=_EmissionMap].second.m_Texture.m_PathIDThe selector syntax [child=value] selects an array element by a child field. Path segments cannot be empty. Selector values use string comparison and do not support expressions.
Path ID references
Section titled “Path ID references”Use $pathId as a set.to value to look up exactly one asset in the same target file:
"set": { "m_Texture.m_PathID": { "from": 0, "to": { "$pathId": { "type": "Texture2D", "match": { "m_Name": "NewEmission" } } } }}Optional content
Section titled “Optional content”Each optional group has a unique, non-empty name, an optional description, and at least one of targets or copyFiles:
"optional": [ { "name": "High-resolution textures", "description": "Replaces textures with 4K versions.", "copyFiles": [ { "source": "extras/skin_4k.resource" } ] }]Selected groups are merged with the main content before preview and installation. Payload destination names must remain unique, and merged operations must satisfy the same combination restrictions as ordinary targets.
Installation and uninstall behavior
Section titled “Installation and uninstall behavior”Installation first validates the package, resolves the game and target files, and prepares a preview. The desktop preview shows mod metadata, the game directory, and optional-content checkboxes. Optional groups are initially unchecked and are merged with the main content when selected.
After Start install, the application prepares patched outputs, payloads, rollback snapshots, and hashes in the backup repository’s .temp directory. It then replaces assets atomically, creates payloads without overwriting existing files, verifies the results, and commits an immutable layer record. Selected optional-group names are saved in layer.json and shown on the completion page.
In Manage Mods, Uninstall checks file integrity and dependencies before asking for confirmation. Uninstall reconstructs modified assets by replaying remaining layers over base snapshots. It also restores or removes payloads according to their snapshots. Missing or damaged layer records, original packages, or snapshots stop the operation instead of risking an incorrect result.
Safety limits
Section titled “Safety limits”manifest.jsoncannot exceed 10 MB.- Total uncompressed package size cannot exceed 10 GB.
- ZIP entries and manifest file paths must be safe relative paths.
- Duplicate entries after path normalization are rejected.
- Preview does not modify assets files or copy payloads.
Authoring recommendations
Section titled “Authoring recommendations”Use UABEA to inspect the target game’s actual asset types, Path IDs, field trees, paths, and values. Prefer stable identifiers such as m_Name; confirm uniqueness wherever an operation requires it; keep accurate set.from checks; use separate patches for OR conditions; and declare every payload explicitly in copyFiles.