You are viewing a potentially older version of this package. View all versions.
Ainzworth-BetterMapCleanup-0.5.2 icon

BetterMapCleanup

Companion cleanup and lifecycle mod for xtavim's BetterMap, with server-authoritative resource and configuration sync.

Date uploaded 6 days ago
Version 0.5.2
Download link Ainzworth-BetterMapCleanup-0.5.2.zip
Downloads 74
Dependency string Ainzworth-BetterMapCleanup-0.5.2

This mod requires the following mods to function

denikson-BepInExPack_Valheim-5.4.2350 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.2350
xtavim-BetterMap-1.1.0 icon
xtavim-BetterMap

Puts creatures, boats, carts and resources on your map. Pins what you find as you find it, keeps and clears your death markers, and names the traders. Everything can be turned on and off, biome by biome, and syncs with ServerSync.

Preferred version: 1.1.0

README

BetterMapCleanup 0.5.2

Companion cleanup/lifecycle mod for BetterMap 1.0.x.

0.5.0 changes the multiplayer architecture substantially: normal gameplay no longer runs BetterMapCleanup's own periodic resource-world reconciliation. Resource discovery piggybacks BetterMap's existing AutoPins sweep, while multiplayer depletion/respawn state is authoritative on a BetterMapCleanup-enabled server and distributed as compact event deltas.

Core features

  • Remove saved BetterMap auto-pins whose effective rule is disabled.
  • Re-apply BetterMap Merge Distance to existing saved pins.
  • Same-resource merge labels such as Obsidian x4 and lifecycle count reduction.
  • Configurable resource depletion threshold (default 90%).
  • Per-resource CrossOff / Remove actions.
  • Dedicated-server resource-state synchronization and persistence.
  • Portal pin removal when a portal is dismantled/destroyed.
  • Conservative orphan portal cleanup in confirmed-loaded areas.
  • Conservative BetterMap PinRecord repair.
  • Mistlands Soft Tissue BetterMap rule without BetterMapFix.
  • Console maintenance/status commands.

0.5.2: server-authoritative configuration

BetterMapCleanup can now mirror BetterMap's server-config behavior without requiring BetterMap on the server. Put the same BetterMapCleanup DLL on the server and clients. The server can then make the synchronized BetterMapCleanup gameplay settings authoritative for every connected BetterMapCleanup client.

Server controls:

[1 - ServerSync]
Enable Server Config Sync = true
Lock Configuration = true

When enabled, a joining client receives the server's active BetterMapCleanup settings. The override is in-memory for the current connection: the client's local .cfg file is not rewritten, and its previous local values are restored after disconnect. With Lock Configuration = true, attempts to change synchronized settings client-side are immediately restored to the server value. Server-side changes are broadcast to already connected BetterMapCleanup clients.

Synchronized settings are the gameplay/cleanup policy: cleanup behavior, merge labels, portal cleanup, PinRecord repair, resource depletion tracking, resource sync enablement, respawn restoration, depletion threshold/action, every per-resource action, Soft Tissue, and Giant Remains. Local diagnostics/maintenance settings (Debug, Cleanup Now, manual reconcile compatibility settings, registry persistence and scan interval) stay client-local.

The config-sync channel is independent of Resource State Sync. A server can therefore still push BetterMapCleanup policy even if Resources > Server Resource Sync is disabled.

0.5.0: event-driven resource architecture

Why this changed

Previous 0.4.x builds attempted to reconcile loaded resources periodically. Even after replacing global Unity searches with a cache, that still meant BetterMapCleanup repeatedly walking resource/member/map state during gameplay.

BetterMap itself does not solve auto-pin discovery that way. Its AutoPins system sweeps the objects Valheim already has loaded and uses its PinRecord history to decide whether to place a pin. BetterMapCleanup now observes that existing discovery path instead of launching another automatic client scan.

Client discovery

On a normal client with BetterMap:

BetterMap AutoPins sweep
    -> BetterMap considers an Ore rule/resource candidate
    -> BetterMapCleanup observes rule + prefab + position
    -> member registry is updated
    -> BetterMap continues its normal pin/PinRecord logic

