-
Notifications
You must be signed in to change notification settings - Fork 2
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 anAudioClip
instance -
FVRObject
-- injects a customFVRObject
instance into the game. This can be a custom weapon or a general item. -
ItemSpawnerID
-- injects a customItemSpawnerID
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 withh3vr_data
and be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1
to targetThompsonM1A1
prefab inassets_resources_objectids_weaponry_smg
asset bundle -
materialName
-- name of theMaterial
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
- To target normal maps, use
-
- for
Mesh
type, value in form<prefabPath>:<meshContainerName>:<meshName>
where-
prefabPath
-- full path to the prefab. Must start withh3vr_data
and be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1
to targetThompsonM1A1
prefab inassets_resources_objectids_weaponry_smg
asset bundle -
meshContainerName
-- name of the object that contains the mesh. Currently this is always the name of theMeshFilter
object -
meshName
-- name of theMesh
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 withh3vr_data
and be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1
to targetThompsonM1A1
prefab inassets_resources_objectids_weaponry_smg
asset bundle -
materialName
-- name of theMaterial
instance
-
- for
Prefab
type, value in form<prefabPath>
where the value is full path to the prefab. Must start withh3vr_data
and be lowercase. Example:h3vr_data\streamingassets\assets_resources_objectids_weaponry_smg\thompsonm1a1
to targetThompsonM1A1
prefab inassets_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
andItemSpawnerID
, target is empty
- for
-
path
-- Path to an asset inside the ZIP to use as replacement.- For
Texture
s, this is path to the PNG file inside the archive. - For meshes, prefabs and materials, the path is in form
<assetBundlePath>:<assetPath>
whereassetBundlePath
is the path to the asset bundle inside the ZIP andassetPath
is path to the asset inside the asset bundle. - For
AudioClip
s, this is the path to the WAV file in the archive. The WAV must be using PCM format. - For
FVRObject
andItemSpawnerID
, the path is in form<assetBundlePath>:<assetPath>
whereassetBundlePath
is the path to the asset bundle inside the ZIP andassetPath
is 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_magazine
prefab - Searches for
MeshFilter
namedmagazine_30Round
- Applies to any mesh inside the
magazine_30Round
mesh - The replacement mesh is inside
carrot
asset 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
carrot
asset bundle under pathassets\testmaterial.mat