Confirm with your password

Gjallarhorn

Server-side Viking death announcements, boss-defeat chronicles, and join/leave notices. Vanilla clients supported; installing it client-side upgrades the feed to exact killer and cause of death.

Client & Server Discord Role Play Valheim 1.0
Changelog & versions

· Website

Stars
0
Downloads
4
Version
0.3.0
Updated
Author
RAGEmedia
Virus scan
✓ Scan successful
Runs on
Client & Server
Required by
3 mods

Compatibility

Required 1

Install these too — Gale pulls them in for you.
  • Jotunn ValheimModding ·2.30.2

Description

Gjallarhorn

A server-side Viking kill feed and roster. Player deaths land in the top-left message feed and the chat window; boss defeats get the centre-screen banner; players arriving and leaving are announced in the same voice.

Named for Heimdall's horn — the one sounded to announce across all nine realms.

Who needs to install this

The server needs it. Every client is optional, and the mod is not version-enforced.

  • On the server it does all the work — detection, wording, and broadcasting. It reaches players over ShowMessage and ChatMessage, two RPCs vanilla Valheim already registers, so a server full of unmodded players still sees the whole feed.
  • On a client it is purely additive. Installed, that player's deaths are reported with the real cause and the real killer. Absent, their deaths still announce, but the killer is a proximity guess and non-combat causes read as generic.

Mixed populations are fine and expected. Nobody is refused at connect.

Why clients change the quality of the feed

Everything specific about a death — who swung, what kind of damage, whether another player did it — lives in Character.m_lastHit, set in Character.Damage. That runs on whichever peer owns the dying character's ZDO, which is the victim's own machine. A dedicated server never instantiates a Player component for a remote client and can never read it.

So the server falls back to what it can see: the dead flag on each connected player's replicated character ZDO, and whatever hostile creatures are standing near the corpse. That gets the ordinary case right — you died to the thing that was hitting you, and it is still there — and gets ranged kills, deaths on a fleeing mob, and every non-combat cause wrong.

Vanilla client Client with Gjallarhorn
Death announced yes yes
Victim, position, biome exact exact
Killer creature nearest hostile within 20m, a guess exact
Star rank from the guessed creature exact
PvP kills never identified exact, with the killer named
Fall, drowning, fire, freezing, poison, falling trees read as generic each has its own message
Carts, boats, structures, turrets, the edge of the world read as generic grouped as environmental

Boss defeats are exact either way. The server sees them through ZoneSystem.RPC_SetGlobalKey, which is registered server-side only.

Joins and leaves

Vanilla announces arrivals but never departures, and the asymmetry is not an oversight. The arrival line is a chat shout the joining client sends itself, from Game.SpawnPlayer the first time it spawns. A client that is leaving cannot shout, so there is nothing to mirror it with. Both halves have to be observed server-side instead.

Departures are caught at ZNet.Disconnect, the single funnel a clean quit, a dropped connection and a kick all pass through. Arrivals come from a diff over the peer list on the server tick, gated on the player actually having a character in the world, so someone who backs out at character select is never announced. That same diff backs up the departure hook: if a game update ever moves Disconnect, leaves announce a tick late instead of silently stopping.

Leaves come in three wordings, because a crash should not read as a cheerful farewell:

How they left Pool
Quit to menu or desktop LeaveMessages
Crash, alt-F4, network loss LeaveTimeoutMessages
Kicked, banned, not on the permitted list LeaveKickedMessages

RejoinQuietPeriod keeps a flapping connection from filling the feed: a player who rejoins inside the window is not announced, and the leave that follows is suppressed too — unless the session outlasted the window, in which case it was a real visit and its ending is reported. Identity is the peer's platform id, so it survives reconnects and does not collide when two players pick the same name.

Leaves are announced by default. Arrivals are not: vanilla already covers them, so AnnounceJoins starts off, and turning it on adds a second line rather than replacing vanilla's. Stopping the server is silent either way — no wall of departures nobody is online to read.

Known limits

  • Repeat boss kills only announce for clients with the mod. The global key a boss sets on death is added once per world; a second Bonemass changes nothing the server can observe. A client running Gjallarhorn reports every kill, including repeats.
  • The killer guess is a guess. It is labelled as such in the logs ([guess] versus [exact]) so you can tell at a glance which path produced a line.
  • Chat lines also appear as floating text at the death site for players standing nearby, or with the map open. That is vanilla Chat.AddInworldText behaviour and cannot be suppressed from the server. Turn off UseChatLine if it bothers you.
  • Arrivals are left to vanilla by default. Valheim's own "I have arrived!" is a shout sent by the joining client, so a server cannot suppress a message it did not originate. AnnounceJoins is therefore false out of the box — turning it on adds Gjallarhorn's wording on top of vanilla's rather than replacing it. Leaves have no vanilla equivalent and are on by default.
  • A listen server's host announces neither their own join nor their own leave. The host is not a network peer, so there is nothing to observe — and when the host leaves, the server goes with them. Dedicated servers are unaffected.
  • Modded creatures read as their prefab name. The display-name table covers vanilla only; anything else falls back to a cleaned-up prefab name.
  • English only. Creature and biome names come from a built-in table rather than Valheim's Localization, whose singleton is set up by the client-side startup path and is not dependable on a headless server.

Configuration

BepInEx/config/com.ragemedia.gjallarhorn.cfg, generated on first run. Everything except VerboseLogging and DiscordScreenshots is admin-only and synced from the server, so clients cannot give themselves a different feed.

