You are viewing a potentially older version of this package. View all versions.
sighsorry-UsefulRunestones-1.0.2 icon

UsefulRunestones

Exploration rewards for RuneStones and Vegvisirs: reveal weighted global map pins from pinless RuneStones, grant biome-based Vegvisir buffs with cooldowns.

Date uploaded 3 weeks ago
Version 1.0.2
Download link sighsorry-UsefulRunestones-1.0.2.zip
Downloads 75
Dependency string sighsorry-UsefulRunestones-1.0.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

README

UsefulRunestones

UsefulRunestones turns Valheim's RuneStones and Vegvisirs into configurable exploration rewards.


Runestones have a chance to pin configured locations just like vegvisirs!


Vegvisirs can give players shorttime buff according to biome.
So vegvisir is still a little useful even though you already know boss locations.

Highlights

  • Let pinless RuneStones reveal configured world locations as saved map pins.
  • Give custom pin names and pin icons per target location.
  • Use weighted chances so a RuneStone can reveal one target or reveal nothing.
  • Resolve global pins on the dedicated server, then send only the result to the interacting client.
  • Restrict or expand valid RuneStone source biomes per target.
  • Grant weighted Vegvisir status-effect rewards by biome.
  • Combine biome-specific reward tables with an All table.
  • Keep one selected reward and per-player cooldown state per loaded Vegvisir.
  • Play optional shared vfx_, sfx_, or fx_ prefabs when a reward is granted.
  • Sync YAML to clients with ServerSync and reload while the game is running.
  • Support custom biome names through Expand World Data when it is installed.

Why Use UsefulRunestones

UsefulRunestones focuses on small world-interaction rewards that make exploration more useful:

  • Existing RuneStones can point players toward configured landmarks without editing location prefabs.
  • Server owners can tune target weights and the chance of revealing no pin.
  • Vegvisirs can become biome-flavored reward points instead of one-time boss pointers only.
  • Cooldowns are tracked per loaded Vegvisir and per player, so shared servers can reward exploration without giving unlimited buffs.
  • The YAML stays compact enough to maintain by hand.

Generated Files

The mod creates:

BepInEx/config/UsefulRunestones.yml
BepInEx/config/sighsorry.UsefulRunestones.cfg

Server admins should edit the YAML on the server or host. The full YAML text is synced to clients automatically.

RuneStone Global Pins

runestoneGlobalPins rows use this shorthand:

runestoneGlobalPins:
  - Vendor_BlackForest, 0.5, Haldor, Icon3
  - SunkenCrypt4, 0.25, Sunken Crypt, Icon3, [Swamp]

Fields:

locationName, chance, pinName, pinType, sourceBiomes

Field behavior:

  • locationName: target ZoneSystem location prefab/name.
  • chance: final weighted chance for this target. Omitted value defaults to 1.
  • pinName: saved map pin name. Omitted value uses the target location discover label, then child teleport enter text, then locationName.
  • pinType: Valheim Minimap.PinType. Omitted value defaults to Icon3.
  • sourceBiomes: extra RuneStone source biomes that can reveal this target.

If filtered target chances add up to 1 or less, the remaining chance means no pin. If the total is over 1, UsefulRunestones normalizes the target weights so exactly one target can be selected.

When sourceBiomes is omitted or empty, a RuneStone can reveal the target only from the target location's own biome. Add source biomes when you want a RuneStone in one biome to reveal a target in another biome.

Selection lifetime

  • Single-player and the host's own interactions keep one result per loaded RuneStone object. Recreating that object (for example, after zone unloading) allows a new roll. Changing the pin definition also allows a new roll.
  • Remote clients ask the server. The server derives a repeatable roll from the RuneStone's 16m XZ cell, the pin definition, and a secret that lasts while the plugin remains loaded. Height is not part of the cell. This is not a world-seed-based or saved-world result.
  • Nearby RuneStones in one cell share a roll percentile, not necessarily the same target: the server resolves eligible candidates and the nearest location for each request. Changes to available locations can therefore affect the result.
  • Pin definition order, names, icons, chances, and source biomes participate in the selection key. Editing display fields can change the roll too. Restarting the game/server creates a new secret; changing worlds without unloading the plugin does not.

Consequently, unloading a zone does not reroll a remote client's percentile while the server plugin remains loaded, but this does not promise a permanent pin or no-pin result at that world position. The local and remote policies are intentionally unchanged.

Vegvisir Global Effects

vegvisirGlobalEffects rows are grouped by biome:

vegvisirGlobalEffects:
  - All:
    - Rested, 240, 480, 1, vfx_HealthUpgrade
  - BlackForest:
    - GP_Eikthyr, 120, 600, 0.5

Reward fields:

StatusEffect, durationSeconds, cooldownSeconds, weight, effectPrefab

