
Skald
Achievements, grisly death announcements, nemeses, survival streaks, raid and boss call-outs, !skald chat commands, and a server watchdog with weekly Discord recaps. Needed on the server and every client.Skald
The skald remembers every deed. And every death.
Skald keeps the story of your server: who reached the Mistlands first, who has died to trolls eleven times, who has gone twenty days without dying, and whether the server itself is going to make it to Fader.
Quick start
- Install Skald on the server and on every player's game. The server does the remembering; each player's game reports what happened to them and displays Skald's messages. A player without it sees nothing and reports nothing.
- Everyone must run the same version — mismatched clients are turned away at the handshake, with the reason in the log.
- In game, press F10.
Nothing else is required. Discord is optional and off until you add a webhook.
The panel
Press F10. Skald's own window opens, with a tab for each page:
- Achievements — what you've earned, and what you're closest to, with progress bars
- Leaderboards — who leads on achievements, hours, deaths and streaks
- Deaths — how you've died, to what, your grudges, and the server's recent deaths
- The World — what the world is made of, and how the server is holding up
Daniel - 12 of 32 earned
In progress
[#####-----] A Day in Valheim 12.5/24 h
[########--] Woodsman 412/500 trees
[#---------] Deforestation Incident 412/5000 trees
Earned
Into the Mire - Set foot in the Swamp.
Escape or Close shuts it again. Rebind the key with PanelKey.
The same pages also appear in the game's own Texts screen (inventory, then the compendium icon), so nothing is lost if the window can't be built.
There is also an experimental rune icon for the inventory's row of icons, off by
default. That row is prefab data and mods rearrange it, so the rune often lands
badly. PanelIcon turns it on, with PanelButtonExtendPanel and
PanelButtonOffsetX / PanelButtonOffsetY to place it.
In chat
Achievements appear in big text in the middle of the screen, with the detail in chat:
Timothy earned "Into the Mist" Timothy is the first on the server to set foot in the Mistlands.
Deaths get a line, and Skald has opinions:
Skald: Daniel came apart in Troll's grip like wet bread. Skald: Fulda was crushed by the very tree they were chopping. Skald: A Deathsquito killed Timothy. Two grams of pure malice.
Grudges form when the same thing keeps killing you:
Skald: A grudge is born: Troll has killed Daniel 3 times. Skald: Vengeance: Daniel has cut down Troll at last.
Streaks, returns, bosses and raids:
Skald: Astrid has survived 20 days without dying. Something out there is taking notes. Skald: Bjorn returns after 6 days away. Things died in the meantime. Skald: Moder fell after a 6-minute fight. Casualties: 2 (Daniel, Fulda x2). Skald: The ground is shaking near Daniel's base. Trolls.
Arriving after a break gets you a private summary:
While you were away (2 days): Boss down: Bonemass. Timothy earned Woodsman. 3 deaths while you were gone (Troll took 3). Your 9 days without dying still stands.
Chat commands
Type these in chat. Nobody else sees the command or the answer.
| Command | Shows |
|---|---|
!skald |
Your achievements, hours, deaths, streak, nemesis, and the three you're closest to |
!skald <name> |
The same for another player |
!deaths [name] |
Deaths by cause and by killer, and active grudges |
!top |
Leaderboards: achievements, time played, deaths, longest streak |
!world |
What the world is made of, and what grew this week |
!recap |
(Admins) Post this week's recap so far to Discord |
What Skald tracks
- 39 achievements: 7 bosses, 6 biomes, 2 playtime tiers, 19 for combat, work, travel, taming, eating and dying, and 5 hidden ones. Progress counts from when Skald first sees you, so veterans don't unlock everything on day one.
- Death announcements: 326 lines across all 25 ways Valheim can kill you, with their own lines for a dozen notable creatures. Dealt rather than rolled, so you see every one before any repeats.
- Nemesis system: three deaths to the same kind of creature (or the same player) and it holds a grudge. Killing one settles it.
- Survival streaks: in-game days survived without dying, counted only while you're online. When a long streak ends, the death message says so.
- First to reach: the first player into each biome is named.
- Return messages for players back after a long absence, and a private "while you were away" summary of what they missed.
- Boss fight summaries: how long the fight took, and who died in it.
- Raid announcements: everyone hears whose base is under attack, and the casualties when it ends.
- Performance watchdog: frame time, memory, save stalls and world size, alerting Discord when things degrade.
- World census: what your world is actually made of, so growth can be blamed on something specific rather than just noticed.
- Weekly Discord recap: hours, deaths, achievements, bosses, server health, and a forecast of when the world will outgrow the server.
Achievements are awarded once per character per world, ever, and survive restarts and crashes. A new world starts fresh.
Server setup
Installing on a dedicated server. Most hosts can install Thunderstore mods
directly. If yours can't, put Skald.dll in BepInEx/plugins/Skald/ on the server
and restart it. The server needs BepInEx, same as the clients.
Discord does nothing until you give it a webhook:
[Discord]
WebhookUrl = https://discord.com/api/webhooks/...
Nothing is sent anywhere until you do. Once set you get performance alerts and the weekly recap (Sundays at 18:00 server time by default); deaths, achievements and raids can be posted too.
Achievements are a file you can edit.
BepInEx/config/Skald/achievements.json is written on first run with all the
built-ins in it. Change a threshold, add your own, or mark one "hidden": true so
it only shows once earned:
{ "id": "trees_500", "title": "Woodsman", "description": "500 trees felled.",
"type": "stat", "stat": "TreeChops", "target": 500, "unit": "trees" }
Types are stat (any of the game's per-character counters), playtime, biome and
key (a world flag such as defeated_bonemass). A broken file is never
overwritten: Skald logs what's wrong with it, line by line, and uses the built-in
catalog until you fix it.
Where the data lives, beside the world save:
worlds_local/<World>.skald.tsv player profiles, achievements, deaths
worlds_local/<World>.skald.tsv.bak the previous save, for recovery
worlds_local/<World>.skald-health.tsv performance history and world censuses
Deleting them resets that world's records. They're tab-separated and safe to read.
Testing raid announcements: with devcommands on, run event army_eikthyr.
Settings
BepInEx/config/com.dks.skald.cfg, created on first run. "Where" says which side
reads it — client settings can differ per player.
General
| Setting | Default | Where | What |
|---|---|---|---|
Enabled |
true |
both | Master switch. Off leaves the game unpatched. |
Achievements
| Setting | Default | Where | What |
|---|---|---|---|
Enabled |
true |
server | Track and announce achievements |
AnnounceInChat |
true |
server | Show Skald's public announcements in game |
AnnouncerName |
Skald |
server | Name in front of Skald's chat lines |
CountLifetimeStats |
false |
server | Count a character's whole life instead of progress on this server |
ReportIntervalSeconds |
30 |
server | How often a client reports its stats |
StartupGraceSeconds |
30 |
server | Silence after startup, so loading a world doesn't spam old milestones |
FirstToReachBiomes |
true |
server | Call out the first player into each biome |
Deaths
| Setting | Default | Where | What |
|---|---|---|---|
Enabled |
true |
both | Announce deaths with cause and killer |
AlsoPostToDiscord |
false |
server | Send death announcements to the webhook |
Nemesis |
true |
server | Grudges against whatever keeps killing you |
NemesisThreshold |
3 |
server | Deaths to the same killer before it's a nemesis |
SurvivalStreaks |
true |
server | Announce days survived without dying |
StreakEndMentionDays |
3 |
server | Streak length worth mentioning when it ends |
Social
| Setting | Default | Where | What |
|---|---|---|---|
ChatCommands |
true |
both | Enable !skald and friends |
PanelKey |
F10 |
client | Key that opens the panel from anywhere |
PanelIcon |
false |
client | Experimental rune in the inventory's icon row. Off: use the key |
PanelButtonExtendPanel |
true |
client | With PanelIcon on, widen the row's panel and put Skald first |
PanelButtonOffsetX |
0 |
client | Nudge that button sideways, in pixels |
PanelButtonOffsetY |
0 |
client | Nudge that button up or down, in pixels |
WhileYouWereAway |
true |
server | Private summary of what an arriving player missed |
WhileYouWereAwayMinHours |
0.5 |
server | Hours away before that's worth sending |
ReturnMessages |
true |
server | Announce players back after a long absence |
ReturnAfterDays |
3 |
server | Real days away that count as a long absence |
Events
| Setting | Default | Where | What |
|---|---|---|---|
BossSummaries |
true |
server | Fight length and casualties when a boss dies |
RaidAnnouncements |
true |
server | Raids, naming whose base, and the toll after |
WorldCensus |
true |
server | Count what the world is made of |
CensusIntervalHours |
6 |
server | Hours between counts |
Watchdog
Tuned for a 4 GB server with around 5 players. Adjust the memory and object thresholds for other sizes.
| Setting | Default | Where | What |
|---|---|---|---|
Enabled |
true |
server | Monitor server performance |
SampleIntervalSeconds |
10 |
server | Seconds per metrics sample |
FrameWarnMs |
50 |
server | Average frame time that counts as slow |
FrameCriticalMs |
120 |
server | Average frame time that counts as bad |
SustainedSamples |
3 |
server | Bad samples before alerting, so one hitch doesn't page you |
MemoryWarnMb |
2800 |
server | Memory warning threshold |
MemoryCriticalMb |
3400 |
server | Memory critical threshold |
ZdoWarnCount |
150000 |
server | World object count worth warning about |
SaveWarnSeconds |
5 |
server | World saves slower than this are reported |
AlertCooldownMinutes |
15 |
server | Minimum gap between repeats of an alert |
Discord
| Setting | Default | Where | What |
|---|---|---|---|
WebhookUrl |
(empty) | server | Your webhook. Empty means nothing is ever sent |
AnnounceAchievements |
false |
server | Also post achievements and boss summaries |
AnnounceRaids |
false |
server | Also post raid start and end |
WeeklyRecap |
true |
server | Post the weekly summary |
RecapDay |
Sunday |
server | Day it posts, server local time |
RecapHour |
18 |
server | Hour it posts (0-23). If the server is down then, it posts at the next start |
Compatibility
- Valheim 1.0 (Unity 6), BepInExPack_Valheim 5.4.2350
- Dedicated and listen servers
- Doesn't touch gameplay, items or balance, so it should sit alongside other mods
Known limits
- Players without Skald see none of its messages, and don't report their own deaths or stats.
- The inventory button may not appear if another mod has rearranged that screen. The key bind always works.
- Raid names come from the game's data rather than its code, so a few raids get a generic "something is coming" line.
- Installing on a world already in progress: the first person to reach each biome after installation is the one called first.

