Releases: Akoozie/ValheimTune
Release list
ValheimTune 0.7.0 — Valheim 1.0 support
Server-side BepInEx plugin for Valheim dedicated servers. Players install nothing.
This binary is byte-for-byte the one running on the reference server — same sha256, no separate release build.
sha256 98440ca31f5b4d807d5be53f519a22b1524c7890eca7e5c6a5f12513c43a48b3
Compatibility
game 1.0.7 (network version 39)
server build 25185644 (Steam app 896660)
needs BepInEx 5.4.x for Valheim
On any other game version the plugin runs in vanilla + measurement mode and says so in the log. Still on 0.221.12? Use 0.6.0.
⚠️ Upgrading from 0.6.0 — read this or the plugin will do nothing
BepInEx reads your existing config file, not the new defaults. Your akoozie.valheimtune.cfg still says:
[Compat]
KnownGoodBuilds = 0.221.12On game 1.0.7 that fails the version gate and every replacement patch silently disables itself — the log says replacements OFF and the plugin measures vanilla while looking perfectly healthy. Edit it before or after copying the DLL:
[Compat]
KnownGoodBuilds = 1.0.7The now-orphaned [Save] SlicedSave and [Save] SaveSliceMs keys are harmless; BepInEx ignores them. You can delete them or leave them.
What changed for Valheim 1.0
Sliced save removed — 1.0 does it better
ZDOMan.SaveAsync no longer exists. Valheim 1.0 rewrote world saving to write one file per chunk and clone only the dirty chunks. Measured on a 698,746-object world, idle:
first save (50/50 dirty) next save (0/49 dirty)
chunk writing 2,713 ms 3 ms
clone (GetSaveClonePerChunk) 187 ms 6 ms
That is a strictly better answer than slicing the clone across frames, so SlicedSave and SaveSliceMs are gone rather than ported. Vanilla now handles it.
Dirty sets re-pointed at the new simulation distance
1.0 removed ZoneSystem.m_activeArea / m_activeDistantArea and the three-argument ZNetScene.InActiveArea. The sync radius is now a per-peer SimulationDistance, clamped server-side to min(client request, server cap). The dirty-set area test was rewritten to mirror the ring predicate in ZDOMan.FindSectorObjects.
Also
Version.m_networkVersionrenamed toVersion.c_networkVersion[Compat] KnownGoodBuildsdefault is now1.0.7- 11 patched methods, down from 15 (the four save-path patches are gone)
Everything else — top-K selection, relay throttle, receive cap, Steam send rate, target frame rate, deferred asset unload, render-mesh skip, the watchdog and the stats line — rebuilt unchanged. ZRpc.cs and ZSteamSocket.cs are byte-identical between 0.221.12 and 1.0.7.
Verified live on 1.0.7
Deployed 2026-09-09 with a player online, 698,748 objects:
[ValheimTune] 0.7.0 loaded on game 1.0.7 (net 39), 11 methods patched, replacements on
[ValheimTune] SendZDOs window 32768/4096, 3 constants replaced (expected 3)
syncList avg 0.07–0.11 ms frame avg 16.7 max 17.0 ms (60 fps)
| Sync cost per call | |
|---|---|
| vanilla 0.221.12 | 4.1 ms |
| dirty sets on 0.221.12 | 0.07 ms |
| dirty sets on 1.0.7 | 0.09 ms |
The rewritten area test was also checked the way counters cannot check it: healthy numbers are equally consistent with an area test that silently drops objects, so the base was walked and confirmed complete before shipping.
SkipRenderMesh fired for the first time on 1.0 (meshSkips 34) — 1.0's zone generation finally gives it ungenerated terrain to skip. It remains default off pending a longer exploration run.
G1 verified after release — every feature is now live-tested
DeferAssetUnload remains default off, but it has now been observed working on 1.0. The hour boundary landed with a player connected:
[ValheimTune] asset unload deferred: 1 player(s) online, will run when the server empties (backstop 240 min)
Frames across the boundary held 16.9-24.6 ms at 60 fps - none of the 443-607 ms Resources.UnloadUnusedAssets() stall measured on 0.221.12. Turn it on with [Server] DeferAssetUnload = true if hourly hitches bother your players.
Known remaining cost (vanilla, not this plugin)
ZDOExtraData.PrepareSave is byte-identical to 0.221.12 and still clones eight maps on every save regardless of how little changed. Measured on 1.0.7 with a player online, one dirty chunk out of 49:
clone 32 ms main thread
ZDOExtraData.PrepareSave 204 ms main thread
chunk writing 142 ms writer thread
-> frame max 243 ms
The plugin does not patch this. It is the best-evidenced target left, and a fix is not simply reinstating the old sliced-save prefix - that clone is what keeps the writer thread safe.
Install
Drop ValheimTune.dll into BepInEx/plugins/ on the server. Nothing goes on clients. Full config reference and the stats-line guide are in the README.
ValheimTune 0.6.0
Server-side BepInEx plugin for Valheim dedicated servers. Players install nothing.
This binary is byte-for-byte the one running on the reference server — same sha256, no separate release build.
Compatibility
game 0.221.12 (network version 36)
server build 21981590 (Steam app 896660)
needs BepInEx 5.4.x for Valheim
On any other game version the plugin runs in vanilla + measurement mode and says so in the log. New in this release: the README now explains what to do when that happens — previously it pointed at a porting doc written for maintainers, which was no help to a server admin.
New in 0.6.0 — G1, deferred asset unload
Vanilla calls Resources.UnloadUnusedAssets() every hour, regardless of whether anyone is playing:
// src_server/Game.cs:239
InvokeRepeating("CollectResourcesCheckPeriodic", 3600f, 3600f);Measured on a 698,000-object world:
Unloading 2 unused Assets ... 607 ms
Unloading 1 unused Assets ... 456 ms
Unloading 0 unused Assets ... 443 ms <- frees nothing, still 443 ms
The cost has nothing to do with what it frees — Unity's MarkObjects walks all ~207,000 loaded objects to release one asset. It was caught landing with two players online at frame max 512 ms against a 17 ms baseline.
Both vanilla entry points route through Game.CollectResources, so one prefix covers them.
[Server]
DeferAssetUnload = false # default
AssetUnloadMaxDeferMinutes = 240Deferred, not skipped. Memory hygiene still matters — the collection runs the moment the last player disconnects, or after the backstop if your server never empties.
Honest status: this ships off and is not yet verified in the field. It is live on the reference server with the knob on, but proving it requires a player online across an hour boundary, which has not happened yet. With an empty server the deferral is a no-op. If you turn it on, look for asset unload deferred: N player(s) online in your log, then asset unload running after N s deferred once everyone leaves.
SkipRenderMesh from 0.5.0 is likewise still off and still unproven — it only fires on terrain that has never been generated, which an explored world does not have.
Everything else, unchanged from 0.5.0
690,000 objects, a 12,000-instance base, 2-6 players, on a 4-core laptop:
| Vanilla | ValheimTune | |
|---|---|---|
| Sync scan, per player per round | 4.1 ms | 0.07 ms |
| Autosave | 381 ms freeze in one frame | 6 ms slices over ~350 frames |
| Join sync cost | ~11 ms per call | ~5.5 ms |
| Join stream rate | 1,261 objects/s | 3,617 objects/s |
| Server frame rate | 30 fps, hard-capped | 60 fps |
Full history in CHANGELOG.md.
Verify the download
sha256 b351d8958020dcb9225e349701ec259df844484d270b97b9a43f4d39c085254d
size 51,200 bytes
MIT licensed. Not affiliated with Iron Gate or Coffee Stain.
ValheimTune 0.5.0
Server-side BepInEx plugin for Valheim dedicated servers. Players install nothing — every change is on the server and the wire format is untouched, so vanilla clients connect exactly as before.
Compatibility
game 0.221.12 (network version 36)
server build 21981590 (Steam app 896660)
needs BepInEx 5.4.x for Valheim
On any other game version the plugin runs in vanilla + measurement mode and says so in the log — it will not silently apply old patch logic to new code.
Install
- Install BepInEx on the server. With the
lloesche/valheim-serverDocker image that isBEPINEX=trueinserver.env. - Drop
ValheimTune.dllintoBepInEx/plugins/(Docker:config/bepinex/plugins/). - Restart. The config appears at
BepInEx/config/akoozie.valheimtune.cfg.
Confirm in the log:
[ValheimTune] 0.5.0 loaded on game 0.221.12 (net 36), 14 methods patched, replacements on
Then apply the recommended settings one at a time.
Measured on the reference server
690,000 objects, a 12,000-instance base, 2-6 players, on a 4-core laptop.
| Vanilla | ValheimTune | |
|---|---|---|
| Sync scan, per player per round | 4.1 ms | 0.07 ms |
| Autosave | 381 ms freeze in one frame | 6 ms slices over ~350 frames |
| Join sync cost | ~11 ms per call | ~5.5 ms |
| Join stream rate | 1,261 objects/s | 3,617 objects/s |
| Server frame rate | 30 fps, hard-capped | 60 fps |
New in 0.5.0
[Server] SkipRenderMesh — a headless server rebuilds terrain render meshes it never draws. This prefixes Heightmap.RebuildRenderMesh and skips it; the collision mesh, paint mask and material instance are untouched.
It ships off, and honestly unproven. On the reference server the prefix attached but the new meshSkips counter stayed 0 across a five minute exploration run, because the server only instantiates a heightmap for ground that has never been generated and an explored world has none. Leave it off until you see meshSkips climb.
Everything else in this release is unchanged from 0.4.2. Full history in CHANGELOG.md.
Verify the download
sha256 d1d49249b66f09acdc873a1098411eb8ca16ec4d78438f26abfcc9481581cded
size 48,640 bytes
MIT licensed. Not affiliated with Iron Gate or Coffee Stain.