Section Setting Default What it does
Channels AnnounceDeaths true Announce player deaths.
Channels AnnounceBossDefeats true Announce boss defeats.
Channels AnnounceJoins false Announce arrivals in Gjallarhorn's voice. Off by default: vanilla already announces them. See Known limits.
Channels AnnounceLeaves true Announce departures. Vanilla has no equivalent.
Channels UseTopLeftFeed true Announcements go to the top-left message feed.
Channels UseChatLine true Announcements also post as a chat line.
Channels BossUsesCenterBanner true Boss defeats use the centre banner. Player deaths never do.
Channels ChatSenderName Gjallarhorn Speaker name on chat lines.
Content IncludeBiome true Resolve {biome}.
Content IncludeStarRank true Render 2-star Greydwarf.
Content LogToConsole true Write announcements to the server log.
Content IncludeSessionDuration true Append how long the player was online to leave lines.
Content SessionDurationSuffix after {duration} in the realm What gets appended. Blank it and use {duration} in a pool to place it yourself.
Detection PollInterval 1.0 Seconds between death-flag checks. Vanilla clients only.
Detection ExactReportGrace 1.5 How long to wait for a client's exact report before guessing.
Detection KillerSearchRadius 20 Radius searched when guessing a killer.
Detection SwarmRadius / SwarmThreshold 6 / 4 When a death reads as "overwhelmed by a horde".
Detection RejoinQuietPeriod 60 Seconds after a departure in which a rejoin is not announced. 0 announces every reconnect.
Messages 18 pools — Semicolon-separated; one picked at random. Death and boss tokens {victim} {killer} {boss} {biome}; presence tokens {player} {duration} {online} {biome}. Pools still on an older release's stock text move to the new defaults on startup; edited pools are left alone.
Integrations DiscordScreenshots true Client-side. Rewrites Discord Screenshots' death caption, see Compatibility.

Compatibility

Discord Screenshots (warpalicious). When both mods are installed on a client, that player's death screenshots are posted with a Gjallarhorn line, such as "Astrid was felled by 2-star Troll in the Black Forest", instead of the generic caption. The line is rolled separately from the in-game one, so the wording can differ, but the killer, stars and biome are the same. Players without Gjallarhorn keep Discord Screenshots' own caption. F12 screenshots are never touched. If a Discord Screenshots update moves the method this hooks, the log says so and its default caption returns.

Do not run this alongside another kill-feed, death-announcement, or join/leave-announcement mod. Nothing stops BepInEx loading both, and every event will simply be announced twice.

Safe to add or remove

Nothing is written to the world save. Announcements are in-memory only.

Changelog

0.3.0 Latest
  • Added support for Discord Screenshots: death posts now name the killer, stars and biome
  • Added dozens of new death, boss, join and leave lines, many with Norse flavour
  • Changed untouched message pools to update to the new defaults automatically
  • Changed the required Jotunn version to 2.30.2
0.2.1
  • Dying no longer reads as a logout. Game._RequestRespawn destroys the body and clears the character ZDO, and nothing sets it again until the new body is instantiated, so for the length of the death screen a dead player looked exactly like someone still at character select. The peer-list diff read that gap as a departure and the respawn as a fresh arrival, spelling every death out as a leave and a join. The character-ZDO gate now applies to joining only, never to staying: a player already on the roster keeps their place whether or not they currently have a body. Character select is unaffected -- a peer that never had a character was never on the roster to begin with.
  • Side effects of the same bug, also gone: {online} no longer dips and recovers on every death, and the session clock behind the leave line no longer restarts at each respawn.
0.2.0

Join and leave announcements.

  • Leave detection via a prefix on ZNet.Disconnect, the single funnel every departure passes through -- clean quit, dropped connection, and kick alike. Vanilla has no leave message because its join message is a chat shout sent by the joining client from Game.SpawnPlayer, and a departing client cannot shout.
  • Join detection by diffing ZNet.GetPeers() on the existing server tick, gated on the peer having a character ZDO so it fires on entering the world rather than at character select. The same diff acts as a backstop for leaves if the Disconnect patch ever fails to bind.
  • Three leave wordings: clean quit, lost connection, and kicked. The reason is staged by prefixes on ZNet.RPC_Disconnect and ZNet.InternalKick; anything unmarked is inferred from whether the socket was still alive.
  • RejoinQuietPeriod suppresses join/leave spam from a flapping connection, keyed on the peer's platform id. A suppressed join suppresses its matching leave.
  • Session duration appended to leave lines, and an {online} token for the remaining count.
  • Departures during server shutdown are silenced via ZNet.StopAll.
  • Four new message pools plus AnnounceJoins / AnnounceLeaves, all admin-synced. AnnounceLeaves is on by default; AnnounceJoins is off, because vanilla already announces arrivals via a shout from the joining client that a server cannot suppress.
  • Startup check that every declared config entry actually got bound. A declared-but-unbound entry compiles cleanly and is null at runtime, so the first announcement reading it throws from inside a Harmony prefix, far from the cause -- the config-side twin of the existing patch-bind check.

1 older entry, full version history & downloads →

Files

5 files · 143 KB download

Loading files…

Manual download
Just this mod One .zip — Gjallarhorn 0.3.0
Files you'll get 2
  • Gjallarhorn 0.3.0 RAGEmedia this mod Get
  • Jotunn 2.30.2 ValheimModding Get

Your browser may ask permission to download several files at once. How to install these manually

Manual installation instructions
1

Install BepInExPack Valheim

BepInExPack Valheim is required to run mods in Valheim.

Download BepInExPack Valheim 5.4.2360 · View mod page

Check out the mod page for detailed installation instructions.

2

Install Gjallarhorn

This mod must be installed on both the client and the server.

Download Gjallarhorn 0.3.0

Extract the ZIP and place the file(s) into the BepInEx/plugins/ folder inside your Valheim game folder.