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.
GsValheimStatsClient
Client companion for the gs dashboard: posts your Valheim combat (weapon & boss damage, DPS, hardest hit), kills, crafts, materials, skills, trophies and per-life deaths. Multiplayer-aware. Pairs with the server-side gs emitter.
| Last updated | 4 days ago |
| Total downloads | 273 |
| Total rating | 0 |
| Categories | Misc Client-side |
| Dependency string | Proudlock_Technology-GsValheimStatsClient-0.2.9 |
| Dependants | 0 other packages depend on this package |
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.2333README
GsValheimStatsClient
A client companion that posts your personal Valheim stats to an HTTP endpoint - by default the self-hosted gs dashboard, but it'll post to any URL you point it at, so you can ingest your stats however you like.
Pairs with the server-side GsValheimStatsEmitter. Both POST to the same endpoint; the dashboard merges them.
Ingesting the data into your own dashboard? See the Data format & self-hosting wiki for the complete payload schema, key conventions, and merge rules.
What it tracks
Read from your own game (the things only the client knows), accumulated and persisted across sessions:
- Profile counters - Valheim's own
PlayerProfilestats: kills, deaths, builds, crafts, jumps, distances (walked / run / sailed / air), trees chopped, items picked up, ... - Skills - every weapon/utility skill level
- Per-creature kills - what you're killing and how much
- Crafts - which items you've crafted (+ counts)
- Materials gathered - Wood, Stone, ores, ...
- Weapons - per weapon category: total damage, kills, hardest single hit, biggest total swing (cleave/AoE)
- Specific weapons - same, per actual item (Bronze Sword vs Iron Sword)
- Boss damage + DPS - your damage to each boss and your active engagement time (DPS = damage / fightSec), incl. fire/poison damage-over-time credited to whoever applied it
- Trophies - collected trophies
- Deaths - cause (incl. felled-by-your-own-tree, Deathsquito), biome, life length, kills before dying
- Multiplayer-aware - whichever client owns a creature records the damage every player deals to it, so combat totals are exact across a group
- Boss self-damage - damage a boss takes from the world (lava / its own fire / falls), with no player to blame
Setup
-
Install via r2modman / Thunderstore (depends on
denikson-BepInExPack_Valheim). -
Launch the game once to generate the config, then edit
BepInEx/config/net.cproudlock.gsvalheimstatsclient.cfg:[General] World = vhserver3 # must match the server's world name EmitIntervalSeconds = 120 # how often it POSTs [Ingest] Url = https://gs.proudtech.net/api/valheim/ingest Token = <bearer token from the dashboard owner> -
Restart Valheim. It POSTs every
EmitIntervalSeconds(and on death).
Stats are filed under
World, so set it to whatever you want to group your runs by (typically the server's-worldname).
Ingesting the stats yourself
The mod just does an authenticated POST of a JSON snapshot. You don't need the gs dashboard - point Url at anything that speaks HTTP.
Request:
POST <Url>Authorization: Bearer <Token>(omitted ifTokenis blank)Content-Type: application/json
Payload (source: "client"):
{
"schemaVersion": 1,
"game": "valheim",
"source": "client",
"reporter": "Erebus",
"world": "vhserver3",
"emittedAtUtc": "2026-06-09T18:00:00Z",
"snapshotIdLocal": "5e2f...",
"players": [{
"name": "Erebus",
"platformId": "-1285113746",
"kills": 312, "bossKills": 1, "deaths": 4,
"longestLifeSec": 7200, "bestKillsBeforeDeath": 150,
"stats": { "vh_EnemyKills": 312, "vh_Builds": 540, "vh_DistanceSail": 4200 },
"skills": [{ "skill": "Knives", "level": 42 }],
"creatureKills": [{ "creature": "$enemy_greydwarf", "kills": 140 }],
"crafts": [{ "item": "$item_club", "count": 3 }],
"materials": [{ "material": "Wood", "amount": 3400 }],
"weapons": [{ "weapon": "Knives", "damageDealt": 493, "kills": 29, "hardestHit": 79, "biggestSwing": 121 }],
"weaponItems": [{ "item": "$item_knife_bronze", "damageDealt": 400, "kills": 25, "hardestHit": 79 }],
"boss": [{ "boss": "Eikthyr", "damageDealt": 1450, "fightSec": 95 }],
"pickups": [{ "item": "$item_trophy_boar", "count": 11 }]
}, {
"name": "Pridetoes",
"weapons": [{ "weapon": "Bows", "damageDealt": 220, "kills": 3, "hardestHit": 60, "biggestSwing": 60 }],
"boss": [{ "boss": "Eikthyr", "damageDealt": 700, "fightSec": 95 }]
}],
"deathEvents": [{
"playerName": "Erebus", "killer": "tree", "biome": "BlackForest",
"posX": 120, "posY": 30, "posZ": -44, "lifeSec": 1800, "killsThisLife": 40,
"tsUtc": "2026-06-09T17:30:00Z"
}],
"bossSelfDamage": [{ "boss": "Fader", "damage": 210 }]
}
Notes:
- All counters are cumulative running totals (idempotent - re-posting the same snapshot is safe).
snapshotIdLocallets a receiver dedupe. - Creature / craft / item keys are Valheim localization tokens (
$enemy_*,$item_*);statskeys arevh_<PlayerStatType>. reporteris who captured this payload. Valheim simulates each creature on the nearest client, so in multiplayer a client also records the combat it witnesses for other players on creatures it owns - those appear as extra, combat-only entries inplayers[](justweapons/weaponItems/boss). Source-separate weapon/boss rows byreporterand sum across reporters: each hit is seen by exactly one owner, so it's an exact total with no double-count. Fire/poison damage-over-time is credited to whoever applied it.bossSelfDamageis per-boss damage taken with no player attacker (lava, the boss's own fire, fall) - a curiosity stat, not attributed to anyone.
Minimal receiver (Node):
import express from 'express';
const app = express();
app.use(express.json({ limit: '1mb' }));
app.post('/api/valheim/ingest', (req, res) => {
if (req.get('authorization') !== 'Bearer my-secret') return res.sendStatus(401);
for (const p of req.body.players ?? [])
console.log(`${p.name}: ${p.kills} kills, ${p.deaths} deaths`);
res.json({ status: 'ok' });
});
app.listen(3001);
Then set Url = http://<host>:3001/api/valheim/ingest and Token = my-secret.
Quick test with curl:
curl -X POST http://localhost:3001/api/valheim/ingest \
-H 'Authorization: Bearer my-secret' -H 'Content-Type: application/json' \
-d '{"game":"valheim","source":"client","world":"test","players":[{"name":"You","kills":1}]}'
Privacy: the mod sends your stats to whatever
Urlyou configure. Only install with aUrl/Tokenyou trust.