


Sorts nearby chests on demand with a single keypress. Chests infer their own category from their contents; you can pin a category permanently with the catagory dropdown inside in-game containers. Multiplayer compatible via ZDO sync.
| Feature | Detail |
|---|---|
| Keybind sort | Press Alt+R (configurable) to sort all chests within ScanRadius |
| Spatial ordering | Chests filled in reading order (top-left → right, then down); same-category chests grouped together |
| Fill-first tagged | Tagged chests of the same category fill completely before spilling to the next |
| Category inference | Chest dominated by Wood items "owns" Wood — no setup needed |
| Tag override | autosort_tag Wood while looking at a chest pins it to Wood permanently |
| Ground suction | Dropped items on the ground are periodically pulled into matching chests |
| Hover tooltip | Shows chest category, tagged/inferred, and the sort keybind reminder |
| Visual effects | Blue highlight + particle VFX on sorted chests (configurable) |
| Multiplayer | MoveItemToThis + ZDO dirty-mark; no server plugin required |
Config file location after first launch:
BepInEx/config/com.yourname.valheim.autosort.cfg
Editable in-game via r2modman config editor or any text editor.
| Key | Default | Description |
|---|---|---|
ModEnabled |
true |
Master switch. Disables everything without uninstalling. |
LogDebug |
false |
Verbose BepInEx console logging for troubleshooting. |
| Key | Default | Description |
|---|---|---|
EnableTagOverride |
true |
Allow autosort_tag <Category> to pin chests. Requires relogging to affect existing chests if changed mid-session. |
| Key | Default | Range | Description |
|---|---|---|---|
SortKeybind |
Alt+R |
Any key combo | Keyboard shortcut that triggers a full sort. Configurable via r2modman. |
ScanRadius |
16 |
4 – 64 m | Radius around the player within which chests are included in a sort pass. |
| Key | Default | Range | Description |
|---|---|---|---|
EnableGroundSuck |
true |
— | Pull ground items into matching chests periodically. |
GroundSuckRadius |
8 |
2 – 32 m | Radius around the player to search for ground items. Independent of ScanRadius. |
GroundSuckInterval |
5 |
1 – 60 s | Seconds between ground scans. Lower = more responsive, slightly more CPU. |
| Key | Default | Description |
|---|---|---|
HighlightContainers |
true |
Flash chests blue when items are sorted into them. |
PingContainers |
true |
Spawn a particle VFX at sorted chests. |
PingVFX |
vfx_Potion_health_medium |
VFX prefab name. Leave blank to disable. Browse prefabs |
Build chests near each other and put a different type of item in each. After a few deposits the mod infers each chest's category. Press Alt+R whenever you want items redistributed.
Look at the chest, open console (F5):
autosort_tag Stone
Valid categories (case-insensitive):
Stone, Wood, Metal, Ore, Gem, Leather, Bone, Fiber, Seed,
Food, Potion, Fish, Arrow, Weapon, Shield, Armor, Tool,
Magic, Trophy, Furniture, Misc
Clear a tag:
autosort_tag
Player presses Alt+R
│
▼
Patch_Player_Update detects SortKeybind.IsDown()
(blocked if inventory / map / store GUI is open)
│
▼
SortEngine.TriggerSortPass()
├─ Sets IsRearrangingItem = true (blocks all AddItem callbacks)
├─ Yields one frame
│
└─ DoSort(playerPosition)
├─ ChestOwnershipResolver.Resolve()
│ ├─ Tagged chests → pinned category, priority 1
│ │ └─ Multiple tagged of same category: rightmost first
│ └─ Inferred chests → dominant item category, priority 2
│
├─ ChestOwnershipResolver.PlanSortFull()
│ ├─ SortInferredByPosition()
│ │ ├─ Pass 1: reading order (top-left → right, then down)
│ │ ├─ Pass 2: find each category's earliest spatial anchor
│ │ └─ Pass 3: cluster same-category chests at their anchor
│ │
│ └─ FindDest() priority chain (mirrors single-item path):
│ 1. Tagged chest (rightmost first, fill before spilling)
│ 2. Inferred chest already holding this item (consolidate)
│ 3. Any inferred chest for this category (spatial order)
│ 4. Free/unclaimed chest (spatially earliest)
│
├─ Execute moves (deferred removal to avoid HashSet mutation crash)
│
├─ PackInventorySlots() for each dirty chest
│
├─ MarkDirty() ONCE per modified chest (ZDO write)
│
└─ Re-read live inventory → notify player of any homeless categories