Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
NetworkPerformanceSystem
Makes Valheim playable for groups spread across continents. Sizes each peer's send window and places simulation authority by measured latency.
| Date uploaded | 2 days ago |
| Version | 1.8.0 |
| Download link | MidnightMods-NetworkPerformanceSystem-1.8.0.zip |
| Downloads | 2018 |
| Dependency string | MidnightMods-NetworkPerformanceSystem-1.8.0 |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured with the correct entry point for mods and preferred defaults for the community.
Preferred version: 5.4.2333ValheimModding-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.27.1README
NetworkPerformanceSystem
Network Performance Systems is a general networking overhaul, designed to tackle the problem created by high ping.
In Valheim, most objects are simulated by users. So a single high ping user in an area can make everything or all sorts of things feel terrible. This mod aims to address that in a number of ways.
Why this is different from the other networking mods
Every other Valheim networking mod treats multiplayer performance as a bandwidth problem — compression, bigger buffers, higher send rates, filtered broadcasts. That is the right diagnosis for ten people in one base saturating a shared cap. It does not handle a larger distributed server, or multiple players from vastly different goegraphic locations.
NPS addresses these issues in a number of ways
- Each peer gets their own Round Trip timing (RTT), Healthcheck and bandwidth estimates
- This allows dynamic adjustments to route around a poor connection
- This higher ping players with decent bandwidth allow the server to send more aggressively to these players in compensation
- Object ownership can be dynamically adjusted around players with poor connections to provide the best experience for all players in the area
- Objects which need network calls to interact with get ownership transferred ahead of time, delay scenarios much less likely
- Objects that change ownership during active requests get their requests properly re-targeted against the new owner
- Objects which are locally important (footsteps for example) are only network broadcast locally, instead of globally around the server
- Server Garbage collection churn is significantly reduced compared to vanilla
Installing
Server-only works. Vanilla clients get the send window, ownership, scheduler, station-request and creature-hit fixes with nothing installed on their end, and the server follows where they actually are rather than where they were two seconds ago.
Installing on clients too adds latency compensation, live position reporting and the clean exit from a dead session for those clients, and lets a ship they own pass to whoever takes its helm. Mixed groups are fine — benefits are per-player, and a client without the mod behaves exactly as vanilla. There is no version lock: nobody gets kicked for not having it.
Works on dedicated servers and on player-hosted games.
Diagnosing and Reporting a problem
An easy way to start is enabling the nps_stats display Run nps_stats_collect (needs devcommands, since sampling costs a Steam call per peer per tick), play, then nps_stats.
A player the link-pressure table marks as LOSSY is already being dealt with: the server steps that one player's send rate down until their connection stops losing packets, and back up once it is clean, without changing anyone else's rate (Steam Transport / Enable Loss Backoff). The "Loss backoff" block shows who is backed off and by how much.
Lag, rubber-banding, hits not landing? Send a report.
Server owners: in
BepInEx/config/MidnightsFX.NetworkPerformanceSystem.cfg, setEnable Network Monitoring = trueunder[Monitoring]. You do not need to restart, and an admin can also change it in game. Play through the problem, set it back tofalse, and zip the newest folder inBepInEx/NpsMonitoring/.Players: your game sends nothing unless the server asks, and never sends names, platform ids, addresses or chat. To opt out anyway, set
AllowMonitoringUpload = falseunder[Client config]in your own copy of that file. The server cannot override it. It only stops your game uploading: the server still logs its own side of the connection, such as your ping, under an anonymous session number.Then post the zip as a GitHub issue or on the Discord, with a description of what you saw: what happened, how often, roughly when, and how many players were on. See Reporting a network problem for what is recorded.
If creatures rubber-band, hits do nothing, or things freeze when players come and go, the server can record what the network was doing so it can be diagnosed rather than guessed at.
- On the server, set
Enable Network Monitoringtotruein theMonitoringsection. No restart is needed, and it can be changed in game by an admin. - Play through the problem. An evening with the usual players is ideal.
- Set it back to
false. - Zip the newest folder under
BepInEx/NpsMonitoring/on the server and send it, with a sentence about what players saw and roughly when, as a GitHub issue or on the Discord.
What is recorded: each time a creature changes owner and whether the change held, messages delivered to a player who no longer owned the target, how regularly each player's creatures report in, and each player's ping and connection quality once a second. Clients that have the mod add what only they can see: what a creature was doing when it changed hands, who it was fighting, how far it jumped on screen, and frame rate. That costs each client up to 2 KB per second of upload, sent in small batches that are held back whenever the connection is busy with the game's own traffic, so recording never delays it.
What is not: player names, Steam or platform ids, IP addresses, chat. Players appear only as
the random session number the game gives them for that connection, and positions are rounded to
the metre. Any player can refuse to send anything by setting AllowMonitoringUpload to false in
their own config.
While it is off it costs nothing: the hooks it uses are only installed while it is on. The folder
is capped by Max Disk MB (4096 by default, across all sessions). When the cap is reached recording
stops and the log says so; nothing already recorded is deleted, so clear out old sessions yourself.
nps_stats shows whether it is running and whether anything is being dropped.
Incompatible with
Other networking mods that rewrite the same code: FiresGhettoNetworking, VBNetTweaks, SkadiNet,
BetterNetworking, Smoothbrain's Network, NetworkTweaks, WarheimNetwork, TimeoutLimit. BepInEx will
refuse to load this mod alongside them rather than leave you half-patched. TimeoutLimit in
particular is no longer something you give up: the Connection Timeout settings cover the same
ground, and unlike a timeout raised at one layer only, they move both of the places vanilla times
out at.
Verified compatible (different layers, no overlap): LeanNet, Compress, Scenic. ReturnToSender is
fine too — it already fixes the scheduler, so that one mechanism stands down and the rest keeps
working. EnRoute and BetterZeeRouter are fine in the same way: both rework the routed-RPC relay, so
relay filtering and relay send reuse stand down when either is present and everything else keeps
working.
Valheim Plus is fine too: it has its own player limit, so this mod's Player Limit settings are
ignored when it is installed and V+'s maxPlayers is the one in force.
ClientGhostWatchdog is fine as well: it does the client-side half of the ghost handling itself and
against its own timeout, so this mod's client watchdog stands down and leaves that mod's behaviour
in charge. The host-side half — evicting a ghost from ownership, which that mod does not do — keeps
running either way.
Credits
- Disconnect ghosting from ClientGhostWatchdog by DreamWraith.
- ZDO Redirect from BetterZeeRouter
CHANGELOG
Changelog
1.9.0
- Creatures no longer get stuck with a player who walked away and came back.
- Fixed objects outside the normal world area changing owner several times every two seconds.
- A player whose packet loss does not improve when the server slows down for them goes back to full speed, and is not slowed down again until the server restarts.
- Peer simulation distance is now included in ownership calculation decisions
1.8.0
- Improves how tightly a players position is tracked to better arbitrate ownership
- The server follows each player's character directly, as it arrives with the game's own object updates. New
Reference Positionsetting Use Character Position (default on). Works for players without the mod and costs nothing on the wire.
- The server follows each player's character directly, as it arrives with the game's own object updates. New
Steam Transport: Send Rate Max KBps and Send Rate Min KBps are replaced by a single Send Rate KBps (default 0, the game's 150).- The new setting is the exact rate the server sends to each player, and it is applied on the server only. Steam never slows down for a connection that cannot keep up, so budget the server's upload for players × rate. A player whose connection cannot take it loses packets instead of getting a slower stream.
Send WindowTarget Rate KBps is also no longer read: each player's window is now sized from the rate Steam actually uses for their connection.
- The server now slows down for a player whose connection is losing packets, one player at a time. New
Steam Transportsetting Enable Loss Backoff (default on), with Loss Backoff Threshold (default 0.95) and Loss Backoff Floor KBps (default 32).- Steam sends to every player at one fixed pace and never slows down for a player who cannot keep up; that player got packet loss.
- When a player has received under 95% of what was sent for 10 seconds, their own connection's rate is stepped down by a quarter, again every 10 seconds while it stays lossy, never below the floor. Once clean for 60 seconds it is stepped back up one step at a time, until it follows Send Rate KBps again. Change rate is isolated to the impacted user.
- Server-side, and needs Enable Transport Tuning.
nps_statsgains a "Loss backoff" block, and the LOSSY verdict in the link-pressure table now says what has been done about it.
nps_stats_collectalso measures how often a send runs out of room before the end of its list, and whether creatures or players were among what was left for later. See the new "Send truncation" block.- Creatures are now arbitrated, and before anything else. New
Ownershipsetting Arbitrate Creatures (default on).- The game marks ships and players as moving objects but not creatures, so earlier prioritization of this caused them to be deprioritized instead.
nps_statsgains a "creatures" line in the Ownership block.
- Hits on creatures are delivered to whoever is simulating the creature. New
Routed RPCsetting Route Creature Hits To Owner (default on).- A hit sent to a player who no longer owned the creature, or to nobody because the attacker's game thought it had no owner, did nothing.
- A creature nobody is simulating is handed to the player who hit it, and the hit follows.
- Server-side, and works for players without the mod.
nps_statsgains a "Creature hits" block.
- Ownership changes made by the server now stick. New
Ownershipsetting Reject Stale Owner Updates (default on).- Server-side.
nps_statsgains a "stale owner" line in the Ownership block.
- Server-side.
- Network monitoring now records creatures.
1.7.0
- Players on a high-ping connection no longer see the world pause every 8 seconds while there is a lot going on.
Queue Drain Interval SecondsandQueue Drain Floor Bytesare no longer read and can be deleted from the config.nps_stats"Third-party send queue thresholds" shows how many outside reads were adjusted and how much is kept out of them for each player.
- A creature with exactly one player near it now belongs to that player, whatever anyone else's latency is. New
Ownershipsetting Creature Proximity Ownership (default on), with Creature Proximity Radius (default 48 m).nps_statsgains a "proximity" line: kept, pulled, and rescues it redirected.
- Network monitoring: a recorder a server owner can switch on when something is wrong, to send with a bug report. New
Monitoringsection, Enable Network Monitoring (default off). See "Reporting a network problem" in the README.- Records each change of a creature's owner and whether it held, messages delivered to a player who no longer owned the target, how regularly each player's creatures report in, and each player's ping and connection quality. Clients with the mod add what only they can see, at up to 2 KB per second in small batches that always wait for the game's own traffic, and a player can refuse with
AllowMonitoringUpload. - No player names, platform ids, addresses or chat. Players appear only as the session number the game gives them.
- Costs nothing while off: its hooks are installed when it is switched on and removed when it is switched off, with no restart either way.
- Written to
BepInEx/NpsMonitoring, compressed, and capped by Max Disk MB (default 4096). Recording stops at the cap; nothing already recorded is deleted. nps_statsgains a "Network monitoring" block.
- Records each change of a creature's owner and whether it held, messages delivered to a player who no longer owned the target, how regularly each player's creatures report in, and each player's ping and connection quality. Clients with the mod add what only they can see, at up to 2 KB per second in small batches that always wait for the game's own traffic, and a player can refuse with
1.6.0
- A player who has stopped answering no longer freezes everything they were simulating. New
Connection Timeoutsetting Evict Ghost Owners (default on), with Ghost Owner Evict Seconds (default 10).- "Stop trusting this peer to simulate" is a different question and is now asked separately. A peer that goes quiet loses its objects to the players who are actually there, while keeping its slot for the full timeout so it can come back. Nothing is disconnected any sooner, and if it returns it competes for ownership again on the next pass.
- Detection asks Steam directly -
SteamNetConnectionRealTimeStatus_t.m_eState, which reports a dead link before anything closes the socket - and falls back to a silence timer for crossplay peers, which report no state. The timer discounts main-thread stalls rather than counting a frozen frame as the peers going quiet. - If every peer goes quiet at once, that is treated as a fault at the host's end and nobody is evicted until one answers.
- This is what makes raising
Connection Timeout Secondssafe: the wait now costs only the slot.
- Clients are no longer left playing a world the server has dropped them from. New
Client configsetting EnableGhostWatchdog (default on).- A warning with a countdown appears halfway to the timeout actually in force and clears itself if the connection comes back; at the deadline, or as soon as the transport calls the link dead, the character is saved and the game returns to the menu with an explanation rather than the generic "disconnected".
- No timeout of its own - it follows the same deadline the game is using, so it cannot disagree with the server's setting.
- Stands down automatically when ClientGhostWatchdog is installed.
nps_statsgains a "Peer liveness" block: who is quiet, for how long, what the transport says, and the eviction and watchdog counters.- Credit: the ghost handling started from ClientGhostWatchdog by DreamWraith. No code is shared; the observation that the game needs a second opinion on whether a peer is still there is theirs.
- Picking berries, mining ore and chopping trees no longer lag when another player owns the object. Ownership arbitration is now tiered: moving objects are placed by latency as before, and interactable-but-stationary ones by distance. New
Ownershipsetting Interactive Object Ownership (default on).- Pickables, ore deposits, rocks, trees, logs and destructibles go to whoever is standing nearest them. These ask their owner to do the work and every handler checks it is the owner, so an object owned by another player costs four network legs per keypress - and placing by ping rather than by distance would not have helped, because nothing about a berry bush changes between interactions.
- Building pieces, containers, crafting stations and portals are still never moved off a player who is present, which is what keeps the fermenter and smelter fix above intact.
- An object is never taken from an owner still within reach of it, never taken for a player further away than
Interactive Claim Radius, and each move is pushed to nearby players immediately. - An unowned patch - one nobody has visited - now goes to the nearest player rather than the lowest-ping one, on the first pass and with no delay.
- Tuning:
Interactive Claim Radius,Interactive Challenge Margin,Interactive Min Hold Seconds,Interactive Max Reassigns Per Pass. The tier has its own budget so a zone full of creatures cannot starve it, or be starved by it. nps_statsgains per-tier ownership counters.
- Ships are now simulated by the player at the helm, so steering is no longer choppy when someone else on board owned the ship. New
Ownershipsetting Ship Ownership Follows Helmsman (default on).- The ship's current owner hands it over when the helm is taken, the same way the game already hands over saddles and carts. This needs the mod on whichever machine owns the ship; a ship owned by a player without it behaves as in vanilla.
- The host gives an abandoned ship (its owner left or disconnected) to the player at its helm first.
nps_statsgains a "Ship helm" block with the handoff and helm rescue counts.
1.5.0
- Updates default send timing to prevent alternating delays from the dedicated server
- New
Allocationsection: four opt-in changes that remove short-lived objects from the ZDO network path, reducing how often the garbage collector runs. None of them alters a byte on the wire or a value in a ZDO.- ZDO Deserialize Fast Path (default on) - reads a received ZDO's fields directly instead of through the fourteen delegates the game allocates for every one.
- Packet Read Fast Path (default on) - reads each incoming ZDO payload straight into the buffer that is about to hold it.
- Send Package Reuse (default on) - reuses the two packet buffers the send path builds, instead of constructing and discarding both on every send to every peer.
- RPC Invoke Fast Path (default on) - calls an incoming RPC's handler directly when its signature is the common one, instead of going through reflection for every message.
- Relay Send Reuse (default on): the host writes each relayed RPC once and hands the same bytes to every player it goes to, instead of rebuilding and re-copying the whole message per player.
nps_statsgains an "Allocation relief" block with a counter per mechanism and the game's own per-second ZDO send/receive rates to read them against.
- New
Routed RPCsetting Limit Relay By Distance (default on): stops relaying object RPCs such as building damage, fragments and ward flashes to players who visited that object earlier but are now too far away to have it loaded.
1.4.2
- Fixes Jotunn-based mods (Jotunn's own config sync included) disconnecting a peer with a 30 second "sending timeout" on higher-latency links (#3)
- New
Compatibilitysection for mods with that threshold compiled in (ServerSync and mods bundling it, ConditionalConfigSync): a peer in sustained backlog has its queue briefly brought under the threshold everyQueue Drain Interval Secondsso they can get their packet out.nps_statsgains a "Third-party send queue thresholds" block showing Jotunn's limit as read back from Jotunn and the drain counters per peer.
1.4.1
- Fixes the player limit not applying to crossplay on dedicated servers.
- The Steam server browser now shows the configured limit for dedicated servers.
1.4.0
- Fixes items vanishing when inserted into a fermenter, smelter, cooking station, fireplace or similar in multiplayer. This is a vanilla bug made worse with more players.
- Station item requests are now delivered to the object's current owner. This is best paired with the Valheim Community Patch, which addresses the other half of this.
nps_statsownership block gains astatic heldline: objects left with a present but not lowest-latency owner because they do not move.- Valheim Plus compatibility: when V+ is installed its player limit is the one in force and this mod's
Player Limitsettings stand down instead of fighting over the same patch sites.
1.3.0
- Removes admin requirement from server commands
- nps_stats_collect requires devcommands
- Adds support for Playfab servers to increase connection limits beyond vanilla 10
1.2.1
- Bumps the maximum connection timeout limit to 600s
1.2.0
Configurable connection timeouts. Vanilla drops a quiet connection after 30 seconds, which is not
enough for a slow or distant link mid-join, and it enforces that at two layers independently - so
raising only one of them changes nothing. The new Connection Timeout section writes both, plus
the handshake timeout Steam applies before a connection exists and the longer allowance the game
already gives itself during a crossplay world transfer. Everything ships at its vanilla value, so
enabling the section on its own changes nothing; nps_stats shows what is actually in force.
1.1.0
Initial release!