You are viewing a potentially older version of this package. View all versions.
JacobsValheim-VikingStoryteller-0.3.0 icon

VikingStoryteller

In-game F8 stats, skills and player snapshots, damage shares, AFK, native game counters and searchable story logs. Optional local HTML overview. No admin powers or automatic chat.

Date uploaded a week ago
Version 0.3.0
Download link JacobsValheim-VikingStoryteller-0.3.0.zip
Downloads 20
Dependency string JacobsValheim-VikingStoryteller-0.3.0

This mod requires the following mods to function

denikson-BepInExPack_Valheim-5.4.2350 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.2350
ValheimModding-JsonDotNET-13.0.4 icon
ValheimModding-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.4

README

Viking Storyteller

Experimental 0.3.0, built and tested against Valheim 1.0.15. Keep a factual record of your Vikings' adventures: kills, deaths, damage contributions, assists, skills, building, crafting, gathering, AFK estimates, biome crossings and exact-creature revenge.

Press F8 in game to open your own server statistics. The package also includes optional tools for a searchable local HTML overview and structured logs for humans and analysis tools.

Storyteller does not write roasts or send automatic chat messages. It supplies the facts for recaps. It grants no admin powers and does not change inventory, loot, combat outcomes or network ownership.

Install and update

Install the same version on the server and participating clients, then restart them. Dependencies remain BepInExPack Valheim 5.4.2350 and JsonDotNET 13.0.4. No additional UI mod or Jotunn dependency is required.

Clients without Storyteller can still join. Version 0.1 clients provide deaths; 0.2 clients provide enhanced combat/activity/action reports. A 0.3 client negotiates 0.3, then falls back to enhanced 0.2 or death-only 0.1. The new stats window, native counters and snapshots require a 0.3 server. Missing collectors receive at most three negotiation attempts; reporting requires acceptance.

The update does not reconstruct unrecorded history. The in-game window reads the cumulative stats file introduced in 0.2; upgrading directly from 0.1 does not backfill that file from old death logs. The HTML tools can still search and summarize retained 0.1 events. Current skill levels are a snapshot, not levels earned on this server. Keep your existing world and Storyteller files when updating normally.

In-game stats window

F8 opens the window; F8, Escape or Close dismisses it. The hotkey is configurable if another mod already uses it. The window blocks normal movement/attack/look input while open and restores control on close. It refreshes from the collector about every 15 seconds while open, with a manual refresh button.

  • Combat: creature killing blows, deaths, assists, player killing blows, actual damage dealt/taken and observed health gains.
  • Adventure: active/AFK/unobserved time, placed pieces, emotes and searchable native/item counters.
  • Skills & Condition: last observed biome, health, stamina, eitr, armor, weight, comfort, weapon, food and skill levels.

These are your world's accumulated collected records, not a live character sheet or necessarily your entire character history. Missing coverage says “Not collected yet.” Snapshots display their timestamp. The server chooses the account from the authenticated connection; a client cannot select another player's account or execute commands through this interface. Up to 384 metric rows are returned, with additional entries retained in server records.

Native gameplay statistics

Observe changes to all 205 actual PlayerStatType categories in the tested build: crafting/upgrades, mining, woodcutting, gathering, food, fishing, farming, taming, pets, building, travel, sailing, portals, boss credit and more. Named dictionaries retain what was picked up, crafted, harvested, eaten or placed. Only the currently connected local character profile is observed.

Counters are read before/after completed game methods and aggregated into bounded batches, normally every 15 seconds. Imported totals never become new progress. A respawn retains the same profile's pending progress; profile, connection and world changes clear it. Native death/kill categories can overlap the independently observed combat records: do not add them together. Increment and set changes remain separate, including decreases/resets.

Native callbacks can miss actions from mods that bypass those game methods. Counters use the game's units. Limited dictionary/batch sizes and backpressure favor gameplay over collecting every event. If optional native hooks fail, combat reporting remains enabled and status reports the missing feature.

Snapshots, skills, sessions and biomes

