You are viewing a potentially older version of this package. View all versions.
TrueNativeStudio-Skald-0.5.0 icon

Skald

Achievements, grisly death announcements, nemeses, survival streaks, boss and raid call-outs, an F10 panel, !skald commands, and a server watchdog with Discord alerts, a live status message and weekly recaps. Needed on the server and every client.

Date uploaded 2 weeks ago
Version 0.5.0
Download link TrueNativeStudio-Skald-0.5.0.zip
Downloads 109
Dependency string TrueNativeStudio-Skald-0.5.0

This mod requires the following mods to function

denikson-BepInExPack_Valheim-5.4.2351 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.2351

README

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

  1. 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.
  2. Everyone must run the same version: mismatched clients are turned away at the handshake, with the reason in the log.
  3. In game, press F10.

Nothing else is required. Discord is optional and off until you add a webhook.

💬 Questions, bug reports or ideas? Join the Discord.


The panel

Press F10. Skald's own window opens on its own, 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, kills, exploring, 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
  • Admin (admins only), your announcements, with switches and a form for adding more: a name, what it says, and dropdowns for when it fires and where it goes

Progress is drawn as proper bars that fill in as the page opens, with the numbers counting up beside them. On the World tab, memory and world size are shown as gauges that turn from green to amber to red as the server fills up.

Escape or Close shuts it again. Rebind the key with PanelKey.


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, what grew this week, and the busiest areas
!recap (Admins) Post this week's recap so far to Discord
!announce (Admins) List, add, switch, test and remove announcements
!skald reload (Admins) Reread achievements.json, messages.json and announcements.json

What Skald tracks

  • 58 achievements: 7 bosses, 6 biomes, 2 playtime tiers, 24 for combat, work, travel, taming, eating and dying, 12 for hunting particular creatures and 7 for exploring, with 8 of them hidden until someone earns them. Progress counts from when Skald first sees you, so veterans don't unlock everything on day one.
  • Kill counts by creature: every kill counted per player and per kind of creature, which the game itself doesn't keep, for achievements like "Troll Toppler: 25 trolls" and a Kills leaderboard.
  • Exploring: how much of the world each player has uncovered on their own map, worked out on their machine and sent as a single number. No map ever leaves it.
  • 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. All of them editable, and yours can be added.
  • 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.
  • Busiest areas: where on the map the objects pile up, and whose build it is, e.g. "Timothy's build, 1.2 km north-east of the world centre: 41,200 objects, mostly building pieces".
  • Live Discord status: one message kept up to date with who's online and how the server is doing.
  • Weekly Discord recap: hours, deaths, achievements, bosses, server health, and how fast the world is growing.
  • Your own announcements: lore on a timer, a private word when someone first reaches a biome, a warning before the nightly restart.

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, the weekly recap (Sundays at 18:00 server time by default) and a live status message; deaths, achievements and raids can be posted too.

Boards that edit themselves. Besides the status, Skald can keep a death log (the last few deaths), a world report (makeup, busiest areas, growth) and a leaderboard up to date, each as a single message it edits rather than a stream of posts. All three are off until you switch them on, and each can have its own webhook so it sits in its own channel. Pin them.

The live status message is posted once and then edited every two minutes: who's online, the in-game day, uptime, frame time, memory, world objects, the last save and the busiest area, under a green, yellow or red light. Pin it. It shows when it was last updated, so if the server dies it visibly goes stale, and a clean shutdown marks it offline. To put it in its own channel (a #server-status, say), give that channel's webhook to StatusWebhookUrl. If the message is deleted, Skald posts a new one.

Achievements are a file you can edit. BepInEx/config/Skald/achievements.json is written on the server, the first time a world loads, with all the built-ins in it. It won't appear on a player's game: the server owns the catalog, so changing it asks nothing of your players. 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" }

New built-in achievements arrive by themselves. When an update adds achievements, Skald adds them to your existing achievements.json on the next load, leaving everything you wrote untouched and keeping the previous file as achievements.json.bak. It records what it has offered in achievements.offered.txt, so one you deleted is never added back.

