


Makes the Swamp Key / Crypt Key ($item_cryptkey) persist indefinitely instead of being
consumed one-per-use when opening a Sunken Crypt gate.
In vanilla Valheim the Crypt Key is not consumed — you keep it forever. Some mods change this
by hooking Door.Open and removing one key from your inventory every time you open a Sunken
Crypt gate (with no config option to turn it off). This mod counters that behavior so your key
behaves like vanilla again: open as many crypts as you like, the key stays.
Patch-order-proof and mod-agnostic. A Door.Open Prefix opens a short "protect window" and
records the door's key item name; a Finalizer closes it. Because Harmony finalizers run
after every postfix, the window reliably spans any other mod's Door.Open postfix regardless
of patch order. While the window is open, prefixes on Inventory.RemoveOneItem / RemoveItem
refuse to delete that key (and report success, so the other mod's logic is unaffected).
It only protects the key during a crypt-gate open — you can still drop, store, trade, or craft with the key normally.
The key consume is a client-side operation, so on its own this DLL could be carried to any server
to keep keys. To prevent that, key protection only activates on a server that also runs this
mod (or when you are the host). A sanctioning server sends each connecting client a tiny
ServerHello handshake RPC; a client only protects keys once it has received that Hello. On a
server that does not run the mod, no Hello arrives, protection stays off, and keys consume
normally. The gate is hardcoded (not exposed in config) so it can't be flipped off to cheat
elsewhere.
This is a client + server mod. The server must run it to sanction key-persistence, and
each player must also install it (the consume happens on the client). Install on both with a
mod manager, or manually drop SwampKeyPersist.dll into BepInEx/plugins.
baka.SwampKeyPersist.cfg:
| Setting | Default | Description |
|---|---|---|
Enabled |
true |
Master switch. |
ProtectAllKeyedDoors |
false |
Protect the key of ANY keyed door, not just Sunken Crypt gates. |
CryptDoorNameContains |
sunken_crypt_gate |
Comma-separated substrings; a door whose GameObject name contains any of these is treated as a crypt gate whose key must persist. |
After opening a Sunken Crypt gate, the BepInEx console logs:
Preserved door key '$item_cryptkey' (blocked consume on crypt-gate open).