Snapshots normally arrive every 30 seconds. They include current health/max health, stamina, eitr, armor, carry/max weight, comfort, equipped weapon/quality, food and remaining duration, up to 128 skills, position, biome and sampled movement/condition flags. This is not a full inventory dump and does not inspect Epic Loot item custom data.

The client checks its biome every two seconds and can send an earlier snapshot when it changes. Very brief crossings can be missed. A biome transition does not establish travel method or the exact crossing instant.

Skill changes compare nearby samples of the same character within one connection. The first sample, a different character, clock rollback or a gap over 120 seconds starts a baseline. Newly seen skills require a baseline too. Gains/losses are observed differences; Storyteller does not guess whether a death, command or another mod caused them.

Session events describe when the collector observed a ready reporting connection and its end. Session duration includes AFK and excludes pre-negotiation time; it is not active play time. An abrupt process failure may leave a session without an end record.

Combat contributions and revenge

Each character's network owner observes resulting health changes. Damage measures HP actually removed after mitigation, caps overkill at remaining HP and ignores zero-loss hits. Each player/creature death can contain HP loss, hit count and percentage by source, with a separate killing blow. Unknown attackers and environmental causes remain unknown or explicit cause buckets; damage-over-time attribution only follows identifying game data.

An encounter resets on observed full recovery or after 120 seconds without recorded health loss. Partial healing can make total HP lost exceed maximum health. Percentages use observed encounter damage, not guaranteed complete damage or a causal percentage of blame. Health continuity gaps and out-of-order reports are flagged. Missing owners, restarts, queue limits or mods bypassing observed methods can leave gaps. In-progress encounters do not survive a restart.

An assist means recorded damage in the creature's final observed encounter without its killing blow; each account receives at most one assist per creature, including across respawns. Exact-creature revenge links require matching world and entity IDs, not just the same creature species. Health gains can include food and other HP changes, not just healing abilities.

AFK, emotes, building and removals

AFK defaults to five minutes without observed in-game input. The grace period counts as active. Activity is reported about every 15 seconds; long stalled/suspended intervals are explicitly unobserved rather than assigned to active or AFK time. This is a heuristic, not proof of physical presence. There are no kicks.

The client reads input-activity timing and focused controller activity, never key contents or chat text. Emotes count as activity. Incoming damage and boat movement do not prove someone is present.

Successful emotes and completed Player.PlacePiece calls record the local player, action, time and position. The server also records recognized boats and built structures when their network objects are permanently removed. Removal cannot distinguish destruction, dismantling or admin deletion, and does not identify a culprit. Ordinary client unloading is not permanent removal. Unrecognized/custom object types can be absent.

Server files

Under BepInEx/config/VikingStoryteller/:

  • README.md and schema-v3.json: starting points and field meanings, including supported native statistics.
  • <world-id>-events.jsonl: one versioned event per line, with stable IDs, UTC observation time, game time, source evidence and links.
  • <world-id>-state.json: compact death/revenge correlation and deduplication.
  • <world-id>-stats.json: cumulative per-player totals and latest snapshots.
  • status.json: version, feature readiness, protocol coverage, accepted/rejected/dropped counts and queues.

Events flush about every two seconds. State saves about every 15 seconds and on normal unload. The event file rotates near 20 MiB and retains ten archives per world. Crashes can lose buffered records, and old rotated files can leave history incomplete. Raw local records contain platform account identifiers, names, in-game locations and gameplay; do not publish them.

Optional local HTML and search tools

The tools/ folder contains dependency-free Python 3.10+ tools. These are run separately by the operator; the mod does not launch a web server. Point --server at an ordinary dedicated-server folder, the collector folder itself, or a managed folder containing server/BepInEx/.... Use your numeric world ID from the log filenames.

python data_hub.py --server "/path/to/valheim-server" --world WORLD_ID --output "/path/to/story-reports"
python preview.py --server "/path/to/valheim-server" --world WORLD_ID --output "/path/to/story-reports" --port 8766