When a BetterMap sweep learns new same-resource members, BetterMapCleanup can refresh <Resource> xN after that same sweep. There is no scheduled BetterMapCleanup world-object scan.

Server-authoritative multiplayer state

Install the same BetterMapCleanup DLL on the dedicated/listen server. BetterMap itself is not required on the server.

The server patches Valheim's actual Destructible, MineRock5 and MineRock mutation paths. Once a tracked resource crosses the configured depletion threshold, the server stores one state transition and sends a compact delta to connected BetterMapCleanup clients:

canonical prefab + position + depleted true/false

The mining player's client is not trusted as the authoritative source. This means the player causing the depletion does not need BetterMapCleanup for the server to observe the world-state change; BetterMapCleanup only needs to be installed on the server and on clients that want their BetterMap pins synchronized.

A remote client with confirmed server support stops doing its old local damage/ZDO recheck coroutines and applies server deltas instead.

Offline/reconnecting players

The server persists resource transitions per world. On join, a BetterMapCleanup client requests a snapshot. Snapshot application is sliced to a small number of records per frame, and the local registry is written once after the queue drains rather than once per record, reducing reconnect hitch risk.

No BetterMapCleanup on the server

The mod remains usable:

  • Singleplayer: local lifecycle hooks handle the local player's actions.
  • Multiplayer client on an unmodded server: local lifecycle fallback still handles events the client can actually observe.
  • Changes made by distant players while the client is absent cannot be guaranteed without server authority.
  • bmc reconcile remains available as an explicit manual repair tool; it never runs automatically in 0.5.0.

OdinEye design lesson

The 0.5.0 split follows the useful architectural principle demonstrated by OdinEye/OdinEyeClient: keep data the server can authoritatively know on the server, and use the client only for client-specific information/UI. BetterMapCleanup does not copy OdinEye's HTTP/WebSocket transport; Valheim's in-game ZRoutedRpc is a better fit for small peer state deltas.

Resource lifecycle

Default threshold:

[Resources]
Track Depletion = true
Depleted At Percent = 90
Depleted Pin Action = CrossOff
Server Resource Sync = true
Persist Resource Registry = true
Restore Respawned Resources = true

Legacy config entries Reconcile Loaded Resources and Reconcile Interval are retained for compatibility/manual repair, but no automatic periodic reconciliation uses them in 0.5.0.

Built-in actions:

[Resources - Actions]
Copper Deposits = CrossOff
Tin Deposits = Remove
Muddy Scrap Piles = Remove
Silver Deposits = CrossOff
Obsidian Deposits = Remove
Giant Remains = CrossOff
Soft Tissue = Remove
Flametal = CrossOff
Unstable Lava Rock = Remove
Leviathans = CrossOff

CrossOff sets the normal Valheim checked state. Remove removes the visible pin while preserving/recreating BetterMap PinRecord suppression so a still-present final <=10% does not immediately recreate the pin.

Large resources that transition from a Destructible wrapper to a fractured MineRock5 continuation are normalized back to the original BetterMap resource. Wrapper destruction itself is not treated as depletion.

Respawn recovery

No guessed background timer is used.

  • Server: if a previously depleted tracked resource actually instantiates again and its authoritative health shows it active, the server stores depleted=false and broadcasts it.
  • Client: BetterMap's own AutoPins candidate observation can also prove that a known depleted member is alive again and release local suppression before BetterMap completes its normal Place operation.

Vanilla finite ores generally do not respawn; the mechanism mainly supports resources/mods that genuinely recreate the tracked object.

Merge labels

With Cleanup > Show Merge Counts = true, same-resource members inside Merge Distance can be represented as:

Obsidian x4

When one represented node depletes:

Obsidian x4 -> Obsidian x3

Different Ore rules are never combined just because both use the Ore category.

Server installation

See SERVER.md.

Client build/install:

.\build.ps1 -Install

The same built BetterMapCleanup.dll can be copied to the server's BepInEx/plugins/BetterMapCleanup/ folder.

Console commands

