Skip to content

For mod authors

Ryan McAfee edited this page Sep 10, 2026 · 1 revision

For mod authors

If you write a Valheim mod, this page says what BakaLoader does with it, what it needs from you, and what it will never do. Short version: almost nothing is required of you, and there is no integration to write.

BakaLoader is a solo project and does not take code contributions. Issues with a Thunderstore link are welcome, especially if a mod's items are coming out wrong in the spawn picker or its config is not showing up in the editor.

The Mods screen listing installed plugins

What a mod needs to be listed

Two things.

A folder in BepInEx\plugins. BakaLoader enumerates the directories one level inside plugins. A loose .dll sitting directly in plugins still loads under BepInEx, but BakaLoader will never list it, because it only looks at folders. Thunderstore packages already ship this way, so this is only a problem for hand built drops.

A folder named Author-ModName. The name is split on the first hyphen. Therzie-Warfare gives author Therzie and mod Warfare. First hyphen only, so a mod name with hyphens in it is fine. An author name with a hyphen in it is not, and would mis-split.

That is all. No manifest is required to be listed, though without one the Installed column reads unknown.

What a mod needs to be update checked

The Author-ModName folder name has to match a package on the Valheim Thunderstore, because that string is the lookup key. Nothing else is read. BakaLoader does not open your DLL, does not read your BepInPlugin GUID, and does not use your assembly version.

manifest.json in the folder root supplies the installed version, from version_number, and the website link from website_url. If the folder split produced no author, name from the manifest is used as the mod name.

What that means for you in practice:

Ship your package so it unpacks to Author-ModName/, which is what Thunderstore already does.

Keep version_number in manifest.json accurate. That number, not your assembly version, is what BakaLoader compares against the latest on Thunderstore.

If your mod is not on Thunderstore, it will be listed with - in the Latest column and never offered an update. That is not an error state, it is just the limit of what a Thunderstore lookup can do. The row menu shows Open Thunderstore page greyed with "Not on Thunderstore".

A user who renames your folder breaks the match. There is nothing you can do about that and nothing BakaLoader can do either, since the folder name is the only identifier available.

How your items reach the spawn picker

No work is needed from you. BakaLoader installs a small plugin, BakaLoaderItemIndexer, into BepInEx\plugins\BakaLoaderItemIndexer\ at every server start. It reads the game's own object database at runtime and writes a catalogue to BepInEx\items.json, which the app then reads.

It patches ObjectDB.Awake and ZNetScene.Awake with Harmony postfixes, and writes only when both ObjectDB.instance.m_items and ZNetScene.instance.m_prefabs are populated. Both halves or nothing, because writing on whichever fires first can pin a catalogue with every creature missing.

It rewrites the file whenever it collects more entries than the last write in this process. That is deliberate: if your own postfix on ObjectDB.Awake runs after the indexer's and adds prefabs, the next write picks them up rather than the first, smaller catalogue locking you out.

The file is written to a .tmp and swapped into place, so the app can never read a half written catalogue.

How your item is named

Localization.instance.Localize(shared.m_name). Whatever token you set is looked up in the game's own localization. If localization is not up yet, or the lookup throws, or comes back empty, the raw prefab name is used instead.

So if your item shows in the picker as $item_mymod_sword instead of Runeblade, your localization entry is either missing or registered after the catalogue was written. Registering it earlier, or adding prefabs later so the catalogue is rewritten, both fix it.

Creatures use Character.m_name the same way.

How your item is classified

The category shown beside each row comes from the item's own ItemDrop.ItemData.ItemType.

Equipment is every weapon type, Shield, Helmet, Chest, Legs, Shoulder, Hands, Tool, Torch, Trinket, Utility and Ammo. The list is the game's own IsEquipable set, read out of the shipped assembly rather than taken on trust, with Hands as the one deliberate extra. Only Equipment entries carry a quality value in the picker, so an item left off this list silently loses its quality box. That is why Utility, which is the Megingjord and the Wishbone, is on it, and Ammo is there so arrows and bolts are not filed as plain items.

Resource is ItemType.Material and nothing else.

Item is everything else. There is no separate consumable category. Food, mead, potions, fish and customization items all land in Item.

Creature is a separate category, assigned to anything with a Character component rather than going through the item classifier.

Quality is offered only for an Equipment entry whose m_maxQuality is greater than 1. Level is offered only for creatures.

If your item comes out in the wrong bucket, it is because of its ItemType. Open an issue with the Thunderstore link if that is genuinely wrong for what the item is.

How your config reaches the Configs editor

BakaLoader lists every *.cfg file in BepInEx\config, top level only. BepInEx writes your config there on first load using your plugin GUID, so nothing is needed from you.

The one place naming matters is mod removal. When a user removes your mod, BakaLoader offers to delete the config files that look like they belong to it. It reduces both the file name and the mod name to lowercase letters and digits and matches if the file name contains the mod name. So Therzie.Warfare.cfg, com.therzie.warfare.cfg and warfare.cfg all match a mod called Warfare. A config named after something unrelated to the mod will not be found, and the user will have to delete it themselves.

The plugins BakaLoader installs

BakaLoader puts five small plugins beside the server at every start. The one that matters most to you is the Commander, which answers RCON and owns a handful of command names, and Max Players, which transpiles game methods you might also be patching. Both are covered on The bundled plugins, including the exact Harmony targets and the command names not to reuse.

There is no API for your mod to talk to BakaLoader

Plainly: none. There is no hook, no event, no named pipe, no static surface to reflect against, no BepInDependency you can declare, and no plan to add one.

The only two channels that exist are one way. The app is an RCON client and Commander is an RCON server. The item indexer writes items.json and the app reads it. That is it.

If you want your mod's items handled better in the picker, or its config found correctly on removal, open an issue with the Thunderstore link. That is the supported route.

An end to end example

A host wants your mod, Author-Runeforge, on their server.

They stop the server, open Mods, press Add from Thunderstore and paste https://thunderstore.io/c/valheim/p/Author/Runeforge/. BakaLoader downloads the package and unpacks it to BepInEx\plugins\Author-Runeforge\. The toast names the version it installed.

They press Scan Thunderstore. Your mod appears with your name and author from the folder, your version from manifest.json, and Current in the Status column.

They start the server. Your plugin loads, BepInEx writes BepInEx\config\com.author.runeforge.cfg, and the item indexer's postfix on ObjectDB.Awake picks up your prefabs and rewrites BepInEx\items.json.

They open Configs, pick com.author.runeforge.cfg from the list, change a value, press Save. The editor writes the file. They restart the server so BepInEx reads it.

A player loses one of your items. The host opens Players, right clicks them, picks Spawn item at…, types part of the item's name and sees it listed under its localized name with the category the classifier gave it. They press Spawn, and Commander instantiates the prefab at that player's coordinates with the cheat flag set.

Nothing in that flow required anything from you beyond a normal Thunderstore package.

Things people expect that do not exist

There is no Linux build and no Docker image. BakaLoader is a Windows desktop app built around the Windows server binary, and it uses a Win32 job object to tie the server process to itself. A Linux port would be a rewrite, not a recompile.

There is no way for a mod to add a screen, a button or a command to BakaLoader.

There is no dependency resolution when installing from a link. A user pasting your mod's link gets your mod and nothing else, so state your dependencies clearly on your Thunderstore page.

There is no client side component. BakaLoader manages the server. Whatever your mod needs on the player's machine, the player installs themselves.

Clone this wiki locally