Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
CustomItemRegistry
BreakoutMods CIR is a BepInEx and Jotunn powered modding API for registering custom 3D item prefabs from AssetBundles.
| Last updated | 2 weeks ago |
| Total downloads | 151 |
| Total rating | 0 |
| Categories | Mods Libraries Tools Skins Crafting Server-side Client-side Utility |
| Dependency string | BreakoutMods-CustomItemRegistry-0.6.2 |
| Dependants | 0 other packages depend on this package |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured with the correct entry point for mods and preferred defaults for the community.
Preferred version: 5.4.2333ValheimModding-Jotunn
Jötunn (/ˈjɔːtʊn/, 'giant'), the Valheim Library was created with the goal of making the lives of mod developers easier. It enables you to create mods for Valheim using an abstracted API so you can focus on the actual content creation.
Preferred version: 2.29.0README
BreakoutMods CIR - Custom Item Registry
Part of the BreakoutMods modding suite.
CIR, short for Custom Item Registry, is a Valheim modding API for developers who want to ship custom 3D item prefabs from AssetBundles without rewriting ObjectDB, ZNetScene, recipe, and multiplayer registration glue in every mod.
Repository: BreakoutMods/CIR-CustomItemRegistry
Community: BreakoutMods Discord
Support development: BreakoutMods Patreon
The library is built for BepInEx 5.x, Harmony, and Jotunn. It leans on Jotunn's PrefabManager and ItemManager for multiplayer-safe prefab and recipe registration, while exposing the original small API, the CIR 0.2 raw builder API, CIR 0.3 typed item templates, CIR 0.4 typed recipe helpers, and CIR 0.6 optional YAML/JSON item packs.
Usage
Reference CustomItemRegistry.dll from your mod project and add BepInEx dependencies:
[BepInDependency(CustomItemRegistryPlugin.PluginGuid)]
[BepInDependency(Jotunn.Main.ModGuid)]
Valheim also has a game type named CraftingStation. If your project references Valheim assemblies, add an alias for CIR's enum:
using CIRCraftingStation = ValheimCustomItemRegistry.CraftingStation;
Register a templated item from Awake:
CustomItemRegistry.Item("BM_IronLongsword")
.FromEmbeddedResource("MyMod.Assets.items", typeof(MyPlugin).Assembly, "BM_IronLongsword")
.DisplayName("$item_bm_ironlongsword")
.Description("$item_bm_ironlongsword_desc")
.Icon("BM_IronLongswordIcon")
.AsSword(sword => sword
.Slash(48f, perLevel: 6f)
.Block(24f, force: 18f, parry: 2f)
.Durability(250f, perLevel: 50f)
.Attack(stamina: 14f, force: 35f)
.Movement(-0.05f))
.Recipe(recipe => recipe
.At(CIRCraftingStation.Forge)
.StationLevel(2)
.Requires(VanillaItem.FineWood, 4)
.Requires(VanillaItem.Iron, 10)
.Requires(VanillaItem.Iron, 0, 8))
.Register();
Typed helpers remove most recipe string memorization, but raw prefab strings remain supported:
using static ValheimCustomItemRegistry.ItemRefs;
CustomItemRegistry.Item("BM_MagicBlade")
.FromBundle(assetBundlePath, "BM_MagicBladePrefab")
.AsSword(sword => sword.Slash(40f).Spirit(10f))
.Recipe(recipe => recipe
.At(CIRCraftingStation.Forge)
.Requires(VanillaItem.Silver, 10)
.Requires(Modded("com.otherauthor.valheim.magicmod", "MagicCore"), 1))
.Register();
You can still use the raw 0.2 builder when you need direct shared-data control:
CustomItemRegistry.Item("BreakoutMaterial")
.FromBundle(assetBundlePath, "BreakoutMaterialPrefab")
.Icon("BreakoutMaterialIcon")
.Gear(gear => gear.Material().StackSize(50))
.ConfigureSharedData(shared => shared.m_value = 25)
.Register();
The original API remains supported:
CustomItemRegistry.RegisterItem(
"MyCrystalSword",
Path.Combine(Path.GetDirectoryName(Info.Location), "myitems"),
"MyCrystalSwordPrefab",
new CraftingRecipe(
new List<Ingredient>
{
new Ingredient("FineWood", 8),
new Ingredient("Crystal", 12),
new Ingredient("Silver", 4)
},
"forge",
1));
By default, CIR expects your AssetBundle prefab to already contain the required Valheim item components: ItemDrop, Rigidbody, ZNetView, ZSyncTransform, and a collider. If any are missing, CIR refuses registration and lists the missing components. For simple test items, you can opt into CIR auto-preparation with .PrefabPreparation(...).
YAML/JSON Item Packs
CIR can load raw item definitions from files without making YamlDotNet or Json.NET mandatory. Put item packs in:
BepInEx/config/CustomItemRegistry/packs
CIR scans that folder recursively for .yaml, .yml, and .json on startup. YAML support activates when ValheimModding-YamlDotNet is installed. JSON support activates when ValheimModding-JsonDotNET is installed. CIR does not ship those DLLs inside its own package.
Mods can also load packs from their own folder:
CustomItemRegistry.LoadItemPacksFromDirectory(
Path.Combine(Path.GetDirectoryName(Info.Location), "packs"));
Check optional parser availability with:
ItemPackParserStatus status = CustomItemRegistry.GetItemPackParserStatus();
See docs/item-packs.md for the schema, examples, and asset path rules.
Features
API
CustomItemRegistry.Item(string itemName)fluent builder entrypoint.RegisterItem(string itemName, string assetBundlePath, string prefabName, CraftingRecipe recipe)legacy API.RegisterItem(CustomItemDefinition definition),TryRegisterItem(...), andRegisterItems(...).LoadItemPacks(...),LoadItemPacksFromDirectory(...),LoadItemPack(...), andGetItemPackParserStatus()for optional YAML/JSON packs.CustomItemBuilder,RecipeBuilder,GearBuilder,CustomItemDefinition,ItemRegistrationResult, andCustomItemRegistrationException.- CIR 0.3 template builders:
WeaponTemplateBuilder,ShieldTemplateBuilder,ArmorTemplateBuilder,BowTemplateBuilder,AmmoTemplateBuilder,ToolTemplateBuilder,FoodTemplateBuilder, andMaterialTemplateBuilder. - CIR 0.4 recipe helpers:
VanillaItem,CraftingStation,ItemRef,ItemRefs, andToPrefabName()extension methods. CraftingRecipewith ingredients, crafting station, repair station, station level, amount, enabled flag, require-only-one ingredient, and quality result multiplier.- AssetBundles can be loaded from file paths, passed as preloaded
AssetBundleinstances, or loaded from embedded resources with.FromEmbeddedResource(...). CustomItemBuilder.PrefabPreparation(...)opts into safe auto-preparation for simple prefabs or adjusts strict validation behavior.- Wearable armor validation checks
Chest,Legs,Helmet, andShoulderprefabs for skinned mesh setup before registration, catching commonSetupVisEquipmentequip crashes early.
Typed Recipe Helpers
RecipeBuilder.At(CIRCraftingStation.Forge)andRepairAt(CIRCraftingStation.Workbench)map known stations to Jotunn prefab names.RecipeBuilder.Requires(VanillaItem.Iron, 10)maps common Valheim ingredients to prefab names.RecipeBuilder.Requires(ItemRef.Modded("com.author.mod", "MagicCore"), 1)soft-links third-party mod items without compile-time references.ItemRef.Prefab("SomePrefab")and raw.Requires("SomePrefab", 1)remain available for custom or newly added prefabs.
Item Templates
.AsSword(...),.AsAxe(...),.AsMace(...),.AsSpear(...),.AsKnife(...), and.AsAtgeir(...)for melee weapons..AsBow(...)and.AsArrow(...)for ranged weapons and ammo..AsShield(...),.AsArmorChest(...),.AsArmorLegs(...),.AsHelmet(...), and.AsCape(...)for defense items..AsTool(...),.AsFood(...), and.AsMaterial(...)for common non-weapon items.- Template-aware validation catches missing weapon damage, shield block power, armor value, and food stats before asset loading.
Item Metadata
- Display name, description, icon sprite by AssetBundle asset name, or direct
Sprite. - Icon asset names load
Spriteby default. Opt-in prefab preparation can allow CIR to convert aTexture2Dwith the same name into a runtime sprite. - Weight, stack size, durability, max quality, tool tier, teleportable flag, and repairable flag.
- Item type helpers for weapons, shields, bows, ammo, tools, armor slots, materials, consumables, shoulder items, trinkets, torches, and utility items.
- Armor, block power, block force, parry, attack force, movement modifier, base damages, per-level damages, and damage modifiers.
- Primary and secondary attack tuning for stamina, eitr, health costs, force multipliers, projectile count, projectile velocity, draw duration, draw stamina drain, reload time, and reload stamina drain.
.ConfigureSharedData(...)escape hatch for advancedItemDrop.ItemData.SharedDataedits.
Registration
- Loads AssetBundles from absolute paths or paths relative to
BepInEx/plugins. - Loads and clones the requested prefab, renaming the clone to the public item name.
- Strictly validates missing
ItemDrop,Rigidbody,ZNetView,ZSyncTransform, and collider components by default. - Can prepare simple prefabs by adding missing
ItemDrop,Rigidbody,ZNetView, andZSyncTransformwhen explicitly enabled. - Warns when an auto-prepared prefab has no collider, but does not add a guessed collider.
- Builds Jotunn item and recipe data from CIR definitions.
- Registers prefabs through Jotunn's
PrefabManagerfor multiplayer-safe ZNetScene registration. - Registers items and recipes through Jotunn's
ItemManager. - Includes Harmony timing patches on
ObjectDB.CopyOtherDBandZNetScene.Awaketo flush items into live databases when Valheim creates or copies them. - Validates missing bundle paths, missing prefab assets, duplicate item names, invalid recipes, and missing craftable item icons with clearer log messages and AssetBundle candidate names.
- Validates template-specific required fields with the template name in the error message.
Minimal Unity Prefab
For production items, build the Unity prefab like a Valheim item and include ItemDrop, Rigidbody, ZNetView, ZSyncTransform, and a collider.
For quick test items, the Unity prefab can be very small if you explicitly opt into auto-preparation:
AssetBundle
MyItemPrefab
visible mesh/model
collider recommended
MyItemIcon Sprite or Texture2D
CIR will add the common Valheim item scripts at registration time only when .PrefabPreparation(...) enables it. Use templates such as .AsMaterial(...), .AsArmorChest(...), or .AsSword(...) so CIR knows which item type and stats to apply.
CIR does not repair Unity Missing Script references, does not choose collider shape/size, and does not guess vanilla asset references. If you use vanilla assets, use Jotunn JVLmock_... references.
Wearable armor is stricter than normal items. .AsArmorChest(...), .AsArmorLegs(...), .AsHelmet(...), and .AsCape(...) need a real Valheim-style wearable visual in the prefab: at least one SkinnedMeshRenderer with a mesh, rootBone, and valid bones. Chest, legs, and cape prefabs should usually follow the vanilla attach_skin... hierarchy. A static mesh plus icon is fine for materials, but not for equipped armor.
If imported armor equips with broken visuals or null references even though the skinned renderer exists, base the prefab on a vanilla armor item and consider calling Jotunn BoneReorder.ApplyOnEquipmentChanged() from your plugin.
Advanced mods with their own custom equipment visual pipeline can disable only this check with .PrefabPreparation(prep => prep.ValidateWearableVisuals(false)).
Example opt-in for a simple mesh prefab:
CustomItemRegistry.Item("SimpleItem")
.FromBundle(assetBundlePath, "SimpleItemPrefab")
.PrefabPreparation(prep => prep
.AutoAddItemDrop()
.AutoAddPhysics()
.WarnOnMissingCollider()
.AllowTextureIconFallback())
.AsMaterial()
.Register();
Developer Example
The src/ExampleCustomItemPlugin project shows template, raw builder, definition, try-register, validation harness, and legacy API usage. Its sample AssetBundle and prefab names are placeholders, so replace them with real assets before shipping.
Project Layout
CIR-CustomItemRegistry/
CIR-CustomItemRegistry.sln
build.ps1
docs/
recipes.md
item-packs.md
templates.md
roadmap/
developer-helper-api.md
src/
CustomItemRegistry/
API/ Public API contracts and registration facade
Builders/ Fluent item, recipe, and gear builders
Helpers/ Vanilla item, station, and modded item refs
ItemPacks/ Optional YAML/JSON pack parsers and DTO mapping
Templates/ Typed Valheim item template builders
Patches/ Harmony timing patches
Plugin/ BepInEx plugin entrypoint
ExampleCustomItemPlugin/
Examples/ Developer-facing usage examples
Testing/ Lightweight compile/validation harnesses
The public namespace and assembly identity stay stable even though the source files are grouped by responsibility.
Installation
If you're using a mod manager, you can likely ignore this section.
- Install BepInEx 5.x for Valheim.
- Install Jotunn.
- Copy
CustomItemRegistry.dllintoBepInEx/plugins/CustomItemRegistry. - Copy developer mods that depend on the API into their own folder under
BepInEx/plugins. - Put each developer mod's AssetBundles next to that developer mod, or pass an absolute AssetBundle path to CIR.
Building
This repo expects to live under a Valheim install like:
Valheim dedicated server/
BepInEx/
valheim_server_Data/
Modding/
CIR-CustomItemRegistry/
Build with:
.\build.ps1 -Configuration Release
Debug builds copy the API DLL into BepInEx/plugins/CustomItemRegistry and the example DLL into BepInEx/plugins/ExampleCustomItemPlugin.
Notes For Asset Authors
- Prefer
VanillaItemandCraftingStationfor common ingredients and stations. Use raw strings for uncommon or newly added prefabs. - Use
ItemRef.Modded("other.mod.guid", "PrefabName")when depending on a third-party item. CIR logs that source mod GUID if the prefab is missing. - Use Jotunn's accepted crafting station names when you pass raw strings. Common examples are
piece_workbench,forge, andpiece_cauldron. Passingnullor an empty string makes the recipe craftable without a station. - Include an item icon in the
ItemDropshared data, pass a directSprite, or call.Icon("SpriteAssetName")for craftable items. .Icon("AssetName")can also use aTexture2Dwith the same name if noSpriteexists whenAllowTextureIconFallback()is enabled.- Add colliders in Unity for reliable drop, pickup, and physics behavior. Strict mode requires one; auto-preparation mode can warn instead.
- Upgrade-only recipe requirements are valid. Use
.Requires("Bronze", 0, 4)when an ingredient should only be consumed by upgrades. - Self-contained mods can embed an AssetBundle in the DLL and call
.FromEmbeddedResource("Namespace.BundleName", typeof(MyPlugin).Assembly, "PrefabName"). - Use templates for normal items first. Drop to
.Gear(...)or.ConfigureSharedData(...)only for unusual behavior. - Keep prefab names stable once released. Renaming a registered item prefab can affect existing saves and inventories.
Bugs, Support, Contributions
Please open issues with the Valheim version, BepInEx version, Jotunn version, the item prefab name, and the relevant BepInEx log lines. Pull requests that keep the public API small and improve interop with Jotunn are welcome.
Changelog
See CHANGELOG.md.