bmc status
bmc cleanup
bmc reconcile
bmc repair
bmc sync
bmc registry [N]
bmc help
  • bmc status: runtime/server-sync/registry diagnostics.
  • bmc cleanup: disabled pins + merge normalization + orphan portals + PinRecord maintenance.
  • bmc reconcile: manual-only legacy resource repair pass against the small loaded-resource cache.
  • bmc repair: PinRecord repair.
  • bmc sync: request a fresh server snapshot.
  • bmc registry [N]: inspect local tracked members.

A connected multiplayer client should report roughly:

serverSync=connected, protocol=3
configSync=connected/locked/0.5.2, configProtocol=1
clientReports=disabled
localLifecycle=server-deltas
automaticReconcile=disabled(event-driven)
BetterMapObservation=hooked

Explicit non-goals

  • No special lifecycle implementation for Sulfur Arches or Frozen Trolls.
  • No continuous full-world or loaded-world scan on clients.
  • No HTTP/WebSocket service; synchronization stays inside Valheim networking.

Current testing status (0.5.2)

The current feature scope is implemented and ready for broader gameplay testing. The following areas still need more long-running real-world validation:

  • merged resource labels/counts, especially Tin;
  • full Remove / CrossOff lifecycle behavior across resource types;
  • PinRecord repair with deliberately missing or duplicate records;
  • full depletion -> respawn -> restored-pin lifecycle;
  • long-running dedicated-server behavior with multiple clients;
  • reconnect, world-reload and synchronization timing edge cases.

Please report duplicate pins, pins that fail to disappear or return, incorrect merge counts, sync issues, or relevant BepInEx log errors.

CHANGELOG

0.7.3

  • Remove the obsolete Soft Tissue rule injection and the Giant Remains enable-setting override. BetterMap owns both discovery rules and their configuration.
  • Remove the companion Pins/Soft Tissue and Pins/Keep Giant Remains settings from config binding and server sync. Old config entries are ignored.
  • Keep normal resource depletion cleanup and synchronization for native BetterMap Soft Tissue pins.

0.7.2

  • Match historical prefab-derived and PlantEverything pin labels to exact rules, including Pickable Smoke Puff.
  • Resolve unambiguous named rules before shifted numeric categories during disabled-pin cleanup.
  • Preserve manually placed BetterMap pins marked by BetterMapSeneaLCompat 0.3.0.
  • Cache expected rule labels per settings snapshot.

0.7.1

  • Publish the completed offline recovery changes under a new release version because 0.7.0 is already registered.
  • Includes persisted portal catch-up, replacement protection and retry handling for sync requests and native replay.
  • Protocol 5; update server and participating clients to this build.

0.7.0

  • Retry unanswered sync requests and temporarily failed native portal replay.

  • Persist accepted portal removals per world and replay them on reconnect or bmc sync, including server restarts.

  • Reuse BetterMap native deletion and protect replacements using the server portal registry.

  • Apply catch-up in batches and wait for map readiness. Resource reconnect snapshots remain in use.

  • Protocol 5 requires matching server/client versions. History begins with this update.

0.6.0

  • Enable client resource reports and server relay (protocol 4), including host map updates and echo suppression.
  • Remove our WearNTear portal deletion and orphan-portal cleanup.
  • Relay BetterMap 1.1.0 native portal deletion to connected Cleanup users; replay through BetterMap, with no independent remover.
  • Resource snapshots remain persisted. Portal events are live-only, not replayed to offline users.
  • See TESTING.md for validation and limitations.

0.5.3 - Smoke Puff lifecycle

  • Track Pickable_SmokePuff via the actual Pickable.SetPicked state and initial Awake state.
  • Include its Forage rule in lifecycle matching, BetterMap observation and merged-label maintenance.
  • Route harvest/respawn through the existing resource-state and pin-action pipeline. Multiplayer clients with an active BMC server wait for its deltas; hosts/singleplayer and local fallback use the same state application.
  • Uses Resources / Depleted Pin Action (CrossOff by default). No periodic world scan added.
  • Update both server and clients. Run bmc reconcile locally for already harvested objects currently loaded, or reload their area after updating the server. Previously unloaded areas are learned when loaded.

Validation: warning-free net48 build against workspace copies of game/BepInEx assemblies. 13 production-hook checks passed with stand-in game/network/map APIs. Real game harvest, merged-pin counts, respawn and multiplayer delivery still require an in-game test.

