Skip to content

Custom Item and Recipe Creation

iDeath edited this page Mar 6, 2021 · 11 revisions

Custom Item Creation

To add an item to the game, a mod maker will have to call the ObjectDBHelper.Add(CustomItem item) method. But what is a CustomItem ?

  • CustomItem

    A CustomItem instance holds 3 variables :

    • A GameObject that will hold a reference to the item prefab
    • An ItemDrop that should be an ItemDrop Component attached to the item prefab
    • A bool called FixReferences

    ItemDrop is a class from the game code, they basically hold all the needed information for the game to define an item, its name, its functionalities, the text that will show up when hovering it, and so on.

Valheim uses Unity Version 2019.4.20, so let's download that and install it.

Launch the editor and create a new project. Click on Window -> PackageManager and search for AssetBundleBrowser and install it.

Now let's put the game assemblies into the project so that we reference the game code on our item prefab. The assemblies are located in the Valheim\valheim_Data\Managed folder.

Game Assemblies

Copy them and put them in a fresh folder in your project called Assemblies

Assemblies Folder

Making our Item Prefab

Now we want to make a prefab that is setup similarly as the item prefabs that IronGate did, for that, whats best than looking directly at one of them.

If you havent already used uTinyRipper on the game folder to get the prefabs showing up in the unity project, please do so.

A tutorial is available here (You only need to follow it up to the ILSpy part which is optional for what we do here)

Let's open the SpearChitin prefab as an example. Should get something like this after opening it

Assemblies Folder

As you can see, the root GameObject have multiple components.

  • A rigidbody, for collision handling
  • ZNetView for making the prefab network compatible
  • ZSyncTransform, same as above
  • ItemDrop

The last one holds the most interesting stuff, whats above Shared is non-important and is used for an actual item once its spawned, the meta-data we want to edit is stored under SharedData, so let's focus on that.

Since there is a stupid amount of fields, let's go over the one that I edited for my custom item Lead

I chose this prefab as a base because almost everything is copied from it, except that I remove the model because its not a spear and remove a child on the projectile prefab that we'll see soon.

The name, as you can see its a token that is prefixed with $ . This is very important for the token lookup and their localization system so you'll also want one at the beginning.

In my case I changed it to $custom_item_lead

Icons : Its an array that is the same size as the number of variant you'll want for you item, if there is only 1 variant, have a single entry in there and drag and drop your 2D Sprite at the Element 0 field.

Description Token, same thing for the name, mine is $custom_item_lead_description

Damages my item was dealing no damage and had no scaling per level so everything was set to 0.

Attack Status Effect, Status Effect can be used for items, the chitin spear has the Harpooned Status Effect for, well, harpooning stuff. I wanted the same for my item, but now you are wondering, how am I gonna reference game assets in my Unity Project. If I were to copy paste those, I'd need to fix shaders, and now I'd also have to be worried about copyright infringement, bad.

The solution is easy though, thanks to ValheimLib that introduces a mock system.

Mock System

We'll start by creating a folder that will hold all our mocks, let's call it Mock, we now want to drag and drop the existing asset from the ripped game project to our custom item project. Let's do that for the Harpooned Status Effect, you should end up with the Harpooned ScriptableObject asset like this :

Copied Asset

Now we want to fix the script reference like so

Fix the Script Ref

We also want to prefix the asset name with VLmock_ so we now we end up with an asset called VLmock_Harpooned

One last thing, we need to tell ValheimLib to fix the references for us, for that, when creating the instance of our CustomItem in code, we want to have the FixReference parameter set to true, like so :

CustomItem = new CustomItem(AssetHelper.LeadPrefab, fixReference : true);

Good, we now have our mock and we can use it for reference in our ItemDrop component ! That was easy.

Attack Projectile, the SharedData can also reference an attack projectile, and we happen to want one here, but this time we want it a bit modified, I only want the trail, without the fangspear in its GameObject hierarchy, we could hack it up directly from the Unity Project, but I found it easier to do from code, so let's do that here :

The relevant piece of code

We use the OnAfterInit provided by ValheimLib, that event is fired once after the ObjectDB is properly init the first time. That's perfect for us ! We want to do this just once : clone the prefab, so that we don't modify the original, remove the GameObject in the hierarchy that we don't want, and then we do the m_attackProjectile assignment.

AssetBundle

Now we want to make our AssetBundle so that we later inject it with our BepinEx plugin dll

Let's create an Asset Label for the AssetBundle that we'll call item_lead

AssetBundle Label

Now, let's use the AssetBundle Browser made by Unity to create our AssetBundle.

Window -> AssetBundle Browser -> Build Tab -> Build

Click Build

We now want to put our AssetBundle in the BepinEx plugin so that we can later inject it.

Freshly made AB

C# BepinEx Plugin Code

Importing the assetbundle into the Visual Studio Project :

  • Right click the project name in the solution explorer
  • Add
  • Existing item
  • Add the assetbundle
  • Properties of assetbundle
  • Select Embedded resource

Now get a reference to the Stream using GetManifestResourceStream

Example shown here

Language Tokens

We need to tell ValheimLib that we want new language tokens for localization, we can do like so :

Example shown here

Custom Recipes

Those ones are done from code since they are very straightforward

Example shown here

One thing to note for adding crafting / repair station requirement :

recipe.m_craftingStation = MockCraftingStation.Create("piece_workbench");

// And making sure that fixReference is set to true so that ValheimLib fix the mock for the workbench !
CustomRecipe = new CustomRecipe(recipe, fixReference : true, true);
Clone this wiki locally