


Two-way Discord β Valheim chat, a live server-status panel with restart/stop reactions, automatic per-client login snapshots, crash detection, GIF/image rendering in chat, and an auto-restart wrapper bat β all driven by a single Discord bot of your own.

Need help, found a bug, want a feature? https://discord.gg/H9uKGcAujs
| Feature | What you get |
|---|---|
| Server Manager panel | A single live-updating embed in a Discord channel showing player count, names, uptime, last heartbeat. Click the π reaction to restart the server, β to stop it (waits for the next π click before coming back). |
| Two-way chat relay | Discord messages appear in-game prefixed with [Discord] author: in the author's Discord role color. In-game shouts get posted back to Discord through a webhook with the player's name + avatar. |
| Inline GIFs and images | Tenor / Giphy / Klipy share URLs and direct attachment uploads render as actual images (and animated GIFs) inside the in-game chat overlay. |
| @mention resolution | A player typing @admin in game chat sends a real @admin Discord ping by resolving the role name via the bot. @everyone and @here work as-is. |
| Login snapshots | Every player that logs in gets a Discord embed posted: their mod list, error count, warning count, the actual mods that produced those errors (no fuzzy-matching false positives), and a client-vs-server mod diff. Admins react to the embed to request the full log / errors-only report / mod list .txt / a session log captured at disconnect. |
| Crash detection | A separate watchdog process spawns alongside the server. If the server crashes or is killed, the watchdog posts a "Server Crash Detected" embed via webhook and updates the status panel. |
| Auto-restart wrapper | A ready-to-edit valheim_server_wrapper.bat is extracted to your config folder on first run. Configure SERVER_NAME / SERVER_PORT / SERVER_WORLD / SERVER_PASSWORD / SERVER_PUBLIC once, drop it next to valheim_server.exe, and run it instead of the exe β the wrapper handles auto-restart-on-crash and stays alive across Discord-triggered stops so a single π click brings the server back. |
| Discord events | Optional per-event webhook posts: server start, server stop, world save, player join, player leave, player death, player shout, random event, new day, anti-cheat kick / violation, hourly summary, midnight EST daily summary. Each one is a separate config toggle so you only ship the events you want. |
FiresDiscordIntegration.dll into BepInEx/plugins/. Which side(s) need it depends on which features you want β see the table below.BepInEx/config/com.Fire.FiresDiscordIntegration.cfg with every setting commented for you.BepInEx/config/FiresDiscordIntegration/valheim_server_wrapper.bat (the auto-restart wrapper template).[Discord] Enabled = true plus the webhook URLs / bot token you set up below.The DLL auto-detects which side it's running on at ZNet.Awake (it calls IsServer() and routes itself to InitServer() or InitClient()). The config file is only read on the side that needs it β clients don't need to configure anything.
| Feature | Server | Client |
|---|---|---|
| Live server-status panel + restart/stop reactions | β | β |
| In-game shouts β Discord (via webhook) | β | β |
| Discord β in-game chat (plain text shows up) | β | β |
| Per-user Discord role color on the relayed chat line | β | β |
| GIF / image rendering inside the in-game chat overlay | β | β |
| Login snapshots (mod list, errors, warnings, attached log) | β | |
| On-demand log / errors / mods requests via Discord reactions | β | β |
| Crash-detection Discord post | β | β |
| Wrapper bat auto-restart + Discord-triggered restart/stop | β | β |
**Without the DLL on the client, the server sees no log data for that player and skips the snapshot entirely (no false-positive embed, no crash).
A player joining a server that has the mod installed but who doesn't have the mod themselves still works β they just don't contribute a snapshot. The rest of the server-side features (status panel, crash notifications, in-game-shout β Discord) work for everyone regardless.
If you only want outgoing webhooks (events posted to Discord), you don't need a bot at all β just create webhooks on the channels you want to receive each kind of post and paste the URLs into the config.
If you want the server-manager panel, the chat relay back from Discord, the per-user role colors, or the reaction-based log requests, you need a bot. Here's the 5-minute setup:


