sighsorry-Blasted_Swimming_Tarred_Bug_Fix icon

Blasted Swimming Tarred Bug Fix

Fix for the long-running Valheim bug where players, carts, or other floating objects can stay stuck in water/swimming/tarred state after leaving a liquid trigger, teleporting, changing scene, or moving below the old liquid surface height.

Last updated 5 hours ago
Total downloads 7
Total rating 0 
Categories Mods Tweaks Server-side Client-side AI Generated
Dependency string sighsorry-Blasted_Swimming_Tarred_Bug_Fix-1.0.1
Dependants 1 other package depends on this package

This mod requires the following mods to function

denikson-BepInExPack_Valheim-5.4.2333 icon
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.2333

README

BlastedSwimmingTarredBugFix

Fix for the long-running Valheim bug where players, carts, or other floating objects can stay stuck in water/swimming/tarred state after leaving a liquid trigger, teleporting, changing scene, or moving below the old liquid surface height.

What It Fixes

This mod targets cases such as:

  • Randomly starting to swim while nowhere near water.
  • Randomly becoming tarred in the Plains while away from a tar pit.
  • Leaving a dungeon and getting launched or forced into swimming because the game still thinks you are in water.
  • Portal routes or teleports near water/tar leaving stale liquid state behind.
  • Carts or floating objects keeping water/tar state after trigger exits are missed.

The bug can happen in vanilla, and some modded setups appear to make it easier to trigger.

How It Works

Valheim liquid volumes keep an internal list of objects currently considered inside water or tar. If OnTriggerExit is missed, or the liquid counter becomes unbalanced, an old WaterVolume or LiquidSurface can keep calling SetLiquidLevel(...) on an object that has already left.

That stale liquid level can then make the player swim or become tarred again when they move to a lower height.

This mod adds several guards:

  • Rejects positive liquid level updates while a player is teleporting.
  • Rejects liquid level updates from a source that no longer overlaps the target.
  • Purges stale entries from WaterVolume and LiquidSurface before vanilla floater updates run.
  • Clamps water/tar counters so missed exits cannot drive them below zero.
  • Clears stale player/floating-object liquid state when no real nearby liquid trigger exists.
  • Clears player water/tar state at the start of teleport; destination liquid triggers can restore it immediately if the destination is actually in liquid.

Testing The Fix

Good reproduction targets:

  • Touch a Plains tar pit, leave it, then move downhill.
  • Use portals where water or tar lies between/near portal endpoints.
  • Enter and exit Mistlands dungeons after touching water.
  • Put a cart or floating item in water/tar, then interact with inventory or other update-heavy actions.

For testing, enable:

DebugLogging = true

Useful log lines include:

Rejected SetLiquidLevel
Purged stale Water entry
Purged stale Tar entry
Emergency-cleared player liquid state

Turn debug logging off after testing, because liquid-related events can be frequent.

Notes

This mod does not add new world objects, items, prefabs, RPC gameplay features, or save data. It only patches runtime liquid state handling.

If you are testing whether the fix is responsible for preventing the bug, you can turn off most protection without removing the DLL:

ValidateSetLiquidLevelSource = false
PurgeStaleSourceLists = false
EmergencyClearPlayers = false
EmergencyClearFloatingObjects = false
ClampLiquidCounters = false
ResetOnTeleportStart = false

The Harmony patches remain loaded, but with those settings disabled the mod mostly passes vanilla behavior through.

Configuration

[Debug]

## Log rejected liquid updates and purged stale entries. Keep disabled during normal play. [Not Synced with Server]
# Setting type: Boolean
# Default value: false
DebugLogging = false

## Seconds between repeated rejected SetLiquidLevel logs for the same target/source/liquid/reason while DebugLogging is enabled. [Not Synced with Server]
# Setting type: Single
# Default value: 1
RejectedSetLiquidLevelLogInterval = 1

[General]

## If true, synced configuration is locked and can only be changed by the server.
# Setting type: Boolean
# Default value: true
LockConfiguration = true

## Reject positive water/tar level updates from a liquid source whose trigger bounds no longer touch the target. [Synced with Server]
# Setting type: Boolean
# Default value: true
ValidateSetLiquidLevelSource = true

## Before WaterVolume/LiquidSurface updates floaters, remove stale IWaterInteractable entries that are no longer inside that source. [Synced with Server]
# Setting type: Boolean
# Default value: true
PurgeStaleSourceLists = true

## If a player still has water/tar level but no nearby current liquid trigger, clear the stuck state. [Synced with Server]
# Setting type: Boolean
# Default value: true
EmergencyClearPlayers = true

## Apply the same emergency clear to Floating objects such as carts/items. [Synced with Server]
# Setting type: Boolean
# Default value: true
EmergencyClearFloatingObjects = true

## Clamp Character/Floating liquid reference counters so missed trigger exits cannot leave negative or stale counts. [Synced with Server]
# Setting type: Boolean
# Default value: true
ClampLiquidCounters = true

## Clear player water/tar state when Player.TeleportTo starts. Current liquid triggers will restore it if the destination is actually in liquid. [Synced with Server]
# Setting type: Boolean
# Default value: true
ResetOnTeleportStart = true

[Tuning]

## Meters added to source and target bounds during source validation. Raise slightly if legitimate shallow water is rejected. [Synced with Server]
# Setting type: Single
# Default value: 0.75
SourceBoundsPadding = 0.75

## Extra meters used when scanning around the target collider for any current liquid trigger. [Synced with Server]
# Setting type: Single
# Default value: 0.35
EmergencyProbePadding = 0.35