Home
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.
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 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
- ID must only contain lowercase latin characters (
-
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 anAudioClipinstance -
FVRObject-- injects a customFVRObjectinstance into the game. This can be a custom weapon or a general item. -
ItemSpawnerID-- injects a customItemSpawnerIDinto 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
Texturetype, value in form<prefabPath>:<materialName>:<texName>:<texParam>where-
prefabPath-- full path to the prefab. Must start withh3vr_dataand be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1to targetThompsonM1A1prefab inassets_resources_objectids_weaponry_smgasset bundle -
materialName-- name of theMaterialinstance -
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
- To target normal maps, use
-
- for
Meshtype, value in form<prefabPath>:<meshContainerName>:<meshName>where-
prefabPath-- full path to the prefab. Must start withh3vr_dataand be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1to targetThompsonM1A1prefab inassets_resources_objectids_weaponry_smgasset bundle -
meshContainerName-- name of the object that contains the mesh. Currently this is always the name of theMeshFilterobject -
meshName-- name of theMeshobject. Usually the same as in the asset bundle
-
- for
Materialtype, value in form<prefabPath>:<materialName>where-
prefabPath-- full path to the prefab. Must start withh3vr_dataand be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1to targetThompsonM1A1prefab inassets_resources_objectids_weaponry_smgasset bundle -
materialName-- name of theMaterialinstance
-
- for
Prefabtype, value in form<prefabPath>where the value is full path to the prefab. Must start withh3vr_dataand be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1to targetThompsonM1A1prefab inassets_resources_objectids_weaponry_smgasset bundle - for
AudioCliptype, value in form<audioClipName>where the value is the name of the AudioClip to replace. - for
FVRObjectandItemSpawnerID, target is empty
- for
-
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>whereassetBundlePathis the path to the asset bundle inside the ZIP andassetPathis 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
FVRObjectandItemSpawnerID, the path is in form<assetBundlePath>:<assetPath>whereassetBundlePathis the path to the asset bundle inside the ZIP andassetPathis path to the asset inside the asset bundle.
- For
-
{
"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_magazineprefab - Searches for
MeshFilternamedmagazine_30Round - Applies to any mesh inside the
magazine_30Roundmesh - The replacement mesh is inside
carrotasset bundle under pathassets\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
carrotasset bundle under pathassets\testmaterial.mat