Valheim
You are viewing a potentially older version of this package. View Latest Version
Install with App

Details

Date Uploaded
3 days ago
Downloads
98
Size
46KB
ADDatHost Valheim hosting
€1

BeanheimNet

Networking improvements for Valheim 1.0.x dedicated servers and clients, with built-in telemetry so every change can be measured instead of guessed. One DLL runs on the server and on clients. No version lock and no wire-format changes: a player without it still connects and simply keeps vanilla behaviour on their side.

What vanilla does, in one paragraph

Every object update is sent reliable on one Steam lane. The game keeps at most 10 KB in flight per player, so throughput is 10 KB ÷ round-trip time (68 KB/s at 150 ms), and Steam's send rate is pinned at 150 KB/s. The same limits apply to each client's own uploads. Building pieces are always sent before creatures, carts and dropped items. Owners write position on any exact change, so a bobbing or jittering object talks every frame, and most relayed traffic on a typical server is ambient fauna.

Features

Everything invisible to players ships on. The two that change what players see ship off: Cleanup (deletes far-off floating junk) and ItemMerge (merges nearby piles).

cfg section What it does Runs on
02 SendWindow Window per peer = RTT × target rate × BDP factor, clamped [MinWindowBytes, 65536]; vanilla when no reading exists. MinWindowBytes matters for LAN peers (a 0 ms ping gets no RTT sizing, and at ~10 send rounds/s the vanilla 10 KB window is a ~100 KB/s cap). Queue-drain compatibility for mods that wait on the socket queue (ServerSync, Jotunn, ConditionalConfigSync); raises Jotunn's MaximumSendQueueSize while on. Transpiler with an IL shape check that refuses if SendZDOs changed. both
03 Scheduler Serve every connected peer each interval under a frame budget instead of one peer per frame with an idle arming frame. ServerTargetFrameRate raises the dedicated server's hard 30 fps request (0 = vanilla). both
04 SteamTransport SendRateMin and SendRateMax to SendRateKBps (Steam requires them equal), globally and on live connections, read back. Without it a bigger window only builds queue. both
05 RelayThrottle Per class (fish / creature / item) and distance band, cap how often Default-type objects are re-sent. Distance is measured from the receiver on the server and from the nearest loaded player on the client uplink, so nothing anyone is looking at is slowed. Defaults (near/far/beyond, Hz): fish 6/3/2, creature ∞/10/5, item ∞/5/3, bands at 40 m and 100 m; receivers extrapolate motion between updates. Nothing is dropped; exempt: never-sent objects, ownership changes, force-sends, players/ships/carts, non-Default types. both
06 Priority Age-fair send order below the foreign-owned-Prioritized and Terrain tiers, so a creature, cart or drop beside a player can outrank a distant building backlog; live x/z reference position from the character. server
07 Deadband Owner-side: skip position/rotation/velocity writes inside a small deadband of the last written value; one exact zero velocity when an object comes to rest. Never players, ships, carts or Prioritized objects. clients
08 Telemetry Per peer every 10 s: Steam RTT vs app RTT (the gap is bufferbloat), window, queue, in-flight, rounds, refused, candidates, sent, KB/s, deferred, throttled, ms/call, top prefabs; receive tally; boot census of every object by prefab and type. Also appended to BepInEx/BeanheimNet-stats.log, which survives restarts. both
09 Items Server: periodic report of dropped items (by prefab, age, in water, far from players). Cleanup = true deletes items older than MaxAgeHours of played time, farther than ProtectRadiusMeters from every player, not near a base piece, in water by default, not on the protected list. Hard rule no setting relaxes: an item with custom data (every EpicLoot enchantment), a quality above 1, or a max stack of 1 (all gear) is never deleted. Every deletion is logged. server
10 ItemMerge Client side: merge same-name, same-quality, same-variant plain stackable drops within MergeRadiusMeters (5) into one stack every MergeIntervalSeconds (30). Vanilla auto-stacks at 4 m, once per item, only while 200+ drops are loaded. Same hard exclusions as Cleanup. clients
11 Triggers One-shot keys (Census, ItemReport, ItemCleanupOnce, Stats): set to true, it runs on the next reload and resets itself. The dedicated server binary never reads console input, so this is how the server is driven. both

In-game console (clients): bnet stats | census | items | cleanup dryrun|run | reload | config.

The cfg is live: edits are picked up within ConfigReloadSeconds (5 s) without a restart.

Reading the numbers

  • deferred = candidates that did not fit the window this round. Sustained non-zero at 2+ peers means the window is the wall. With ≤ 1 peer it is structurally 0 (nothing to relay).
  • refused = rounds that sent nothing because the queue was above the window. High refused with high rtt is the 10 KB/RTT limit.
  • app RTT ≫ rtt (Steam) = data queueing behind other data (bufferbloat).
  • throttled = RelayThrottle deferrals this interval (spaced out, not lost).
  • frame avg 33.3ms on a server line = the dedicated server's 30 fps cap; sched frames/served/budget-breaks appear when Scheduler is on.
  • steam-status ok N not-ok N last <EResult> appears if Steam's connection-status call fails; without it the window stays vanilla for that peer.
  • Vanilla's own Connections N ZDOS:X sent:Y recv:Z line stays as the cross-check; both counters are meaningless at ≤ 1 peer.

Measuring a change

Turn one toggle off in the cfg (live), play ten minutes, compare the stats lines, turn it back on. Measured on a two-to-four-player server before release: a LAN client's upload went from ~130 KB/s pinned at the Steam cap with thousands of updates deferred per ten seconds to ~44 KB/s with none deferred, and an area arrival that trickled for 15–20 s drained in about half a second.

Rollback

[01 General] Enabled = false (live) makes every patch behave like vanilla on its next call. Full removal: delete the plugin folder. Nothing persists in the world except Cleanup deletions, and only when it was enabled.

Fail-soft rules

Every private game member is bound once at startup; a missing member disables only the features that need it, with a logged reason. Every patch body is wrapped: an exception logs once per minute and that call falls back to vanilla. The plugin installs telemetry only if Smoothbrain Network, ValheimTune, NetworkPerformanceSystem, ReturnToSender, BetterNetworking or VBNetTweaks is loaded, and lists every other Harmony owner of the methods it touches at boot ([owners] lines).

Building

dotnet build BeanheimNet/BeanheimNet.csproj -c Release

References resolve from the game's valheim_Data/Managed folder and a BepInEx 5 install (Directory.Build.props holds the paths; override with -p:ValheimDir=… / -p:GaleProfileDir=…). -p:DeployToProfile=true also copies the DLL into that profile's BepInEx/plugins/BeanheimNet/. tools/package.sh builds the Thunderstore zip.

DatHost — Valheim server hosting, first month for one euro
DatHost — Valheim server hosting, first month for one euro
DatHost — Valheim server hosting, first month for one euro
DatHost — Valheim server hosting, first month for one euro
DatHost — Valheim server hosting, first month for one euro