Skip to content

Custom items

Geoffrey Horsington edited this page Aug 23, 2020 · 4 revisions

WIP
This guide is WIP and is bound to change as better tooling is developed.

This guide assumes you are familiar with using MonoMod, Unity Editor and the process of extracting stubbed MonoScripts from the game.
This guide should be currently used only as a general guide for porting currently existing items to Sideloader format.

Starting version 0.3.0, Sideloader allow to inject custom FVRObjects into the game. This essentially allows to create new weapons, ammunition and general items without permanently editing the originals. As of writing this, the process of creating new items involves the following steps:

  1. Extract game assets with UtinyRipper or similar tool that can provide stubs for Assembly-CSharp.dll
  2. Import ripped assets into Unity Editor
  3. Create new prefabs/assets for FVRObject and ItemSpawnerIDs
  4. (Optional) Write MonoMod patcher to inject custom MonoBehaviour code into Assembly-CSharp
  5. Bundle assets and prefabs into an asset bundle (for example with AssetBundles Browser) and build Assembly-CSharp.mm.dll
  6. Write Sideloader manifest file
  7. Package everything into a h3mod

This guide currently covers steps 6 and 7 as the previous steps are commonly used for adding new items with tools like LSIIC.

Creating manifest file

Collect your asset bundles and possible MonoMod patchers into a single folder:

Asset bundle and MonoMod patcher in the same folder

Note that

  • You can have multiple asset bundles
  • All MonoMod patchers' names must end with .mm.dll. Other than that, the starting name of the assembly does not matter.

Next, create a new file and name it manifest.json. Open it and insert the following boilerplate:

{
    "manifestRevision": "1",
    "guid": "my.guid.name",
    "name": "My Mod name",
    "version": "1.0.0",
    "description": "My simple description",
    "assetMappings": [
        {
            "type": "FVRObject",
            "target": "",
            "path": "ABPath:AssetName"
        },
        {
            "type": "ItemSpawnerID",
            "target": "",
            "path": "ABPath:AssetName"
        }
    ]
}

Next, fill in the values in the template. Here are explanations:

  • guid: Unique ID for the mod. Must be lowercase, have no spaces and only contain alphanumerical characters or dots (.)
  • name: Human-readable name of the mod
  • version: Version of the mod. Must be of form <number>.<number>.<number>
  • description: Optional description for the mod

Then fill in the asset mapping. In the example above there are two mappings:

  • "type": "FVRObject" means to inject a custom FVRObject and to inject "type": "ItemSpawnerID" new ItemSpawnerID
  • target should be empty
  • path must be of form ABPath:AssetName where ABPath is the path to the asset bundle inside the archive and AssetName is path to the asset inside the asset bundle

You can add more mappings like so:

"assetMappings": [
        {
            "type": "FVRObject",
            "target": "",
            "path": "ABPath:AssetName"
        },
        {
            "type": "ItemSpawnerID",
            "target": "",
            "path": "ABPath:AssetName"
        },
        {
            "type": "ItemSpawnerID",
            "target": "",
            "path": "ABPath:AssetName"
        },
        {
            "type": "FVRObject",
            "target": "",
            "path": "ABPath:AssetName"
        }
    ]

Remember to add the comma (,)!

Here's an example of the filled in manifest file for the following mod structure:

Examle mod structure

{
    "manifestRevision": "1",
    "guid": "h3vr.blockbuilder57.modpanelv2",
    "name": "Mod Panel",
    "version": "1.0.0",
    "assetMappings": [
        {
            "type": "FVRObject",
            "target": "",
            "path": "lsiic:Assets/LSIIC/ScriptableObjects/FVRObjects/ModPanelV2.asset"
        },
        {
            "type": "ItemSpawnerID",
            "target": "",
            "path": "lsiic:Assets/LSIIC/ScriptableObjects/ItemSpawnerIDs/ModPanelV2.asset"
        }
    ]
}

Note that lsiic refers to the asset bundle file and Assets/LSIIC/ScriptableObjects/FVRObjects/ModPanelV2.asset refers to the asset inside the asset bundle. By default, Unity Editor will generate a .manifest file that will contain the full paths of all assets inside the asset bundle:

Example contents of lsiic.manifest generated by Unity:

Assets:
- Assets/LSIIC/ScriptableObjects/FVRObjects/SpectatorCamera.asset
- Assets/LSIIC/ScriptableObjects/FVRObjects/Weaponry/SpectatorCameraAttachment.asset
- Assets/LSIIC/ScriptableObjects/FVRObjects/ModPanelV2.asset
...

Bundling it all together

When you have the final mod folder:

Examle mod structure

Package it into a .zip file and change the extension to either .h3mod or .hotmod.

Important caveats

  • Only mm.dll files are accepted into h3mods. If you need to have extra dependencies (like LSIIC.Core.dll), either compile the code directly into your MonoMod patcher OR make it into a separate BepInEx plugin!