Field behavior:

  • StatusEffect: status effect prefab name.
  • durationSeconds: optional override. Omitted value uses the prefab duration.
  • cooldownSeconds: optional cooldown. Omitted value uses the prefab cooldown.
  • weight: optional selection weight. Omitted value defaults to 1.
  • effectPrefab: optional shared visual/audio effect. Must start with vfx_, sfx_, or fx_.

Cooldown values:

  • 0: no cooldown
  • below 0: once per loaded Vegvisir per player
  • above 0: per-player cooldown in seconds

VRS_ClearStatus is a built-in miss reward that clears current status effects and shows the configured clear-status message.

Rewards and per-player cooldowns belong to each loaded Vegvisir object on the local player's client. Recreating the object allows a new reward selection and fresh cooldowns; rewards are not saved by world position. Changing the ordered candidate keys, weights, effective cooldowns, duration overrides, or FX also resets selection and cooldowns on the next interaction. Localization-only changes do not reset them.

Localization

Optional localization fields:

localization:
  messageVegvisirEffectReceived: "You have received {name}"
  messageVegvisirClearStatus: "You got bamboozled"
  messageVegvisirBuffCooldown: "Buff Cooldown {seconds}s"
  messageVegvisirAlreadyActive: "Already active {name}"

Supported placeholders:

  • {name} for status-effect names.
  • {seconds} for cooldown seconds.

Compatibility

UsefulRunestones is designed to sit beside the other standalone mods:

  • Use DropNSpawn for creature drops, object loot, spawners, and world spawn tables.
  • Use BossRules for boss altars, boss stones, Forsaken Powers, boss despawn, and boss tame pressure.
  • Use UsefulRunestones for pinless RuneStone global pins and Vegvisir rewards.

If another mod owns the same RuneStone or Vegvisir interaction, disable the overlapping UsefulRunestones feature in the BepInEx config.

Developer Validation

With the local paths in environment.props configured, build and copy the final merged plugin DLL into the game, then run the managed smoke checks in a fresh PowerShell 7 process:

dotnet build UsefulRunestones.sln -c Debug -p:DeployToGame=true
pwsh -NoProfile -File Tests/SmokeTests.ps1 -Configuration Debug

Use -p:DeployToGame=false to skip the game DLL copy. The Debug build does not create a Thunderstore package. The smoke checks load the built mod, its publicized Valheim build references, and native Unity assemblies; the script itself does not launch Valheim, deploy the mod, or create a package. Passing does not verify Harmony patch activation or private-member access in the game's Mono runtime. A normal Release build creates a distribution package and requires an explicit release request.

Before release, also test single-player, a listen host plus a remote client, and a dedicated server: pin/no-pin interactions, repeated requests, reconnection, zone unload/reload, YAML reload, Vegvisir cooldowns and conflicting status effects, and Expand World Data both installed and absent. World-edit mods that reset locations require their own compatibility check.

The pin RPC names and v1 payload remain unchanged. This mod's global pin RPCs check the actual connection against the claimed sender before dispatch/relay. Invalid or throttled requests receive no response; an accepted roll with no pin still sends the normal no-pin response. Install the updated mod on the server as well as clients: a client cannot independently authenticate the original sender of traffic relayed by an older server.

GitHub

https://github.com/sighsorry1029/UsefulRunestones

CHANGELOG

Version Update Notes
1.0.3 - Updated UsefulRunestones for Valheim 1.0.7 client and dedicated server assemblies.
- Rebuilt the embedded ServerSync adaptation for the new ZRoutedRpc.Everybody constant, fixing the startup MissingFieldException.
- Preserved native login packet ordering while ServerSync buffers PeerInfo, including player, history, admin, and network-time messages.
- Switched game build references to original, non-publicized assemblies and added cached Harmony accessors for required private members.
- Preserved RuneStone selection, pin RPC v1, Vegvisir reward/cooldown behavior, configuration keys, and optional Expand World Data integration.
- Updated the package dependency to BepInExPack Valheim 5.4.2350 and expanded client/server regression checks.
1.0.2 - Fixed Vegvisir reward selection overflow with very large finite weights.
- Authenticated RuneStone pin RPC senders against their actual connections and rejected invalid relay targets.
- Stopped responding to rejected or rate-limited requests while preserving normal no-pin responses and the v1 payload format.
- Co-located feature helpers, removed redundant candidate allocations, and clarified cache ownership.
- Documented existing local/remote selection lifetimes without changing their policies; update both server and clients for the RPC protection.
- Added managed regression checks and explicit DeployToGame build support.
1.0.1 - Simplified configuration and runtime state management.
- Replaced duplicate reflection and serialization code with Valheim APIs.
- Hardened RuneStone server RPC validation and made server selections stable without a growing position cache.
- Preserved existing status effects when a Vegvisir reward cannot be granted.
- Rejected non-finite YAML numbers and improved reload safety.
- Updated README and Thunderstore metadata and artwork.
1.0.0 - Initial Release