The token goes into a dedicated file at your Valheim install root (the folder that contains valheim_server.exe) β not into any BepInEx config:
<server folder>/FiresDiscordIntegration_BotToken.cfg
If the file doesn't exist yet, start the server once with the mod installed β it auto-creates an empty template there on first load. Open the file, paste your token after BotToken = , save, restart.
Why it's not in BepInEx/config/: Modman and other profile sharing mehods sync configs when shared, sharing a bot token with ANYONE is a bad idea. The dedicated file lives outside that path so the sync tools never touch it.
The wrapper bat reads the same file to drive the Discord-triggered restart polling, so the bat and the mod stay in sync automatically.
In Discord, User Settings β Advanced β Developer Mode turns on the "Copy ID" right-click option.
Then right-click and Copy ID on:
[Discord] DiscordGuildId[Discord.BotListener] ChatChannelId[Discord.BotListener] StatusChannelId (or ServerManagerChannelId if you want the panel in a separate channel from snapshots)In each channel that should receive event posts: Edit Channel β Integrations β Webhooks β New Webhook β Copy URL. Paste the URL into the matching [Discord.Webhooks] setting:
GeneralWebhookUrl β start / stop / save / hourly summary / daily summaryChatWebhookUrl β relayed in-game chat (so messages show with the player's name + avatar instead of the bot's)AntiCheatWebhookUrl β kick / violation notificationsClientLogWebhookUrl β login snapshots + on-demand log artifactsWebhooks and the bot can post into the same channel β Discord doesn't care.
On first server load the mod extracts valheim_server_wrapper.bat to:
<server folder>\BepInEx\config\FiresDiscordIntegration\valheim_server_wrapper.bat
That's a template. Open it in a text editor and fill in the config block near the top:
SET SERVER_NAME=My Valheim Server (these don't need "")
SET SERVER_PORT=2456
SET SERVER_WORLD=Dedicated
SET SERVER_PASSWORD=changeme
SET SERVER_PUBLIC=1
SET RESTART_DELAY=10
These are the same flags you'd normally pass on the valheim_server.exe command line. Password must be 5+ chars and cannot appear inside the server name.
Then copy the edited bat to your Valheim dedicated-server folder (the one with valheim_server.exe in it). The bat can be renamed to anything β run_my_server.bat, server.bat, whatever β and you can drop a copy of it into multiple server folders if you run several instances on one machine. Each copy reads sentinel + flag paths relative to its own location, so they don't step on each other.
This feature is mostly for server owners running their own server off of a spare pc using windows who dont have ftp setup or a convenient server console... you can stop and restart the server from your phone on discord if the heartbeat stops and the cmd window is still open It does have its own heartbeat falure code to auto restart, but lets face it... its not working as intended yet (future feature maybe)
Then run the bat instead of valheim_server.exe. The bat:
Do not add setlocal enabledelayedexpansion to this bat.(not like you will edit below the restart delay line) The inline PowerShell for polling discord hates it and it mangles the script. The template ships with delayed expansion off for that reason.
The BepInEx/config/com.Fire.FiresDiscordIntegration.cfg file has every setting documented inline β open it for the full list. Highlights:
| Section | Key | Notes |
|---|---|---|
Discord |
Enabled |
Master switch. |
Discord |
DiscordGuildId |
Required for @mention resolution + per-user role colors. |
Discord.Webhooks |
GeneralWebhookUrl / ChatWebhookUrl / AntiCheatWebhookUrl / ClientLogWebhookUrl |
Outgoing webhooks. Empty = that channel disabled. |
Discord.BotListener |
EnableBotListener |
Master switch for everything that needs the bot token. |
| (no key) | FiresDiscordIntegration_BotToken.cfg at server root |
Bot token lives in its own file outside BepInEx/config/ β see step 3 above. |
Discord.BotListener |
ChatChannelId |
Channel the bot reads Discord chat from. |
Discord.BotListener |
StatusChannelId |
Channel where the live status panel lives. |
Discord.ServerManager |
ServerManagerChannelId |
Optional β separate channel for the panel if you don't want it in StatusChannelId. |
Discord.Events |
EnableStatusHeartbeat |
Turn the live panel on/off. |
Discord.Events |
Notify* |
Per-event toggles. Default to sensible "on" values; turn down the noise as you like. |
Discord.ClientLogs |
NotifyClientLoginArtifacts / AttachFullClientLogOnLogin / AttachModListOnLogin / AttachErrorsWarningsOnLogin |
Control what shows up on each login. |
Discord.Appearance |
WebhookDisplayName / WebhookAvatarUrl |
Override the author name / avatar for webhook posts. Empty falls back to the bot's @me username + avatar. |
[Discord]-prefixed lines happens in a Harmony postfix on Chat.OnNewChatMessage β should coexist with chat-channel mods as long as they don't strip the buffer entry before our patch runs.FiresDiscordIntegration_BotToken.cfg at the server root, and the channel IDs from this mod's BepInEx config. Other mods' configs are not touched.The Discord webhook + REST plumbing was originally built inside FiresGhettoNetworking. Split out into this standalone mod so people dont have a mod outside the scope of their networking mod wrapped up in one. decided to actually offer it as a stand alone after working on it for the last few months since I've noticed a few sub par versions surface lately that can't pull the log from discord itself and dont have cool features like gifs XD
MIT β see LICENSE.