-
Notifications
You must be signed in to change notification settings - Fork 7
Custom Item and Recipe 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
?
-
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. - A
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.
Copy them and put them in a fresh folder in your project called Assemblies
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
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.
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 :
Now we want to fix the script reference like so
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 :
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
.
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
Now, let's use the AssetBundle Browser
made by Unity to create our AssetBundle.
Window -> AssetBundle Browser -> Build Tab -> Build
We now want to put our AssetBundle in the BepinEx plugin so that we can later inject it.
- 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
We need to tell ValheimLib
that we want new language tokens for localization, we can do like so :
Those ones are done from code since they are very straightforward
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);