glemoig-CraftStationStorage icon

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-5.4.2202 icon
denikson-BepInExPack_Valheim

BepInEx pack for Valheim. Preconfigured and includes unstripped Unity DLLs.

Preferred version: 5.4.2202
ValheimModding-Jotunn-2.24.3 icon
ValheimModding-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.3

README

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 Expand button 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 × SlotsPerStationLevel slots. 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 inventory pushes every matching item from your inventory into its slot, exactly like quick-stacking into a chest. Each slot row also has compact controls: + stack / + all to deposit and - stack / - all to 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.

  1. Install the .NET SDK (6.0+).

  2. 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>
    
  3. Copy bin/Release/CraftStationStorage.dll into Valheim/BepInEx/plugins/. Jötunn must also be installed.

Krafs.Publicizer publicizes assembly_valheim at build time so the code can use private fields like m_nview, m_inventory and m_craftingStation without 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