ProfilerValheim Zeta
A developer tool for in-game CPU profiling of BepInEx mods. Shows per-mod and per-method CPU load, spike alerts, A/B snapshots comparison and report export. Not intended for regular gameplay.
CHANGELOG
Changelog — ProfilerValheim Zeta
All notable changes to this project are documented here. Format follows Keep a Changelog.
[1.1.0] — 2026-02-22
Added
- Method-level drill-down — click any mod row in the table to expand and see the top-10 heaviest methods inside it with individual
AvgMsandCalls/svalues. - Worst Frame line — orange line on the CPU graph showing a rolling per-frame maximum with slow decay. Helps spot intermittent lag spikes that averages would hide.
- Event Markers — press
MARK EVENTbutton to stamp a visible green vertical marker on the graph at the exact moment of interest (entering a dungeon, opening inventory, starting a fight, etc.). - Alerts tab — automatic spike detection. Any mod exceeding 16.6 ms in a single frame is recorded with timestamp and peak value. Stores up to 100 events, clearable on demand.
- A/B Snapshot Compare tab — save two profiling snapshots and see a colour-coded delta table: red = regression, green = improvement.
- Export to file —
EXPORTbutton writes a full human-readable.txtreport (per-mod stats, method details, alert log) toBepInEx/profiler_reports/. - Search & filter — live text filter on the mod table + toggle to hide mods below 0.1 ms noise threshold.
- Resume Monitoring — after stopping, re-enable data collection without re-scanning all mods. Previously applied hooks remain active.
- Stop Monitoring button — scan/monitor button is now a toggle: green
SCAN MODS→ redSTOP MONITORINGand back. State is always visible.
Fixed
- Namespace mismatch (
ProfilerValheim.ZetavsValheimModProfiler) that prevented the project from compiling. missing using ValheimModProfiler.InstrumentationinIngameProfiler—ProfilerBootstrapperwas not resolving, causing the scan button to flicker back to green in ~0.1 s._isRecordingand_stackwere not[ThreadStatic]— could corrupt self-time calculation under multi-threaded BepInEx hooks.- Silent
catch {}blocks replaced withLogger.LogWarning(...)throughoutProfilerRecorderandProfilerBootstrapper. DrawLine/ graph rendering called outsideEventType.Repaint— caused Unity IMGUI warnings and visual artifacts. All graph drawing is now guarded.GUI.contentColorleak — impact colour was not always reset after coloured rows, causing subsequent rows to inherit the wrong tint.AvgMsinDrawLineusedAtaninstead ofAtan2— incorrect angle for nearly-vertical graph segments.- Dead file
Class1.cswith mismatched namespace removed from project.
Changed
- Snapshot accumulator now publishes a cloned
TotalHistoryand per-mod history arrays — UI can no longer read a buffer whileEndFrameis writing into it. CachedCallsStringnow showsN/s(calls per second) instead of a raw accumulation counter.GlobalHistorynow also maintained asWorstFrameHistorywith slow decay for the worst-frame overlay.
[1.0.0] — 2026-02-22
Added
- Initial release.
- In-game profiler overlay (toggle with
F8). - Per-mod CPU load:
AvgMs,Impact %,Calls/s. - Rolling 300-frame CPU graph with per-mod colour lines and interactive tooltip.
SCAN MODSbutton — applies Harmony hooks toUpdate/FixedUpdate/LateUpdateof all installed BepInEx plugins at runtime.- Self-time measurement via call-stack tracking — child method time is subtracted from the parent, so each mod's cost is shown without double-counting.
- Thread-safe sample collection via
ConcurrentDictionary+Interlocked. - 60/30 FPS reference lines on the graph.
CLEAR GRAPHbutton.