Skip to content
Geoffrey Horsington edited this page Aug 23, 2020 · 12 revisions

Creating mods with sideloader

IMPORTANT: This guide is technical and is aimed at people who work on UI tools for sideloader and those who want to make mesh/prefab/material replacements.
If you want to make skin mods, use SkinPacker for now.

Sideloader mod format

A sideloader mod is a ZIP archive renamed to .h3mod that contains the following files:

  • PNG files (optional, used for textures)
  • Unity asset bundles (for meshes, prefabs and materials)
  • manifest.json (required)

For now, to create mesh/prefab/material replacements, you have to manually create asset bundles via Unity. A preferred way for now is to use AssetBundle Browser tool for Unity which allows you to easily compose and build asset bundles.

manifest.json

Manifest file contains metadata about the mod as well as information for sideloader about how to map the assets in the zip archive to in-game assets.

For more technically inclined, check out manifest's schema file and schema docs that contain technical info about the schema file.

Example manifest file:

{
  "manifestRevision": "1",
  "guid": "horse.coder.carrot_gun",
  "name": "Carrot Thompson M1A1",
  "version": "1.0.0",
  "description": "This is an example gun",
  "assetMappings": [
    {
      "type": "Texture",
      "target": "::m1a1_BaseColor:",
      "path": "thompson.png"
    }
  ]
}

Explanation of each value

  • manifestRevision -- MUST be "1"
  • guid -- A unique ID of the mod. Any string is a allowed with the following limitations:
    • ID must only contain lowercase latin characters (a-z) or numbers 0-9
    • Only the following punctuation is allowed: ., -, _
    • No whitespace is allowed
  • name -- Human-readable name of the mod. Must not contain newlines.
  • version -- version of the mod. Must be of form <major>.<minor>.<fix> as per semver spec
  • description -- Human-readable description of the mod. Can contain newlines.
  • assetMappings -- Tells sideloader how to find assets to replace and what assets to replace them with.
    • type -- Type of the replacements. Allowed values are
      • Texture -- the mapping targets a texture inside a prefab
      • Mesh -- the mapping targets a mesh inside a prefab
      • Material -- the mapping targets a material inside a prefab
      • Prefab -- the mapping targets a whole prefab
      • AudioClip -- the mapping targets an AudioClip instance
      • FVRObject -- injects a custom FVRObject instance into the game. This can be a custom weapon or a general item.
      • ItemSpawnerID -- injects a custom ItemSpawnerID into the game. This is essentially an icon visible in the item spawner for a certain object.
    • target -- a template string that tells sideloader what asset to replace. The value is of form <value1>:<value2>:<value3>... where <value> defines an optional value that depends on the selected type. If a value is not specified, any asset is matched. Allowed values:
      • for Texture type, value in form <prefabPath>:<materialName>:<texName>:<texParam> where
        • prefabPath -- full path to the prefab. Must start with h3vr_data and be lowercase. Example: h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1 to target ThompsonM1A1 prefab in assets_resources_objectids_weaponry_smg asset bundle
        • materialName -- name of the Material instance
        • texName -- name of the texture to replace. Must be the name of the MAIN TEXTURE (not the normal or alloy) (but without .png)
        • texParam -- shader parameter name to which attach the texture. If not specified, defaults to _MainTex. This allows to swap normal maps.
          • To target normal maps, use _BumpMap
          • To target "alloy" textures, use _SpecTex
      • for Mesh type, value in form <prefabPath>:<meshContainerName>:<meshName> where
        • prefabPath -- full path to the prefab. Must start with h3vr_data and be lowercase. Example: h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1 to target ThompsonM1A1 prefab in assets_resources_objectids_weaponry_smg asset bundle
        • meshContainerName -- name of the object that contains the mesh. Currently this is always the name of the MeshFilter object
        • meshName -- name of the Mesh object. Usually the same as in the asset bundle
      • for Material type, value in form <prefabPath>:<materialName> where
        • prefabPath -- full path to the prefab. Must start with h3vr_data and be lowercase. Example: h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1 to target ThompsonM1A1 prefab in assets_resources_objectids_weaponry_smg asset bundle
        • materialName -- name of the Material instance
      • for Prefab type, value in form <prefabPath> where the value is full path to the prefab. Must start with h3vr_data and be lowercase. Example: h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1 to target ThompsonM1A1 prefab in assets_resources_objectids_weaponry_smg asset bundle
      • for AudioClip type, value in form <audioClipName> where the value is the name of the AudioClip to replace.
      • for FVRObject and ItemSpawnerID, target is empty
    • path -- Path to an asset inside the ZIP to use as replacement.
      • For Textures, this is path to the PNG file inside the archive.
      • For meshes, prefabs and materials, the path is in form <assetBundlePath>:<assetPath> where assetBundlePath is the path to the asset bundle inside the ZIP and assetPath is path to the asset inside the asset bundle.
      • For AudioClips, this is the path to the WAV file in the archive. The WAV must be using PCM format.
      • For FVRObject and ItemSpawnerID, the path is in form <assetBundlePath>:<assetPath> where assetBundlePath is the path to the asset bundle inside the ZIP and assetPath is path to the asset inside the asset bundle.

Examples of asset mappings

{
    "type": "Texture",
    "target": "::m1a1_BaseColor:",
    "path": "thompson.png"
}
  • Checks for replacements in ALL prefabs
  • Applies to all materials inside the prefab
  • Applies to textures named m1a1_BaseColor
  • Applies texture as _MainTex
{
    "type": "Mesh",
    "target": "h3vr_data\\streamingassets\\assets_resources_objectids_weaponry_smg\\thompsonm1a1_magazine:magazine_30Round:",
    "path": "carrot:assets\\sosig_melee_crowbar.asset"
}
  • Only replaces meshes inside thompsonm1a1_magazine prefab
  • Searches for MeshFilter named magazine_30Round
  • Applies to any mesh inside the magazine_30Round mesh
  • The replacement mesh is inside carrot asset bundle under path assets\sosig_melee_crowbar.asset
{
    "type": "Material",
    "target": ":",
    "path": "carrot:assets\\testmaterial.mat"
}
  • Changes ALL MATERIALS
  • DO NOT DO THIS UNLESS YOU KNOW WHAT YOU'RE DOING
  • The replacement material is inside carrot asset bundle under path assets\testmaterial.mat
Clone this wiki locally