UsefulRunestones
Exploration rewards for RuneStones and Vegvisirs: reveal weighted global map pins from pinless RuneStones, grant biome-based Vegvisir buffs with cooldowns.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
Alltable. - Keep one selected reward and per-player cooldown state per loaded Vegvisir.
- Play optional shared
vfx_,sfx_, orfx_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: targetZoneSystemlocation prefab/name.chance: final weighted chance for this target. Omitted value defaults to1.pinName: saved map pin name. Omitted value uses the target location discover label, then child teleport enter text, thenlocationName.pinType: ValheimMinimap.PinType. Omitted value defaults toIcon3.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 to1.effectPrefab: optional shared visual/audio effect. Must start withvfx_,sfx_, orfx_.
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
The current compatibility target is Valheim 1.0.7 (Windows client build 25185596 / dedicated server build 25185644). Build references use the original game assemblies, not publicized copies. The embedded ServerSync adaptation and its provenance are documented in Libs/ServerSync.NOTICE.md.
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 Windows PowerShell 5.1 (.NET Framework) process:
dotnet build UsefulRunestones.sln -c Debug -p:DeployToGame=true
powershell.exe -NoProfile -ExecutionPolicy Bypass -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, original Valheim/Unity assemblies and installed Harmony; use -GameManagedPath <original Managed directory> to check a dedicated server snapshot in a separate process. PowerShell 7 is not supported by this harness with the installed Harmony runtime. 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.


