Valheim
Install with App

Details

Latest version
1.6.0
Last Updated
First Uploaded
Downloads
346
Likes
1
Size
65KB
Dependants
ADDatHost Valheim hosting
30% off

DeathRoulette

Every death remakes the evening. A player falls, and the whole server gets one random event — a gift, a curse, or a cruel cosmic joke.

Server-side only. Install it once on the dedicated server, and every vanilla client plays along. Nobody installs anything, nothing changes about saves, and unmodded players connect and leave without a trace.

Built and verified against game build l-1.0.12 (network 40, world 41), BepInEx 5.4.23.5.

Source: https://github.com/Geckuss/valheim-deathroulette

Why you'll like it

  • Zero client install. The server does everything. Your friends need nothing, and you never re-sync a modpack.
  • One death, one event. No death goes unremarked: the server names the fallen -- and the cause when it can see it -- counts down 3, 2, 1 in the raid-banner slot, and then the roulette fires. A global cooldown (default 30 s) stops a wipe from piling five events at once.
  • 63 events in four personalities. Quick buffs, real raids, wild travel, visible comedy — with a default weight that leans into fun.
  • Deadly but never cheap. Damage events cap at a fraction of current health, so the roulette can knock you down but never kill you itself. The fun kills you, not the mod.
  • Tune everything from a config file. Change any weight, disable any event, flip raid gating — no rebuild, and admin commands can reload it live.
  • Admins stay in control. Trigger any event on demand, see the odds, end raids, and audition effects — all from the in-game console.