Types are stat (any of the game's per-character counters), playtime, biome, key (a world flag such as defeated_bonemass), kills (a number of one kind of creature, e.g. "creature": "troll") and explored (a percent of the world). 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.

Your own messages, on a timer or when something happens. BepInEx/config/Skald/announcements.json, written on the server with examples in it, all switched off until you enable them:

{ "announcements": [
  { "id": "lore", "enabled": true, "when": "every 45m", "to": "chat",
    "lines": ["The gods are watching, and they are bored.",
              "Every raven that follows you is taking notes."] },
  { "id": "swamp", "enabled": true, "when": "firstbiome:Swamp", "to": "private",
    "lines": ["The water here has a taste. Old iron, and older mistakes."] }
] }

When: every 45m, at 03:00 (server clock), dawn, dusk, newday, join, firstjoin, biome:Swamp (each time a player walks in, not on spawning, at most every 5 minutes each), firstbiome:Swamp (their first time ever), death, boss, raid, achievement. Where: chat, banner or discord for everyone; private or private, banner for only the player it happened to. Placeholders: {player}, {biome}, {boss}, {killer}, {day}, {online}. Add requirePlayers to keep quiet on an empty server and minGap to space repeats.

Every message is a file you can edit. BepInEx/config/Skald/messages.json, written on the server on first run, holds every line Skald says: deaths by cause and by creature, grudges, streaks and returns.

{
  "deaths": {
    "byCause": { "Drowning": ["The sea kept {player}."] },
    "byKiller": { "troll": ["A troll made a rug out of {player}."] }
  },
  "streaks": ["{player} has gone {dayspan} without dying. Suspicious."]
}

Placeholders are {player}, {killer}, {count} and {dayspan}. Your lines are added to Skald's by default; "mode": "replace" makes yours the only ones, and [] with replace silences that kind of message. Sections you leave out keep their built-in lines. Broken files are never overwritten: Skald logs what's wrong and uses its own lines until you fix it.

The full guide. Skald writes BepInEx/config/Skald/GUIDE.txt on the server every time a world loads: every field, trigger and placeholder for all three files, and lists of every death cause, creature, boss, stat and biome, taken from the running game so they match your server exactly, mods included. After editing any file, type !skald reload in game as an admin; no restart needed.

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
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 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
ObjectAlertCount 0 server Alert when the world passes this many objects. 0 = never: the count only grows with exploration, so it's tracked, not warned 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
LiveStatus true server Keep a live status message up to date
DeathLog false server One message holding the most recent deaths, edited in place
DeathLogSize 10 server How many deaths it shows (3-25)
WorldReport false server One message with the world's makeup, busiest areas and growth
Leaderboard false server One message with the standings
LeaderboardIntervalMinutes 15 server Minutes between leaderboard updates
DeathLogWebhookUrl, WorldReportWebhookUrl, LeaderboardWebhookUrl (empty) server A channel of its own for each. Empty uses WebhookUrl
LiveStatusIntervalSeconds 120 server Seconds between status updates (30-3600)
StatusWebhookUrl (empty) server Separate webhook for the status message. Empty uses WebhookUrl
StatusServerName (empty) server Name on the status message. Empty uses the server's own name

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

Privacy

Skald keeps, on the server, beside the world save: each character's name and the game's own ID for that character, playtime, the game's per-character counters (trees felled, enemies killed and so on), biomes visited, deaths (cause, killer and time), grudges, streaks, achievements, and when they were last seen. It does not store Steam or other platform IDs, IP addresses, or locations. A refused !recap logs the requester's platform ID to the server log so admins can fix adminlist.txt.

Nothing leaves the server unless the admin sets a Discord webhook. With one set, performance alerts and the weekly recap (player names, hours, deaths, achievements) are posted there, and deaths, achievements and raids too if enabled.

If you run a server with Skald, tell your players. To erase a player's record, stop the server and delete their lines from <World>.skald.tsv; deleting the whole file resets everyone. Keep your webhook URL private: anyone who has it can post to your channel.

Known limits

  • Players without Skald see none of its messages, and don't report their own deaths or stats.
  • Raid names come from the game's data rather than its code, so a few raids get a generic "something is coming" line.
  • Stats and deaths are reported by each player's own game. Skald checks who sent them and limits how often, but it can't tell whether the numbers are true: a player with a modified game can claim achievements they didn't earn. The same player could just as easily cheat in the game itself.
  • Installing on a world already in progress: the first person to reach each biome after installation is the one called first.

Questions, bugs and ideas

💬 Questions, bug reports or ideas? Join the Discord , it covers Skald and my other Valheim mods.

License

MIT - see LICENSE. Provided as is, without warranty of any kind. Back up your worlds; the author is not liable for lost data or anything else arising from its use.

Skald is a fan-made mod, not affiliated with or endorsed by Iron Gate or Coffee Stain. Valheim is a trademark of its respective owners.

CHANGELOG

Changelog

Upgrading: the server and every player should run the same version. Where a release changes the protocol it says so, and mismatched clients are turned away at the handshake with the reason in the log.

0.5.1

Added

  • Banner-only messages. A new server setting, [Banners] AlsoInChat, stops banners being copied into chat, so the chat window no longer pops open over them. With it off, an achievement's description shows under its title on screen instead.
  • Longer banners. [Banners] Seconds sets how long banners stay on screen, from the game's own 4 seconds up to 30. Each announcement can set its own with "seconds", and the Admin tab has a Duration picker for banners.
  • A simpler Where in the Admin tab: Chat, Banner, Discord, or Chat and Discord, with a Private box for "only the player it happened to". The box only appears where private can work: not on timers, bosses or raids, which don't happen to one player, and not with Discord, which can't message one person.
  • Variants in the Admin tab. "+ Add a variant" adds up to four more ways to say an announcement (Says V2 to V5); one is picked at random each time it fires, and each is used before any repeats. The list shows how many variants each one has.

Fixed

  • {day} is now the world's current day on every trigger. It was blank on all but newday, and Test always showed Day 1.
  • Private announcements on achievement never reached the player who earned it.
  • Private announcements that could never be sent (on a timer, or to Discord) were accepted and then silently skipped. Skald now refuses them and says why.

Changed

  • Now depends on BepInExPack_Valheim 5.4.2351, the current pack.

Upgrading: 0.5.0 and 0.5.1 still play together; the protocol is unchanged. Update the server first: the banner settings, variants and fixes all live there. A player still on 0.5.0 sees banners the old way, with the game's timing and a chat line.

0.5.0

Added

  • Hunting achievements. Skald now counts every kill per player and per kind of creature, which the game itself doesn't, and a new kills achievement type uses it: "Troll Toppler: 25 trolls". Twelve built in, from greydwarfs and boars to sea serpents and gjall, one of them hidden; a Kills leaderboard; and any creature you like in achievements.json. A cluster of kills from one swing now counts in full.

  • Exploring. How much of the world each player has uncovered on their own map, worked out on their machine and reported as a single number, so no map ever leaves it. Maps shared at a cartography table don't count. A new explored achievement type, seven built in from 2% to the whole world (the last two hidden), and an Explored leaderboard.

  • New built-in achievements reach existing servers. Skald adds any it ships to your achievements.json on the next load, as additions to the file rather than a rewrite, so your own entries and notes survive, with the previous file kept as .bak. What it has offered is recorded in achievements.offered.txt, so one you delete stays deleted.

  • The welcome for first-time players is on by default: a private word the first time anyone joins, pointing them at F10. Every other example stays off.

  • GUIDE.txt, written beside Skald's files on the server: everything needed to write your own messages, announcements and achievements, with every field, trigger and placeholder explained. Its lists of death causes, creatures, bosses, stats and biomes are taken from the running game each time a world loads, so they are always exact for that server, including anything other mods add.

  • !skald reload (admins) rereads all three files in place, so edits apply without a restart.

  • Boss triggers take the boss's own short name: boss:bonemass, boss:gdking.

  • An Admin tab in the Skald window (F10), for announcements. Admins get a fifth tab listing what is set up, with a switch, a Test and a Remove button on each, and a small form for writing a new one: a name and what it says (typed into the game's own text box), and dropdowns for when it fires and where it goes. No file editing, no restart.

  • !announce in chat, which the Admin tab uses under the hood, so the window can only do what an admin could type and rights are checked in one place: !announce list, add id=lore when="every 45m" to=chat line="...", on, off, test, remove, reload. Non-admins are turned away.

  • Announcements that are switched off are now kept in the list rather than ignored, so they can be seen and turned on again. The file is rewritten with its explanatory header intact, through a temporary file with a .bak, so a failure can't leave it broken.

  • Three more Discord messages that edit themselves, like the live status, so a channel holds a living board instead of a stream of notifications. All off by default, each with an optional webhook of its own so it can live in its own channel:

    • Death log (DeathLog): the last 10 deaths, newest first, with times that keep counting in every reader's client. This is the one that makes deaths-to-Discord bearable to leave on.
    • World report (WorldReport): what the world is made of, its busiest areas and how fast it's growing. Redrawn after each census.
    • Leaderboard (Leaderboard): achievements, hours, deaths and streaks, refreshed every 15 minutes.
  • Your own messages, on a timer or when something happens. BepInEx/config/Skald/announcements.json is written on the server with worked examples, all switched off until you enable them. Each entry is some lines plus an occasion to say them on:

    { "id": "swamp", "enabled": true, "when": "firstbiome:Swamp", "to": "private",
      "lines": ["The water here has a taste. Old iron, and older mistakes."] }
    

    It ships with 14 worked examples, all off: a rotation of twelve Norse lore lines, a private word for each of the nine biomes the first time a player reaches one, dusk and new-day banners, a welcome for a player's first ever visit, and a 3am restart warning. Turn on the ones you like and rewrite the rest in your server's voice.

    When: every 45m, at 03:00 (server clock), dawn, dusk, newday, join, firstjoin, biome:Swamp (each time a player walks in), firstbiome:Swamp (their first time ever), death, boss, raid, achievement. Where: chat, banner (big text on screen) or discord for everyone, and private or private, banner for only the player it happened to. Placeholders: {player}, {biome}, {boss}, {killer}, {day}, {online}.

    Lines are dealt from a shuffled bag, so a dozen lore lines all get used before any repeats. requirePlayers keeps chatter off an empty server, minGap sets the least time between repeats, and nothing may fire more often than every 30 seconds.

  • Every message Skald says is now yours to rewrite. BepInEx/config/Skald/messages.json is written on the server on first run, holding all 326 death lines by cause and by creature, plus the grudge, streak and return lines. Add your own, delete ones you dislike, or rewrite the lot in your server's voice. Placeholders: {player}, {killer}, {count}, {dayspan}.

    { "deaths": { "byKiller": { "troll": ["A troll made a rug out of {player}."] } } }
    

    By default your lines are added to the built-in pool, so they turn up alongside Skald's. "mode": "replace" makes yours the only ones, and a pool set to [] in replace mode goes quiet. A section you leave out keeps its built-in lines. Custom lines are dealt from the same shuffled bag, so they don't repeat either.

    As with achievements.json, a broken file is never overwritten: every problem is logged with the section it came from, and the built-ins carry that session.

Fixed

  • Mistakes in Skald's files are reported by line. Instead of "at position 6942", the log names the line and column, shows the line, and says when the usual culprit is to blame: a comma missing between two entries.
  • The weekly recap can no longer be lost. It was marked as sent before Discord had it, so a failed post lost that week for good. Now it's marked only once Discord confirms it, and a failed post is tried again 15 minutes later.
  • Discord asking Skald to slow down no longer drops posts. Every message (alerts, the recap, the status message and boards) waits the time Discord asks for and tries again, rather than giving up.
  • Scrolling in the Skald window no longer touches the camera behind it at all (it used to zoom for a frame and snap back), and the Admin tab's dropdown lists have a scrollbar and move three rows per notch of the wheel.
  • Skald now reads a player's biome the way the game does. Valheim 1.0 decides it from biome sectors, and the older method Skald asked could disagree across a wide area near borders (the game logs "GetBiome error" when they do), so a player could walk into the Black Forest and be counted as having been there all along. Biome announcements and first-into-a-biome now happen when the player's own screen says they have arrived.
  • Skald can now keep several Discord messages up to date rather than just the status. State files from 0.4.x carry their status message over, so it keeps editing the same one rather than posting a new one.
  • The Discord status no longer sits on "starting up" forever when the watchdog is switched off. It reads "online" instead, and still shows who's on, the day, uptime and the world's object count; only the frame time and memory need the watchdog.

Removed

  • The experimental rune icon in the inventory (PanelIcon and its three placement settings), which never sat right, and Skald's pages in the game's Texts screen, which F10's window replaced. Four fewer places a Valheim update can break.

0.4.0

Added

  • Busiest areas. The world census now also works out where the world is crowded, and whose building it mostly is:

    1. Timothy's build, 1.2 km north-east of the world centre (x 1240, z -380): 41,200 objects, mostly building pieces (38,900)

    Shown in !world, the World tab and the weekly recap, and named in the Discord alert when the object count runs high - so it points at the base or the forgotten pile of dropped loot that is actually to blame.

  • Live server status in Discord. One message that Skald keeps editing in place: who is online, the in-game day, uptime, frame time, memory, world objects, the last save, and the busiest area, under a green, yellow or red light. Pin it once. It says when it was last updated, so a server that went down without warning shows as stale, and it's marked offline on a clean shutdown. Needs the webhook; StatusWebhookUrl can send it to its own channel.

  • Real progress bars in the Skald window. Rounded bars that fill in when a page opens, with the numbers counting up alongside and a glint running along each. New bars for achievements earned and bosses defeated, and gauges on the World tab for memory and world objects that go from green to amber to red as they fill. The game's Texts screen still shows the text version.

Changed

  • The world's object count is tracked, not warned about. It only ever goes up: every area anyone explores adds its trees, rocks and bushes to the world for good, so a warning about it can only ever get louder. It's still counted and shown in !world, the World tab, the weekly recap and the Discord status, now with how fast it's growing. The alert is off by default; ObjectAlertCount turns it back on at a line you choose (it replaces ZdoWarnCount).
  • F10 opens the Skald window on its own, without the inventory behind it. The cursor is freed and your character stays put while it's open; Escape closes the window without opening the pause menu, and opening the inventory, map or menu closes it.
  • Skald is now MIT licensed. See License at the end of the README.

Fixed

  • Wild bushes are no longer counted as construction. Mods that let you plant flora or place rocks attach a build-piece component to those prefabs, so every shrub and stone in the world counted as a building piece: one server showed 248,000 pieces where roughly 25,000 were built by hand. A piece now counts as construction only if someone actually placed it, which the game records on the object itself. Ordinary walls and floors are unaffected, and the busiest-areas list is honest again. Expect one step change in your census history where the counts move back.
  • Memory readings now match your host's panel. Skald read the runtime's "private bytes", which on Linux counts reserved address space and ran hundreds of MB high (3,384 MB against a panel showing 2,785). On a hosted server it now reads the container's own figure, the one the host enforces and its panel shows, and falls back to resident memory elsewhere. Memory alerts fire at the right point, and the status message shows usage against the server's real limit (e.g. 2,785 / 4,096 MB).
  • The Skald window's pages no longer run off its right edge. They were drawn 100 units too wide and clipped, cutting off the ends of long lines.
  • Long pages in the Skald window can be scrolled. The mouse wheel did nothing, so the end of Leaderboards (and any long page) was out of reach. There's a scrollbar now too, shown when a page runs past the window.

Security - update the server as well as clients

  • Players can no longer pose as each other, or as the server. Valheim lets a modified client put any sender on a message. The server now checks every Skald message against the connection it actually came from, and drops forgeries. Before this, a modified client could file deaths or stats under another player's name, use an admin's identity for !recap, or put fake Skald banners on everyone's screen.
  • Clients only accept Skald messages that come from the server.
  • Rate limits per player on everything a client can ask of the server, so a modified client can't flood chat, Discord or the disk. Normal play never gets near them.
  • Stat reports must name one of the game's own counters, with a real number.
  • A character's record of what killed them is capped at 200 kinds of killer.
  • Discord posts explicitly allow no mentions, so a name can never ping @everyone.
  • Webhook URLs are stripped from anything Skald logs. A webhook URL is a password, and admins paste logs into support threads.

Still protocol v3: 0.3.0 and 0.4.0 work together, but the protections above and the new server features need 0.4.0 on the server, and the new bars need it on clients.

0.3.0

Added

  • Skald's own window. Press F10: a tab each for achievements (with progress bars), leaderboards, your death record, and what the world is made of. Escape or Close shuts it. The same pages also appear in the game's Texts screen.
  • achievements.json. The catalog is now a file you can edit. Change thresholds, write your own, mark some hidden. The defaults are written out on first run, and a broken file falls back to the built-ins rather than leaving you with none, with each problem named in the log, line by line.
  • While you were away. Arriving after a break gets you a private summary: bosses downed, what everyone earned, how many died and to what, and whether your streak survived.
  • !world. What the world is actually made of (building pieces, dropped items, creatures) and what grew this week. The weekly recap includes it too, so "your world is getting big" becomes something you can act on.
  • Five hidden achievements. You'll find them the hard way.

Changed

  • Death messages: 133 lines became 326, and they no longer repeat until the pool is exhausted. Lines are dealt like cards rather than rolled, so all 18 ways of describing a fall are used before any comes round again.

  • A dozen creatures have their own lines, added to the general pool rather than replacing it, so a Deathsquito reads differently from a Greydwarf:

    A Deathsquito killed Daniel. Two grams of pure malice. Timothy was killed by Neck. A Neck. Let that sit.

  • Performance alerts name what is actually filling the world instead of listing what might be: "The world holds 267,758 networked objects, mainly building pieces (120,400), dropped items (38,200) and creatures (21,000)."

  • The memory alert no longer prints the figure twice, reads against the ceiling rather than in isolation, and groups large numbers.

  • Protocol v3: every player needs 0.3.0 to match the server.

Fixed

  • !recap refusals now name the exact line adminlist.txt needs. Valheim 1.0 wants the prefixed form (V_7656...), not the bare SteamID64, which 0.2.1 wrongly advised. It also recognises when your ID is listed but in the wrong shape, when the file it reads is empty, and when an old-style STEAM_0: ID is in there.

Experimental

  • A Skald rune for the inventory's row of icons, off by default (PanelIcon). That row is prefab data and other mods rearrange it, so the rune tends to land on top of something. The key bind is the reliable way in.

0.2.1

Fixed

  • !recap refusals explain themselves: the reply shows the ID the server sees for your connection and what is wrong with adminlist.txt. The server log records which file it read and how many entries it had.

Server-only; 0.2.0 clients work with a 0.2.1 server.

0.2.0

Fixed

  • Announcements now actually appear in game. Valheim 1.0 permission-checks the sender's platform account on every chat message and silently drops any without one, which was every Skald message. Skald now displays its own messages.
  • Deaths were never announced: the death report tripped over the hit-type enum being byte-backed.
  • Playtime, biomes and stats were never tracked on dedicated servers, because the player ID Skald keyed on is never filled in by 1.0. It now reads the ID the game stores on each character.
  • Achievement state can no longer be lost to a crash, a mis-timed load, or a half-finished save, any of which could re-award achievements.

Added

  • Achievement banners in the centre of the screen.
  • !skald, !deaths, !top and !recap chat commands, answered privately.
  • Nemesis system: die to the same thing three times and it holds a grudge; kill one to settle it.
  • Survival streaks at 5, 10, 20, 30, 50, 75 and 100 days without dying.
  • First-to-reach call-outs for each biome.
  • Return messages for players back after a long absence.
  • Boss fight summaries with fight length and casualties.
  • Raid announcements naming whose base is under attack, and the toll afterwards.
  • Weekly Discord recap with a world-size forecast.

Changed

  • Protocol v2: every player needs 0.2.0 to match the server.
  • State now lives beside the world save, so it survives a BepInEx reinstall and is picked up by whatever already backs up your worlds.

0.1.0

First release.

  • Achievements for bosses, biomes, playtime and the game's own per-character stats.
  • Death announcements naming the cause and the killer.
  • A performance watchdog for frame time, memory, world saves and world size, alerting a Discord webhook.