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.
CraftStationStorage
Buy ingredient storage slots on crafting stations (workbench, forge, etc). One ingredient per slot, unlimited amount. Materials spill on removal.
| Last updated | 2 weeks ago |
| Total downloads | 10 |
| Total rating | 0 |
| Categories | Crafting AI Generated |
| Dependency string | glemoig-CraftStationStorage-0.3.0 |
| Dependants | 0 other packages depend on this package |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured and includes unstripped Unity DLLs.
Preferred version: 5.4.2202ValheimModding-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.24.3README
CraftStationStorage
A BepInEx + Jötunn plugin for Valheim that gives every crafting structure its own ingredient storage.
Each station (Workbench, Forge, Artisan Table, Black Forge, Food Preparation Table, Cauldron, Galdr Table, Mead Ketill — and any other crafting station) can be expanded once for a structure-dependent price. Expanding unlocks a fixed number of ingredient slots that scales with the station's level. Every slot holds one ingredient type but an unlimited amount of it, and only accepts ingredients the station can actually use for crafting/repairing.
Features
- One-time expansion from the crafting menu. An
Expandbutton appears in the crafting panel of a station (with the cost item's icon, amount and a Valheim-style tooltip). It charges a single structure-dependent cost (default 100 of the station's signature wood — see below). Once expanded the button disappears. - Level-based slot count. Expanding grants
station level × SlotsPerStationLevelslots. Upgrading the station later adds more slots automatically. - Storage window on interact. Press E (Use) on an expanded station to open its storage window. It lists every used slot with an icon, name and count.
- Search field. Type to filter slots — handy once a station has many slots.
- Chest-style filling.
Fill from inventorypushes every matching item from your inventory into its slot, exactly like quick-stacking into a chest. Each slot row also has compact controls:+ stack/+ allto deposit and- stack/- allto withdraw. Withdrawing a slot to empty releases it so the freed slot can hold a different ingredient. - Add-ingredient dropdown. Bind a free slot to any allowed ingredient (it immediately pulls what you're carrying).
- Ingredient restriction. Only items that appear as an ingredient in a recipe the station can craft/repair may be stored (toggleable in config).
- One ingredient per slot, unlimited quantity.
- Spill on removal. When the station is removed with the hammer or destroyed, all stored materials and the resources you paid to expand are dropped on the ground.
- Multiplayer-safe persistence. All state lives in the station's own ZDO, so it saves with the world and replicates to other players. The interacting client claims ownership before writing (same model vanilla containers use), and a soft "in use" lock stops two players editing the same station simultaneously.
How it works (design)
| Concern | Implementation |
|---|---|
| Attach storage to stations | Harmony postfix on CraftingStation.Awake adds a StationStorage component. |
| Persistence / sync | Expanded flag + used slots + paid cost are serialized into the station ZDO (css_expanded, css_data, css_cost, css_rev). A revision int tells clients/UI when to refresh. |
| Slot capacity | station level × SlotsPerStationLevel (clamped by MaxSlotsPerStation), evaluated live from CraftingStation.GetLevel(). |
| Allowed ingredients | Built from ObjectDB.instance.m_recipes: every ingredient of every recipe whose crafting/repair station matches. |
| Interact window | Built at runtime with Jötunn's GUIManager (woodpanel + scroll view + buttons + input field + dropdown). No asset bundle required. |
| Expand button | Injected into the crafting panel via a postfix on InventoryGui.Update; hidden once IsExpanded. |
| Spill on removal | Manually patched (with per-hook try/catch) on Piece.DropResources, WearNTear.Remove and WearNTear.Destroy, de-duplicated so it spills exactly once and never on world unload. |
Building
This project references Valheim + Unity assemblies from your local game
install (they can't be redistributed). NuGet packages (BepInEx.Core,
JotunnLib, Krafs.Publicizer) are restored automatically.
-
Install the .NET SDK (6.0+).
-
Point the build at your Valheim folder and build:
dotnet build -c Release -p:VALHEIM_INSTALL="C:\Program Files (x86)\Steam\steamapps\common\Valheim"or create
CraftStationStorage.csproj.user:<Project> <PropertyGroup> <VALHEIM_INSTALL>C:\Path\To\Valheim</VALHEIM_INSTALL> </PropertyGroup> </Project> -
Copy
bin/Release/CraftStationStorage.dllintoValheim/BepInEx/plugins/. Jötunn must also be installed.
Krafs.Publicizerpublicizesassembly_valheimat build time so the code can use private fields likem_nview,m_inventoryandm_craftingStationwithout reflection.
Configuration
Config file: BepInEx/config/com.moddev.craftstationstorage.cfg
| Section | Key | Default | Notes |
|---|---|---|---|
| General | Enabled |
true |
Master switch. |
| General | IncludedStations |
(empty) | CSV of station piece prefab names. Empty = all crafting stations. |
| General | ExcludedStations |
(empty) | CSV of station prefab names to skip. |
| Behavior | RestrictToUsableIngredients |
true |
Only accept ingredients the station uses. |
| Behavior | SpillOnRemove |
true |
Spill materials + expansion cost on removal/destruction. |
| Behavior | SlotsPerStationLevel |
5 |
Slots granted per station level. Capacity = level × this. |
| Behavior | MaxSlotsPerStation |
0 |
Hard cap on slots. 0 = no cap (level-based only). |
| Cost | StationExpansionCosts |
(per-station map) | One-time cost. piecePrefab:itemPrefab:amount entries separated by ;. |
| Cost | FallbackExpansionItem |
Wood |
Cost item for stations not listed in the map. |
| Cost | FallbackExpansionAmount |
100 |
One-time cost for unlisted stations. |
| Input | ExtraOpenKey |
None |
Optional extra key to open storage while hovering an expanded station. |
| UI | BuyButtonOffsetX/Y |
0 / 40 |
Nudge the Expand button. |
| UI | WindowWidth/Height |
540 / 640 |
Storage window size. |
Default per-station expansion cost (StationExpansionCosts)
| Station | Prefab | One-time cost |
|---|---|---|
| Workbench | piece_workbench |
100 Wood |
| Forge | forge |
100 Core wood (RoundLog) |
| Cauldron | piece_cauldron |
100 Core wood |
| Black forge | blackforge |
100 Yggdrasil wood |
| Food preparation table | piece_preptable |
100 Fine wood |
| Galdr table | piece_magetable |
100 Yggdrasil wood |
| Mead ketill | piece_MeadCauldron |
100 Core wood |
| Artisan table | piece_artisanstation |
100 Fine wood |
| (anything else) | — | FallbackExpansionAmount of FallbackExpansionItem (100 Wood) |
Slots granted = station level × SlotsPerStationLevel (default 5). For example a
level-3 Forge grants 15 slots; upgrading it to level 4 raises that to 20.
Known station piece prefab names: piece_workbench, forge,
piece_artisanstation, blackforge, piece_magetable, piece_cauldron,
piece_preptable (Food Preparation Table). The Mead Ketill and any other
crafting station are covered automatically because targeting is based on the
CraftingStation component, not a hard-coded prefab list.
Notes / caveats
- This mod cannot be compiled or tested in this environment (no .NET SDK,
no Valheim assemblies). The code is written against the documented public API
and Jötunn 2.24.x. The most likely area to need small tuning against your
installed Jötunn/Valheim version is the runtime UI layout in
src/UI/StoragePanel.cs(element positions/anchors). All GUI creation is wrapped in try/catch and logs to the BepInEx console instead of crashing. - Because the mod changes persisted world data, it is marked
EveryoneMustHaveMod— install it on the server and all clients. - Spilled "infinite" stacks are dropped as a single item entity per slot; picking them up merges up to the normal stack size and leaves the remainder on the ground.
Project layout
CraftStationStorage/
├─ CraftStationStorage.csproj
├─ manifest.json # Thunderstore metadata
├─ src/
│ ├─ Plugin.cs # BepInEx entry + config + Harmony bootstrap
│ ├─ Patches/Patches.cs # Harmony patches (attach, buy button, spill, hotkey)
│ ├─ Storage/StationStorage.cs # per-station data model, ZDO persistence, ops, spill
│ ├─ Storage/StationIngredients.cs # allowed-ingredient index + item metadata cache
│ ├─ UI/BuySlotWidget.cs # "+ Slot" button in the crafting panel
│ ├─ UI/StoragePanel.cs # interact window (search + slot rows + deposit/take)
│ └─ Util/ItemUtils.cs # inventory <-> storage helpers + ground drops