The first command creates overview.html, summary.json, report.json, events.jsonl, an indexed events.sqlite, UTC day partitions, per-player exports and schema.json. The HTML is self-contained. The second optionally serves it on 127.0.0.1 only; open http://127.0.0.1:8766/ on the same computer and use Refresh data. No external scripts, analytics or fonts are loaded, and the service has no admin endpoints.

Filter by period, player, event type and text; drill into damage percentages, source lines, skill snapshots and exact-event links. Routine telemetry can be hidden from the timeline. Matching client/server biome observations remain as evidence but count once. The optional managed-server observer is read only when its local maintenance/admin/stories folder exists.

python query.py --database "/path/to/story-reports/events.sqlite" --player "Your Viking" --kind player_death --limit 20
python query.py --database "/path/to/story-reports/events.sqlite" --text Lox --since 2026-09-20T00:00:00-05:00

Derived exports omit platform account IDs and session tokens, retain source file/line references, and distinguish unavailable values from zero. UTC observation time is the query clock; the browser displays local time. Exports reflect retained input files; old day files may remain after rebuilding. Source logs remain untouched. Gameplay exports are private and are not included in this package.

Configuration

JacobsValheim.VikingStoryteller.cfg preserves existing master switches:

  • Send gameplay death reports: master client reporting/negotiation switch, despite its historical name.
  • Collect gameplay death reports: master server collection and own-stats service switch.
  • AFK after seconds without input: default 300, range 60–3600.
  • Report player snapshots: default enabled.
  • Player snapshot interval seconds: default 30, range 15–300; observed biome changes can report sooner.
  • Open stats hotkey: default F8.

Restart the affected game/server after editing configuration. No RCON, API key, external analytics or admin powers are added. The optional Python preview opens only its explicitly requested local port.

Validation and limits

99 C# model checks and 11 reporting tests cover identity, damage math, correlation, AFK, snapshots, native deltas, respawn/profile boundaries, bounded own-stat views, provenance, SQLite search and missing-data handling. Isolated native-game tests exercise real damage/death/removal, patched profile increments, protocol v1/v2/v3 negotiation, serialization, own-stats replies, input gating, and rejection of wrong identities, tokens, replayed or invalid reports. The enhanced HTML was checked in a browser against test-world telemetry.

Normal multi-PC play and visual/input testing of the new in-game window remain necessary. Headless native tests verify its hooks and server data path, not the rendered client window. This is an experimental release; missing or conflicting mods can leave incomplete reports. The server validates identity, world, session token, timestamp, ownership and payload bounds, but client observations are not anti-cheat proof.

Correlation retains 2,000 deaths and up to 8,192 victim IDs. Up to 2,048 encounters and 64 source buckets per encounter are retained. Native buffers cap at 512 names, cumulative native metrics at 4,096 names per player. World rollback can reuse IDs: preserve a backup, then archive/reset corresponding Storyteller state if you deliberately want a fresh reporting history.

MIT source and a Windows build script are included. Build against your own Valheim/BepInEx/Harmony assemblies. Game assemblies and private test/admin tools are not redistributed.

CHANGELOG

0.4.4

  • Support TidyChests 1.4/1.5 quick-deposit signatures while retaining the earlier adapter, and observe its restock path without nested duplicates.
  • Add BestAutoSort 0.6 server-authority deposit/withdrawal observation after persisted commits, with actual quantities, sender attribution and optional Epic Loot metadata.
  • Keep legacy chest-owner observation; reject remote claims against server-owned chests. Cached responses, rejected/uncertain transfers and unresolved actors are not recorded as successful player transfers.
  • Exclude BestAutoSort feeder transactions from player-inventory attribution. Integrations remain optional and never modify inventories, ownership or transaction outcomes.

0.4.3

  • Observe creature drops and successful world pickups with optional Epic Loot metadata and exact-ID origin links.
  • Add item-transfer evidence, including Tidy Chests quick deposit, committed BestAutoSort chest transactions and observed local consumption.
  • Distinguish player-origin pickups, recipe and planting consumption, and automatic FeedLikeGrandma chest removals.
  • Add searchable item/chest summaries, bounded origin caches and separate routine detail routing.
  • Preserve missing-origin and incomplete-transfer evidence rather than inferring where items came from or went.

