You are viewing a potentially older version of this package. View all versions.
Proudlock_Technology-GsValheimStatsClient-0.2.7 icon

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.

Date uploaded a month ago
Version 0.2.7
Download link Proudlock_Technology-GsValheimStatsClient-0.2.7.zip
Downloads 18
Dependency string Proudlock_Technology-GsValheimStatsClient-0.2.7

This mod requires the following mods to function

denikson-BepInExPack_Valheim-5.4.2333 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.2333

README

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 PlayerProfile stats: 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

  1. Install via r2modman / Thunderstore (depends on denikson-BepInExPack_Valheim).

  2. 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>
    
  3. 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 -world name).


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 if Token is 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). snapshotIdLocal lets a receiver dedupe.
  • Creature / craft / item keys are Valheim localization tokens ($enemy_*, $item_*); stats keys are vh_<PlayerStatType>.
  • reporter is 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 in players[] (just weapons/weaponItems/boss). Source-separate weapon/boss rows by reporter and 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.
  • bossSelfDamage is 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 Url you configure. Only install with a Url/Token you trust.

CHANGELOG

Changelog

0.2.10

  • Fixed grossly inflated (and in other cases under-counted) "materials gathered" totals. Materials now come from Valheim's own cumulative, character-persistent pickup counter (PlayerProfile m_itemPickupStats), filtered to Material-type items, instead of a hook on Inventory.AddItem. The old hook fired on every inventory add, so hauling a resource between chests or recovering it from your tombstone re-counted the whole stack (silver was the worst offender), and it was session-only so anything gathered in a previous play session was lost.

0.2.9

  • Per-life stats (time alive, kills that life, longest life, best streak) now measure a life from the game's own cumulative counters (active play time + kills) instead of the per-session clock, and the start-of-life snapshot persists across logins. A life that spans multiple sessions is now counted correctly, and offline time is excluded. Previously these reset every launch, so a death only logged the final session's slice.

0.2.8

  • Boss-kill detection moved client-side: every kill emits a per-fight event (first blood, top damage, DPS, participants), so the boss-fight chronicle and repeat-kill history work. Fixed the headline boss-kill count.

0.2.7

  • Docs: plain-text README (removed em-dashes and emoji).

0.2.6

  • Docs: dropped em-dashes and emoji from the changelog and wiki for a plainer style.

0.2.5

0.2.4

  • Docs: refreshed README ingest examples (reporter, multiplayer combat-only entries, bossSelfDamage) and bundled this changelog.

0.2.2

  • Fire / poison / spirit damage-over-time is now credited to the player who applied it - works even when several players stack burns on one boss (each application is attributed at the moment of the hit).
  • Capture boss self / environmental damage (lava, the boss's own fire, falls) - damage a boss takes with no player attacker, reported per boss.

0.2.1

  • Emit-on-milestone: a new hardest hit or a kill flushes a post within ~15s instead of waiting the full interval, so big moments show up fast.

0.2.0

  • Multiplayer weapon attribution: whichever client owns a creature now records the damage every player deals to it, attributed to the real attacker and source-separated by reporter. Combat totals are exact across a group, no double-counting.

0.1.9

  • Removed debug logging.

0.1.8

  • Fixed hardest hit. Now hooks Character.RPC_Damage (where backstab/crit/armor are actually applied) instead of the Damage forwarder, so post-backstab numbers are captured correctly.

0.1.7

  • Boss DPS (active engagement timing), specific weapon items (Bronze Sword vs Iron Sword), trophies, and biggest total swing (cleave/AoE).

0.1.6

  • Weapon damage / kills / hardest hit, captured client-side.

0.1.x

  • Initial release: Valheim PlayerProfile counters, skills, per-creature kills, per-item crafts, materials gathered, and per-life death details (cause incl. felled-by-tree, biome, life length, kills before dying).