Changelog

0.5.2

Testing status

  • Feature-complete for the current scope and released for broader gameplay testing.

  • Still needs wider validation of merge labels/counts (especially Tin), full Remove/CrossOff lifecycle behavior, deliberate PinRecord repair cases, depletion/respawn restoration, multi-client dedicated-server longevity, and reconnect/world-reload sync timing.

  • Added server-authoritative BetterMapCleanup config synchronization, modeled after BetterMap's ServerSync behavior.

  • Added [1 - ServerSync] Enable Server Config Sync (default true) and Lock Configuration (default true).

  • Joining BetterMapCleanup clients receive the server's synchronized cleanup/resource policy through a compact dedicated RPC snapshot.

  • Server values are applied in memory only; client config files are not rewritten and the previous local values are restored after disconnect.

  • With config locking enabled, client edits to synchronized settings are immediately reverted to the server value.

  • Runtime server-side setting changes are broadcast to connected BetterMapCleanup clients.

  • Config synchronization is independent from resource-state synchronization, so policy can still be server-controlled when resource-state sync is disabled.

  • bmc status now reports config-sync state, protocol, peer count and lock state.

  • Local-only diagnostics/maintenance settings remain unsynchronized.

0.5.1

  • Fixed build failure in BetterMapCleanupEventSync.cs by importing the BepInEx namespace required for PluginInfo.
  • Removed the obsolete _nextResourceReconcileAt field left behind after the 0.5.0 event-driven rewrite, eliminating the compiler warning.
  • No runtime behavior changes from 0.5.0.

0.5.0

Event-driven/server-authoritative resource architecture

  • Removed automatic periodic resource reconciliation from normal gameplay.
  • BetterMapCleanup now observes BetterMap's own AutoPins.Place candidates and AutoPins.Sweep completion rather than launching a second client world scan.
  • Added server-authoritative resource mutation hooks for tracked Destructible, MineRock5 and MineRock resources.
  • Resource Sync protocol bumped to 3.
  • Clients no longer submit authoritative depletion reports; the server derives state from the world itself.
  • Remote clients with confirmed server support stop their old local damage/ZDO recheck coroutines and consume compact server deltas instead.
  • Same DLL continues to support BetterMap-free dedicated servers (BetterMap remains a soft dependency).
  • Persisted server state canonicalizes legacy fracture/source prefab names on load.
  • Respawn is event-driven: a previously depleted server record is revived only when the tracked object is actually observed active again.
  • Join snapshots are applied in bounded batches (8 records/frame).
  • Registry file writes are deferred while a snapshot is being applied and performed once when the queue drains, avoiding per-record file-I/O stutter.
  • Server snapshot records for disabled/unavailable BetterMap rules are discarded from the per-frame pending queue instead of being retried forever; bmc sync can request them again after a config change.
  • bmc reconcile remains as an explicit manual repair command only.
  • bmc status now reports automaticReconcile=disabled(event-driven), BetterMap observation state, protocol 3, clientReports=disabled, and whether local lifecycle is using server-deltas or local-fallback.

Architecture note

  • Reviewed OdinEye/OdinEyeClient's public server/client split as a design reference: server-authoritative information remains server-side, while client-only data/UI stays client-side. BetterMapCleanup keeps Valheim-native ZRoutedRpc rather than adopting OdinEye's REST/WebSocket transport.

0.4.8

  • Added runtime-mode detection and suspended periodic reconciliation in true singleplayer / solo-host cases.

0.4.7

  • Fixed 0.4.6 scope errors in the reconciliation label-update optimization.

0.4.6

  • Replaced periodic global Unity FindObjectsByType scans with an event-driven loaded-resource cache.

0.4.5

  • Added respawn recovery, console commands/status diagnostics and resource sync protocol 2.

0.4.4

  • Added assembly_utils.dll reference and Valheim 1.0.15 server-peer API compatibility.

0.4.3

  • Added resource member registry, loaded-zone reconciliation and optional server resource sync.

0.4.2

  • Added conservative PinRecord repair/resync.

0.4.1

  • Added conservative orphan portal cleanup.

0.4.0

  • Added same-resource merge labels/counting and lifecycle count decrement support.