0.4.2

  • Add Today / Last 7 days / All time leaderboard filters, compact daily-to-monthly history and automatic retained-raw-log period import.
  • Save bounded boss encounter summaries with player damage shares and exact-boss death links.
  • Attribute observed poison/burning effects conservatively; mixed-source pools remain unassigned. Preserve the source of lethal ticks through deferred death processing.
  • Add a configurable F8 leaderboard with shared ranks, bounded replies and honest missing-data handling.
  • Detect optional Epic Loot and report changes to equipped rarity/enchantments; show latest gear in F8.
  • Exclude proven maximum-health clamps from combat damage and avoid per-tick food-decay log noise.
  • Add age/size retention, verified compressed archives and a compact lifetime ledger; archive storage is bounded too.
  • Reduce routine snapshots during detected AFK and suppress initial None-biome transitions.
  • Read compressed archives on demand, use common creature names, and prune stale generated exports.
  • Remove repeated read-only/admin UI notices; keep one concise description statement.

0.4.1 - Previous version data import support

  • Keep the F8 window opaque when focused or clicked.
  • End the GUI event cleanly when switching tabs, filtering counters or closing. Restore shared GUI colors after drawing.
  • Automatically backfill retained 0.1 kills/deaths once per world, preserving newer progress and saving an import marker with the totals. Identify imported portions in F8.
  • Simplify repetitive README text.

0.4.0

  • Group building, mining, woodcutting, crafting, gathering and fishing into ten-minute per-player work summaries with separate action-time sites, evidence-based main activity and partial disconnect/restart recovery.
  • Keep kills, deaths and revenge immediate. Link recent work with explicit time/proximity limits and confidence wording.
  • Separate readable story events from routine detail evidence, retaining searchable provenance and avoiding duplicated totals.
  • Add latest work summaries to F8 Adventure and the HTML overview. Negotiate protocol 4 with compatibility fallbacks to earlier collectors.
  • Preserve existing gameplay settings, optional reporting and read-only statistics. No automatic messages or admin powers.

Changelog

0.3.0

  • Add a configurable F8 in-game stats window with Combat, Adventure, and Skills & Condition tabs. It reads the authenticated player's own server record, refreshes while open, and restores normal input when closed.
  • Observe changes across Valheim's 205 native stat categories, plus named pickup, crafting, harvest, food, building and enemy-credit counters. Keep overlapping native counters separate from directly observed deaths and damage.
  • Add periodic snapshots of health, stamina, eitr, armor, carry weight, comfort, equipped weapon, food and skills. Compare nearby same-connection skill samples without counting imported character history as earned progress.
  • Sample client biomes every two seconds; add reporting-session start/end events. Snapshots normally refresh every 30 seconds and on observed biome changes.
  • Preserve pending native-stat changes across respawn; reset on character-profile or connection changes. Expire invalid entries individually so one stale metric does not invalidate a fresh batch.
  • Explicitly distinguish long unobserved client stalls from active and AFK time. Flag gaps and out-of-order observations in damage breakdowns.
  • Add a searchable HTML overview, SQLite index/query tool, player/day exports, stable event links and a field schema. Avoid double-counting matching client/server biome observations.
  • Keep detailed damage ledgers out of compact correlation saves; cache native reflection fields and bound queues, metrics, snapshots and own-stat replies.
  • Include source, optional report tools, field documentation and validation notes. No admin commands, automatic announcements or external analytics.

0.2.0

  • Add actual HP loss and per-source percentages, assists, persistent player statistics, AFK estimates, emotes, building placements and boat/structure removals.
  • Negotiate enhanced reporting while retaining death-only compatibility with version 0.1.
  • Add a read-only report tool.

0.1.0

  • Initial experimental owner-reported deaths, killing blows and exact-creature revenge correlation.