Quick start

  1. On your dedicated server, make sure BepInEx 5 and Server Devcommands are installed (Devcommands is optional but recommended — it's how admins drive the mod).
  2. Drop DeathRoulette.dll into the server's BepInEx/plugins/ directory.
  3. Restart the server. That's it. Players need nothing.

On first run the mod writes BepInEx/config/geckuss.deathroulette.cfg — every event with its weight, ready to tune.

A restart kicks everyone online.

Docker (lloesche/valheim-server)

The image re-syncs plugins from its persistent /config/bepinex/plugins/ bind mount at startup, so install the DLL there (not just into the live container layer) or it silently reverts on the next restart:

docker cp DeathRoulette.dll valheim:/config/bepinex/plugins/Geckuss-DeathRoulette/DeathRoulette.dll
docker restart valheim

The event table

All 63 events and their default weights. Weight 0 disables; changing a weight needs no rebuild. The armour-set and standalone potion events ship disabled (weight 0) so they can be called directly (server dr fire <id>) without rolling on their own — armour fitting and witch's brews dish them out at random instead.

Kind — the gods give back. (29)

Event Id W What happens
Forsaken Gift forsaken_gift 7 A random forsaken power is granted to everyone.
Windfall windfall 7 Scatters a pile of materials on the ground at the corpse.
Second Wind second_wind 6 Every surviving player is healed to full.
Called to the Grave corpse_run 5 Fifteen seconds after dying -- once the fallen player has respawned -- they are pulled back to their grave.
Adrenaline adrenaline_rush 4 A surge for everyone: full heal, a stamina-regen buff, and Ashlands adrenaline.
Fenris Blessing fenris_blessing 0 The fenris set bonus, callable directly: faster on foot for five minutes.
Wolf Set wolf_set 0 The wolf set bonus, callable directly: frost resistance and truer blades for five minutes.
Root Set root_set 0 The root set bonus, callable directly: arrows and poison slide off for five minutes.
Troll Set troll_set 0 The troll set bonus, callable directly: sneaking sharpens for five minutes.
Lox Set lox_set 0 The lox set bonus, callable directly: a lox's hide for five minutes.
Harvester Set harvester_set 0 The harvester set bonus, callable directly: gathering comes swifter for five minutes.
Berserk berserk_fury 0 The berserker set bonus, callable directly: hits land harder for 45 seconds.
A Path Revealed revealed_path 4 Pins the nearest landmark on each player's map and turns them to face it.
Mercy of Dawn dawn_mercy 4 Time skips to the next morning.
Granted Rest rested 4 Rested buff for everyone.
The Gods Relent gods_relent 4 Ends the raid that is currently running.
Mercy of Dusk dusk_mercy 4 Time skips to the next nightfall.
Feather Fall feather_fall 4 Slow Fall on everyone for five minutes: no fall damage.
Lessons Held hold_lessons 3 No skill drain for ten minutes.
Berserk berserk_fury 3 Berserk on everyone for 45 seconds: hits land harder.
Witch's Brews witches_brews 3 A potion for everyone, picked from every potion in the mod — applied once (meads run their full duration), and each player gets one they were not just handed last time.
Giant's Strength giants_strength 3 Megingjord for everyone for five minutes: 150 carry weight.
Armour Fitting set_bonus 3 One of the seven armour-set bonuses at random, for everyone: fenris, berserk, wolf, root, troll, lox or harvester.
Lightfoot lightfoot 0 Lightfoot mead on everyone, given once for its full ten minutes: lighter steps, no fall damage. Callable directly; not rolled on its own.
Mistveil mistveil 3 Demister on everyone for five minutes: the mist parts.
Mage's Luck mage_luck 0 Minor eitr mead on everyone for three minutes: eitr regens. Callable directly; not rolled on its own.
Wolf Sight wolf_sight 2 Wolf Sight on everyone for five minutes: hits land harder.
Magic Barrier magic_barrier 2 The staff of protection's barrier wraps everyone.
Shaman's Ward shaman_shield 2 The fuling shaman's ward on everyone.
Kindred Spirits animal_friends 2 A handful of wild animals (boars, wolves, lox, hens) near every player are tamed on the spot.

Harmless — theatre, mood, spectacle. (7)

Event Id W What happens
Odin's Indifference taunt 9 Odin passes comment. Nothing else happens.
Lament gjall_lament 7 A gjall's taunt echoes over every player. Unsettling, harmless.
Ancient Omen bossstone_omen 7 A boss-stone activation effect fires at everyone's feet. Pure theatre.
Phantom Numbers phantom_numbers 6 Floating text appears over every player. Purely cosmetic.
Buried Luck buried_luck 3 Wishbone on everyone until toggled off or death: buried riches sing. The buff has no duration, so it stays until death.
Angler's Luck fishing_knot 2 Fishing hat set bonus on everyone until toggled off or death: pure luck and triumph. The buff has no duration, so it stays until death.
Dvergr Favour dvergr_ally 2 Dvergr power on everyone for 90 seconds: a strange, brief glow.

Mean — keep your guard up. (18)

Event Id W What happens
Thunderclap thunderclap 7 Lightning strikes every player, for a little damage.
Lurch stagger_all 5 Everyone is staggered, losing control briefly.
Blood Tax blood_tax 5 Survivors lose up to a quarter of current health. Never lethal.
Pyre pyre 4 Burning and fire damage on everyone for 10 seconds, with flames underfoot.
Deep Chill deep_chill 4 Cold and Freezing on everyone for 10 seconds, with a steady frost bite.
Tar-Soaked tar_soaked 4 Tared on everyone for 10 seconds: slow and clumsy.
Loud Grief loud_grief 4 Everyone is loud for a minute: real noise creatures can hear through walls, waking and aggroing everything within 40 m, and a couple of creatures surface beside each player.
Plague plague 4 Poison and poison damage on everyone for 20 seconds.
Troll Love troll_love 0 Troll pheromones on everyone for two minutes: trolls warm to people. Callable directly; not rolled on its own.
Fog of War fog_of_war 3 The map is hidden from everyone for five minutes.
Seasick seasick 3 Puke on everyone, once: food breaks free.
Rooted rooted 3 Immobilized on everyone, once: rooted in place.
Maddened Beasts maddened 3 Neutral and tamed creatures near every player turn hostile for a minute — then calm down again.
Cold Rain soaked 3 A cold downpour: Wet and Cold on everyone, with a splash underfoot.
Slimed slimed 3 Slimed on everyone for 20 seconds: slow and clumsy.

Brutal — the gods have a plan for you. (9)

Event Id W What happens
Raid raid 10 A real raid: music, banner, spawners. Progression-gated by default.
Swarm swarm 8 Spawns a handful of small creatures on the corpse.
Grave Guardian grave_guardian 7 One creature is spawned on the corpse to guard it.
Scattered scatter 7 Every survivor is thrown a short random distance.
Riktig Fuling riktig_fuling 6 A band of goblin_gem — real, undressed Fulings — spawns on the corpse.
No Escape no_escape 5 Portals refuse to work for five minutes.
Summoned Mourners summon_mourners 5 Every survivor is teleported to the corpse, wherever it is.
Swapped swap_places 3 Two random players trade positions. Needs two online.
Pilgrimage pilgrimage 1 Sends everyone to the altar of the last boss the world defeated, wakes it up, and returns everyone home 20 seconds after it dies.

Admin commands

Admins drive the mod from the in-game developer console, through Server Devcommands. Press F5 and prefix commands with server so they run on the server, where the plugin lives:

server dr status            # master switch, cooldown, who is online and where
server dr list              # every event with its weight
server dr possible          # which raids vanilla would allow right now, and where
server dr fire thunderclap  # trigger one event
server dr roll             # roll the table as if someone died (with the usual countdown)
server dr fx <prefab>       # audition any effect prefab
server dr stopraid          # end the running raid
server dr reload            # re-read the config file in place
server dr help              # full list

Only players on the server's adminlist.txt can run these (Server Devcommands enforces that). The command is registered as both deathroulette and the shorter dr. fire refuses when nobody is online, because every effect needs a player to act on.

Configuration

The config file is BepInEx/config/geckuss.deathroulette.cfg, generated on first run.

  • [General] — master Enabled switch, death/effect announcements, CooldownSeconds (default 30), CountdownSeconds (default 3: the 3, 2, 1 before a rolled event fires, 0 = instant), DeathCauseWindowSeconds (default 5: how far back a server-visible hit is named as the cause of death, 0 = never), verbose logging.
  • [Weights] — one entry per event id (see the table); 0 disables that event. Defaults match the table above.
  • [Raids] — UseVanillaGating (default on: raids follow progression, biome and base checks) and Pool (empty = whatever vanilla currently permits). Turn gating off for chaos.
  • [Effects] — override the prefab lists behind Thunderclap, AncientOmen, Lament, plus ThunderclapDamage and AdrenalineBuff.
  • [Events] — PilgrimageSummonsBoss (default on) turns the mass teleport back into a boss fight. LoudGriefDuration (default 60 s), LoudGriefNoisePower (default 40 m), LoudGriefSpawnCount (default 2) and LoudGriefSpawnPrefab (default Greyling) tune how long everyone is loud, how wide the wake-and-aggro radius is, and whether extra creatures surface beside each player (set the count to 0 for sound-only).

Safety rails

  • Never self-inflicted death. blood_tax and thunderclap cap their damage at a fraction of current health (a broken trigger can't recurse into more deaths).
  • One event per death and a global cooldown (default 30 s).
  • Graceful declines. Events that can't apply — nobody else online, no raid running, no boss defeated yet — return quietly and are re-rolled rather than wasted.
  • World-state ops are reversible. Global keys (NoPortals, NoMap) are cleared automatically when their duration ends; raids end via vanilla's own system.

FAQ

  • Do players need the mod? No. This is server-side only; vanilla clients see everything.
  • Will it break existing saves or world files? No. The mod changes no save format and no protocol.
  • I rolled an event and nothing happened. Some effects resolve names client-side (status effects, prefabs) and a wrong name fails silently. Drive it deliberately to check: server dr fire thunderclap, then server dr fx <prefab> to audition assets. If it announces but shows nothing, it's a name, not the plumbing — see Name accuracy.
  • How do I make an event rarer or remove it? Set its [Weights] entry in the config (0 disables), then server dr reload.
  • Can a roulette event kill me? Not directly — see Safety rails. It can absolutely set you up so that something else kills you. That's the point.

Compatibility and limits (be honest)

  • Built against l-1.0.12 (network 40, world 41) with BepInEx 5. When the game or BepInEx updates, rebuild against the server's current assemblies.
  • It can only drive things stock clients already understand. Custom audio, custom VFX, HUD text, and screen shake would need a client-side mod and are intentionally out of scope.
  • Status-effect and prefab names must exist in the client's assets (ObjectDB / ZNetScene); the server can't validate them, so bad names fail silently.

How it works (for the curious)

The short version: the server watches for deaths, then tells vanilla clients to do things using their own RPCs. Nothing here requires a client mod.

  • Death detection. A player's ZNetView is owned by their client, so Player.OnDeath never runs on a server. The broadcast made from inside it — m_nview.InvokeRPC(Everybody, "OnDeath") — is a routed RPC; the server sees it in ZRoutedRpc.HandleRoutedRPC before relaying it, with the dying player's ZDOID. A postfix there catches every death, and name/position come off the ZDO.
  • How they died, when the server can tell. Almost all player damage is computed on the dying player's own client, so the server stays blind to most causes. Every hit a server-owned thing lands on a player — falling trees and rocks, carts, ballistae/turrets, creature projectiles, environment AOEs — goes through Character.Damage, so a prefix there records the last one per player (DeathCause). If a death broadcast arrives soon after, the announcement names it.
  • Death-to-effect timeline. The death line is announced, then the countdown walks down the raid-banner slot (CountdownSeconds, default 3), and only then the event is rolled, applied, and announced — same ShowMessage RPC all along.
  • Driving vanilla clients. ServerActions calls RPCs the stock client has always registered: RPC_AddStatusEffect, RPC_Heal, RPC_TeleportTo, RPC_AddNoise, RPC_Stagger, RPC_Damage, ChatMessage/ShowMessage, ZNetScene's SpawnObject, RandEventSystem.SetRandomEventByName, plus ZDO-level backend like BaseAI.SetAggravated and RPC_SetTamed. Per-ZDO RPCs are owner-guarded in vanilla, which is exactly why broadcasting them is safe: the owner acts and everyone else no-ops.
  • Effects are server-authorized, not client-scripted. Sound/VFX prefabs instantiate on every client via SpawnObject (good for effects, wrong for creatures — spawning N copies is the duplicate-spawn trap the mod carefully avoids).
  • ZNet.IsDedicated() lies in this build (hardcoded false); everything uses the real IsServer().
  • Why commands can't ride chat. Chat is emitted as one RPC per online player, addressed to that player's own peer — a dedicated server has no player of its own, so messages are dropped. Announcements go through the routed ShowMessage RPC instead (the "ground is shaking" slot).

Name accuracy

Three name pools resolve in different places:

  • Raid names come from game prefabs and vary by world and version. [Raids] Pool is empty by default = "whatever vanilla currently permits". To pin a list, read the world's real names off the running server (logged at startup) and set them in config.
  • Effect prefabs resolve in the client's ZNetScene. 1,892 real names from the build's asset manifest are in reference/effect-prefab-names.txt.
  • Status effects resolve in the client's ObjectDB. Names used here are long-standing vanilla names but not statically verified — confirm them in play.

Building from source

dotnet build -c Release

netstandard2.1, matching BepInEx 5 on Unity Mono. No publicizer needed. The build needs the assemblies in lib/ (game + BepInEx + 0Harmony + Unity), copied from a local install (valheim_Data/Managed) and your server's BepInEx/core; they're gitignored rather than committed.

src/Plugin.cs          BepInEx entry point, config, command-file poll
src/DeathWatcher.cs    Harmony patch that detects death server-side
src/DeathCause.cs      best-effort 'how they died' from server-visible hits
src/ServerActions.cs   server -> vanilla client primitives
src/RouletteEvents.cs  the weighted event table
src/StartupPatch.cs    logs the world's real raid names on start
src/Announce.cs        the two announcements (who died, what fired)
src/CommandFile.cs     polled command-file admin channel
src/ConsoleCommands.cs 'dr' developer-console command (via Server Devcommands)
src/EffectSustain.cs   re-applies status effects over their intended duration
src/EffectSpec.cs      effect-prefab layering parser

Changelog

See CHANGELOG.md.

Thunderstore development is made possible with ads. Please consider making an exception to your adblock.