


Author: Skarif
Version: 1.1.0
GitHub: SkarifWW/ProfilerValheim.Zeta
Toggle overlay: F8
⚠️ This is not a gameplay mod.
ProfilerValheim Zeta does not add items, mechanics, or any content to your game.
It is a developer and modder tool designed for CPU profiling, performance analysis,
and debugging of BepInEx plugin assemblies inside a live Valheim session.
If you are a regular player looking to improve FPS - this is not what you need.
ProfilerValheim Zeta is an in-game profiler that instruments other BepInEx mods at runtime using Harmony hooks and measures how much CPU time each mod consumes per frame - broken down to the individual method level.
The key difference from external profilers (like dotTrace or Unity Profiler) is that it runs inside the game, in real gameplay conditions, with your exact mod list loaded, without any separate process or build configuration. You press one button, it scans your installed mods, and immediately starts showing live data.
It was built for situations like:
Update() method is the bottleneck."A rolling 300-frame CPU load graph is drawn at the top of the profiler window.
Total ms, Worst ms, and the name of the heaviest mod at that moment.Press MARK EVENT at any moment during gameplay - a green vertical stamp appears on the graph at that exact frame. Use it to correlate what you were doing with what you see on the graph (entering a dungeon, interacting with a chest, triggering a boss, etc.).
Below the graph is a sortable table of all scanned mods:
| Column | Description |
|---|---|
| Mod Name | Assembly name of the BepInEx plugin |
| Avg CPU | Average self-time per frame in milliseconds |
| Impact | Percentage of total frame budget consumed |
| Calls/s | Number of instrumented method calls per second |
Impact is colour-coded: red above 5%, yellow above 1%.
Click any row in the mod table to expand it and see the top 10 heaviest individual methods within that assembly - with their own AvgMs and Calls/s. This is the feature that turns "mod X is slow" into "method Foo.Update inside mod X is the bottleneck".
Automatic spike detection. Any mod that exceeds 16.6 ms in a single frame (the threshold for dropping one frame at 60 FPS) is recorded in the Alerts log with:
HH:mm:ss)Up to 100 events are stored. The tab label shows the current count. You can clear the log at any time.
Designed for iterative optimisation:
Delta is colour-coded: 🔴 red means the mod got more expensive, 🟢 green means it improved.
Click EXPORT to write the current state to a .txt report file at:
BepInEx/profiler_reports/profiler_YYYY-MM-DD_HH-mm-ss.txt
The report includes the full mod table with method details, all spike alerts, FPS and mod count. Useful for sharing with other developers or attaching to bug reports.
ProfilerValheim Zeta uses Harmony Prefix/Postfix pairs to wrap instrumented methods. When SCAN MODS is pressed, it iterates all loaded BepInEx plugins and applies hooks to:
MonoBehaviour.Update(), FixedUpdate(), LateUpdate() of every component in each plugin.Prefix and Postfix methods of every Harmony patch class found in each plugin assembly.The profiler itself is excluded from scanning to avoid self-measurement.
Self-time is computed correctly: each method tracks how long its children took (via a per-thread call stack) and subtracts that from its own elapsed time. This means if ModA.Update calls ModB.SomeHelper, only ModB.SomeHelper's own time is charged to ModB - not the time ModA spent waiting for it.
All sample collection is thread-safe: ConcurrentDictionary + Interlocked.Add/Exchange ensure no data races even if hooks fire from background threads.
ProfilerValheim.Zeta.dll into BepInEx/plugins/.F8 to open the profiler overlay.ℹ️ Scanning takes a moment depending on how many mods you have installed. The status bar at the top of the window shows progress. You can click STOP SCAN at any time - already-applied hooks remain active.
Every instrumented method call goes through a Prefix and Postfix wrapper. The overhead per call is a few hundred nanoseconds (two Stopwatch.GetTimestamp() calls and some stack operations). On a typical modpack of 30–50 mods this adds up to roughly 0.1–0.5 ms total per frame - visible but not game-breaking for a diagnostic session.
When STOP MONITORING is pressed, recording is disabled at the very first line of every Prefix - the overhead drops to a single branch check, essentially zero.
static constructors and initialization code that runs before Awake is not captured.If you are optimising your own mod, the most useful workflow is:
F8) and hit SCAN MODS.0Harmony.dll bundled with BepInEx; no separate install needed.Update methods - this is expected and intended behaviour.Full source available at github.com/SkarifWW/ProfilerValheim.Zeta.
Issues and pull requests are welcome.
ProfilerValheim Zeta - see inside your modpack, fix what's slow.