Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
ValheimLink
Links this Valheim server to the group's Raid Ledger: pushes your character, explored map and the item catalogue. Server + client; per-player opt-out in the config.
| Date uploaded | 12 hours ago |
| Version | 0.1.5 |
| Download link | GamerSaloon-ValheimLink-0.1.5.zip |
| Downloads | 6 |
| Dependency string | GamerSaloon-ValheimLink-0.1.5 |
This mod requires the following mods to function
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.2351ValheimModding-JsonDotNET
Shared version 13.0.3 of Json.NET from Newtonsoft, net45 package for use in Valheim mods. Maintained by the ValheimModding team.
Preferred version: 13.0.4README
RL Valheim Link
Links this Valheim server to the group's Raid Ledger site: on every profile save (the server's save broadcast, logout, quit) your client sends a summary of your character (equipment, inventory including Equipment & Quick Slots rows, skills, trophies, known items and recipes) and your explored map with pins to the game server, which uploads it to Raid Ledger with the server's own token. Once per game version one admin's client also exports the item catalogue (names + icons from the installed game, so modded items work).
Nothing on your PC talks to the internet: only the dedicated server holds a Raid Ledger token.
Players
Part of the GamerSaloon modpack; nothing to set up. Not join-enforced: without it you simply send
nothing. To opt out, set [Client] OptOut = true in BepInEx/config/RaidLedger.ValheimLink.cfg
(SendCharacter / SendMap turn off one kind). Nothing is sent until you have spawned, and nothing
leaves your PC except through the game server you are playing on.
Server setup (operator)
- Install the same version on the dedicated server (
BepInEx/plugins/RlValheimLink/, three DLLs). The server rejects clients on a different mod version, so keep the server and the modpack in step. - Start it once so
BepInEx/config/RaidLedger.ValheimLink.cfgexists, then set under[RaidLedger]:BaseUrl— your Raid Ledger instance (scheme + host, no trailing slash);ServerId— the id Raid Ledger shows next to the token (the Pelican server id, as digits);ServerToken— the per-server token from Raid Ledger's Pelican panel integration page (press Generate on this server's row; it is shown once). Paste it into the file; it is never written to any log.
- Restart the server. The log (
BepInEx/LogOutput.log) showsRLVL: server half active: … token=setand, a few seconds later,RLVL: PUT blob … → 201 storedfor the world's base map. - Item catalogue: the export is produced by an admin's client (a SteamID64 listed in the
server's
adminlist.txt,Steam_7656…format), once per game version and again when the server's mod set changes. The server asks the first admin who joins; nothing else is needed. To let any player do it, set[Server] ItemsExportBy = anyone.
Operations (operator)
- Token rotated or rejected: uploads halt with
RLVL: uploads HALTED: 401 …and retry every 10 minutes. Paste the new token into the config; it is picked up on the next retry, no restart needed. - Raid Ledger instance rebuilt, moved, or server id changed: nothing to do. The server notices that its upload target changed and re-sends the base map and the item catalogue by itself; players' character and map data re-send on their next save.
- Switching worlds: the base map is rendered once per world and game version (about 20 s of server
ticks on first load) and cached under
BepInEx/RLValheimLink/spool/basemap/. rlvl statusin a client's F5 console (launch option-console) prints what the mod is doing.
Privacy
The server receives: your SteamID64 (from the connection, not from the client), character id and name, equipment, inventory, skills, trophies, known items and recipes, explored-map bitmaps, map pins (type, position, label), and sends them to the operator's Raid Ledger. Pin labels are never logged. Source and the exact wire format: https://github.com/Raid-Ledger-Plugins/rl-valheim-link
CHANGELOG
Changelog
0.2.1 — 2026-10-20
[Server] WorldAllowlist(comma-separated world names, case-insensitive; empty = every world). When the loaded world is not listed the server half stays idle: no base-map render, every client's hello is answered withreject hello: world 'x' is not linked …so a 0.2.1 client sends nothing that session (an older client keeps sending and the server drops it), and nothing is spooled or uploaded. For one dedicated server that is sometimes booted into a test world: the character key has no world in it, so a test-world session would otherwise become the character's latest snapshot in Raid Ledger.- Client: a
rejectwhose reason starts withhello:now stops the session's captures (older servers never send one). [Chests] Dump(dedicated server only, defaulttrue): a diagnostic for the planned chest-inventory capture, on by default (operator ruling: nothing should need a flag;Dump = falseskips it). Two minutes after every start, the server reads every container from the world's ZDOs with the game's ownInventory.Loadand logsRLVL: chestdump[r<run>.c<check>]lines: the keys on a few known chests (items/itemDatahashes), which data shape and whichInventory.Loadvariant decode a 1.0.20 chest (and whether the temporary inventory avoids instantiating item objects), milliseconds per stack, row counts, counts per prefab (duplicates, creator 0, gone, dropped), totals ofDumpMaterials,creator/creatorIndexon personal chests, every container and processing-station prefab with its values, and the 1.0.20-only recipe and station fields.DumpRuns(default 2) andDumpRerunMinutes(default 10) repeat it and report what changed (freshness). Logs only: no upload, no new message kind, no ZDO string contents in the log; it does log chest positions and the player and Steam ids of chest creators and connected players. Each run (two by default, about 2 and about 12 minutes after start) can cause a short server hitch, longer on large worlds; discovery is spread at one prefab query per tick. It never runs in a player's single-player or self-hosted world. Because it uploads nothing it also runs on a world that is not inWorldAllowlistand without a Raid Ledger target. Run 1 logs how long its two single-frame steps took (setup tick,probe tick).- Members that are new in 1.0.20 are read by name through
GameAccess, so a wrong guess shows up as a dump line, never as a failure of the captures.
0.2.0 — 2026-10-19
Bundled release after the first full in-game runs (operator ruling: fewer, better-tested iterations).
- Compatibility by protocol, not version. The server accepts any client that speaks the same RPC
protocol and logs the client's mod version; a server-side update no longer forces a modpack update.
Server.RequireExactModVersion = truerestores the strict check. - Equipment & Quick Slots rows named through its official API (
API.IsSlotCell), so the extra inventory rows arrive asequipment/quickslotinstead ofother. - Progress lines at 25/50/75% for large transfers (the icon atlas is ~6 MB and Steam sends it at ~150 KB/s, about 40 s).
- Includes 0.1.6: the logout flush sends only the small snapshots and leaves large transfers to a live session.
0.1.6 — 2026-10-19
- Fix: logging out while an item-catalogue export was queued lost everything, including the character and map — the multi-megabyte atlas sat ahead of them and the connection closed before any of it drained. At logout/quit the client now sends only the small snapshots (character first, then map) and drops large transfers; the server asks for the catalogue again on the next join. Seen on the operator's second admin join.
0.1.5 — 2026-10-19
- The server notices when its upload target changed (Raid Ledger instance rebuilt or moved, server id or token changed) and forgets its "already uploaded" markers, so the base map and the item catalogue are re-sent without any manual step; dedupe watermarks and pending messages are kept.
- Operator instructions: server setup, item catalogue by admins, token rotation and rebuilt-instance
behaviour on the Thunderstore page;
docs/operations.mdrunbook.
0.1.4 — 2026-10-19
- Fix: captures made on logout or quit were lost — the game saves the profile and closes the connection in the same frame, so chunks queued for later frames never left the client. The client now flushes every queued transfer synchronously (and flushes the socket) when the save is a logout/quit save.
- Fix: the admin check for the items export accepts both
Steam_<id>(Valheim 1.0 list format) and bare SteamID64 entries inadminlist.txt.
0.1.3 — 2026-10-19
- Fix: the client never sent anything on Valheim 1.0.20 — the runtime enforces member visibility, and the
build (compiled against publicized references) called the private
ZRoutedRpc.GetServerPeerID()directly (MethodAccessExceptionevery tick, seen in the operator's client log). Every non-public game member the mod reads now goes through HarmonyAccessToolsinGameAccess.cs(equipment slots, trophies / known items / recipes, skills, minimap bitsets and pins); routed-RPC ids come from public API. - A startup self-check logs
game member access ok|BROKEN, and CI scans the built DLL against an unpublicized reference assembly so a direct private access can never ship again.
0.1.2 — 2026-10-19
-
First version published to Thunderstore as
GamerSaloon-ValheimLink, frommainbyrelease.yml. -
Fix: a spooled blob with no message referencing it yet (the base map, rendered at world load) was never uploaded; blobs now go up on their own, oldest first, before messages. Found on the first real run.
-
No operator URLs in the repository or the built DLL: the
BaseUrlconfig description and the design doc no longer carry an example instance URL (operator ruling). The pinned contract keeps Raid Ledger's own$id, which is theirs to change.
0.1.1 — 2026-10-19
- Build against the game build the operator runs: Valheim 1.0.20 on Unity 6000.0.75 via the
Digitalroot.Valheim.Common.ReferencesandUnityEngine.Modulespackages (ValheimGameLibs stopped at 0.221.4). - Console command registration no longer binds one
ConsoleCommandconstructor signature (1.0.20 added a parameter and the old binding threwMissingMethodExceptionat every Terminal init); it picks theConsoleEventoverload by reflection. - Steam id read through reflection into the game's own Steamworks.NET; no Steamworks reference shipped.
- First real-endpoint findings: the server half renders the 2048² base map in ~21 s on the dedicated server
and queues it; error bodies are
{ code, message }(fixed in 0.1.0's PR 4).
0.1.0 — unreleased
- Contract library (
RlValheimLink.Contract): message model, JSON writer, pre-send validator covering schema.json and every CONTRACT.md §6 refinement, bitset/gzip/base64 encoder, PNG encoder; tests against the pinned golden and invalid fixtures. - Client half: character, map (explored + shared layer + pins) and items (ObjectDB + icon atlas)
captures on
Game.SavePlayerProfile, hello on spawn, per-player opt-out,rlvlconsole command. - Chunked routed-RPC transport (
RLVL_Chunk/RLVL_Control) with caps and per-peer rate limits. - Server half:
RlValheimLink.Core(enricher with socket identity + playerId cross-check + clock clamp, disk spool with latest-wins dedupe and content-addressed blobs, uploader state machine honouring Raid Ledger's codes, budgets, 429 Retry-After, backoff and 401/403 halts, HTTP client with gzip bodies) plus the game glue (peer identity cache, hello → needItems, base-map render once per world and game version). Tested end to end against the mock receiver. - Contract pin refreshed to Raid Ledger main after ROK-1833 (additive: optional
blobon file icons); mock receiver matches the real routes, error codes, rate buckets and quotas. - Thunderstore package name decided:
GamerSaloon-ValheimLink. - Tooling: mock ingest receiver, ajv + C# fixture validation, contract drift check, CI and release workflows, Thunderstore layout.