In-game overlay for TaskBarHero (TBH: Task Bar Hero) — DPS · damage-taken · stage-compare · gear-score · item-stats · farming-planner · box-log · opened-box stats · loot-heatmap · Steam-market price-peek, all toggled from an F1 control center. Built as a BepInEx 6 IL2CPP plugin. Tested on game v1.00.09 (Unity 6 / IL2CPP). UI auto-detects English / 日本語 / 繁體中文 / 简体中文 / Español.
⬇️ Players: just download the zip from Releases — no compiling needed.
🌐 Website: https://tbh-dps-meter.zeabur.app
![]() |
![]() |
| DPS panel (damage you deal) | Damage-taken panel (damage you receive) |
DPS panel:
- Live DPS (5s sliding window) + Peak + Average
- Total damage + encounter duration + wave count
- Damage-type breakdown (melee / projectile / area / summon / DoT / trap, with combined flags)
- Crit rate + crit-damage share
Damage-taken panel:
- Live DTPS (damage per second taken) + Peak + Average
- Total taken + duration + biggest single hit
- Hits (times you were hit) + incoming crit (monsters' crit rate against you)
- Two distribution bars: element attribute (physical/fire/ice/lightning/chaos) and damage type
Press F11 to open the stage-compare panel: it groups your saved runs by stage (per difficulty) and shows the current run against a baseline (fastest clear by default, or a run you pin), with deltas for duration, active vs idle (running) time, avg/peak/crit, attributes, damage distribution and per-wave times — plus the full per-character loadout: equipped gear (with item names & affixes) and skills (with levels), per party member, highlighting what changed vs the baseline. A clear-time trend chart sits on top; click a point to inspect that run. Use ◀ ▶ to browse runs, ≪ ≫ to switch stages, the character tabs to switch hero, and the pin button to set a baseline.
Stage / character / skill / item names follow the in-game language — set the game to English / 日本語 / 繁體中文 / 简体中文 / Español and the panel switches live (no restart needed).
Clear-time trend on top (click a point to inspect that run); below, baseline ∣ this run in aligned columns with green/red deltas, plus the character's gear & skills.
Press F7 for the gear-score panel — a WoW-style power rating for your whole party at a glance. Each item is scored from its rarity + item level + affixes + applied sockets, rolled up per character into a total with an ⚔ attack / ⛨ defence split. Every row shows the item icon, a rarity-coloured name (TBH's 10-tier ladder: Common → … → Immortal → Cosmic), its level, applied-socket pips (◆) and its score. Toggle Detailed to expand each item into its per-effect point breakdown.
Gear is read from your save (affixes & sockets); rarity, item level and icons are resolved from a bundled wiki table keyed by item — so it works offline and survives game updates. Affix names follow the in-game language.
Per-character total + attack/defence split; each item rarity-coloured with icon, level, sockets and score. Detailed mode breaks every item into its scoring parts.
Press F8 for the item-stats panel — it counts everything you're holding across your backpack + warehouse (stash) + trading stash (equipped gear excluded). A single scrollable list shows one row per item (icon + rarity-coloured name + ×N held), with identical items merged. Two rows of filter chips above the list let you slice by rarity and by category — combine them (e.g. Immortal × Ring), click a chip again to clear it, and each chip's count cross-updates with the other active filter.
Rarity, category, name and icon come from a bundled wiki table keyed by item, so it works offline and in all 5 UI languages — and it covers non-gear (materials, boxes) too. The summary line shows bag / warehouse / trade as used / capacity, with warehouse capacity reflecting your active tabs (a full 4-tab warehouse reads 196/196, not 196/343).
One scrollable list, one row per item with icon, rarity-coloured name and held count; rarity and category filter chips on top, counts that cross-update; summary shows bag/warehouse/trade used vs capacity.
Press F6 for a personalized "what should I farm?" ranking of every stage — gold/sec and exp/sec side by side, sortable, with difficulty filter chips. Unlike a static wiki table, it is calibrated to your own build:
- Stages you've cleared use your real measured numbers (green,
Real). - Stages you haven't use the wiki baseline × your personal multiplier (learned from your runs),
with the clear time fit from your measured runs (
time = perHP·HP + perWave·waves) — markedEst.. - An EXP-retention % column reflects the in-game level penalty (your level vs the stage level), so over-/under-leveled stages are ranked honestly — higher stage ≠ always better.
- Build-aware: each run is fingerprinted (gear + affixes + skills + level); only runs from your current build count toward calibration. Change gear and it auto-detects, prompting a re-clear.
A basis line shows what the calibration rests on (runs · stages · level · current vs old build).
Every stage ranked by your real gold/sec & exp/sec; green = measured, grey = estimated from your personal multiplier; the Keep column is the in-game EXP-retention penalty.
Press F5 for the treasure-box log: every box pickup recorded with time · stage · box name. Stage Boss Boxes show in blue and get their own boss-box tally, alongside per-stage counts and a boxes-per-hour rate. A sound plays on every pickup — open the ⚙ settings to toggle it, adjust the volume, test it, or choose your own .wav (a built-in two-note chime by default).
Each box logged with time, stage and name; Stage Boss Boxes in blue with a separate tally.
Press F4 for opened-box stats — what you actually pull when you open boxes. A grade × box-kind matrix (count and %) over your lifetime tally shows the rarity distribution per box type (so you can see which boxes are worth opening), alongside a paged, time-ordered open log.
Press F3 for the loot heatmap — two stacked day × 24-hour grids that reveal when your loot happens: the top grid = box pickups (mirrors the F5 log, blue), the bottom = legendary-or-better opens (from F4, grade ≥ 3, gold-green), with a summary row on the side. A clear-time trend chart at the bottom follows whichever stage is currently selected in the F11 compare panel, so you can line up when you grinded against how fast you were clearing.
Hover an item — in your backpack, a reward popup, anywhere it has a tooltip — and a small box shows its Steam Community Market price: current price, 24h change (波動), median sale price, listings, 24h volume, and a 7-day price curve. Prices come from a cron-built feed refreshed every ~30 min, so no per-player Steam scraping. Middle-click an item to pin the box to it — it stays put while you move the cursor onto the curve, where hovering any point shows that point's time · price · change vs now. Press F4 to enter position-adjust mode and drag the box where you want it. Toggle it from the F1 control center.
![]() |
![]() |
| Hover any item for its Steam Market price | Pin + hover the curve to read each day's price |
Press F1 for the control center — one compact hub that lists every panel as a toggle button (lit when shown, dim when hidden), so you can flip DPS, damage-taken, compare, planner, box-log, opened-box and loot-heatmap on/off from a single place instead of memorizing every hotkey. A tiny live summary (DPS · session time · boxes opened) sits at the top. Shown on launch by default; new panels register themselves automatically. The bottom rows hold the global settings: UI scale, hide-in-menu, and two independent font-size steppers — 大字 (big) for titles, main numbers and list rows, 小字 (small) for dim hints, axis labels and buttons — applied live across every panel.
Panels auto-shrink so they never run off the screen on small or low-resolution displays. Set your own
size with the − UI % + control in the F1 control center, or Ctrl + PageUp / PageDown — applied
to every panel and saved as UI.UIScale. Two separate font-size steppers (大字 / 小字) sit next
to it for the text itself, saved as UI.FontSize and UI.FontSizeSmall.
- F1 — toggle the control center / hub (configurable:
HubUI.ToggleKey) - F9 — toggle the DPS panel (configurable:
ToggleKey) - F10 — toggle the damage-taken panel (configurable:
TakenUI.ToggleKey) - F11 — toggle the stage-compare panel (configurable:
CompareUI.ToggleKey) - F7 — toggle the gear-score panel (configurable:
GearScoreUI.ToggleKey) - F8 — toggle the item-stats panel (configurable:
ItemStatsUI.ToggleKey) - F6 — toggle the farming planner (configurable:
FarmUI.ToggleKey) - F5 — toggle the box log (configurable:
BoxUI.ToggleKey) - F4 — toggle the opened-box stats panel (configurable:
BoxOpenUI.ToggleKey) - F3 — toggle the loot heatmap (configurable:
LootMapUI.ToggleKey) - F4 — enter the price-box position-adjust (drag) mode (configurable:
Price.AdjustKey) - Middle-click an item — pin / unpin the price box to it (then hover the curve to read each day)
- Mouse drag — move a panel (positions saved independently; panels never drag off-screen)
- Reset button (top-right) zeroes the meter; ◀ ▶ browse past-stage records
- PageUp / PageDown — adjust panel opacity; Ctrl + PageUp / PageDown — scale all panels
⚠️ Clicks pass through to the game (the plugin only reads the mouse, it does not capture input), so your character still acts when you click on a panel. This is expected.
- Download
TBH-DpsMeter-vX.Y.Z.zipfrom Releases. - Steam → right-click "TBH: Task Bar Hero" → Manage → Browse local files
(you should see
TaskBarHero.exe). - Extract ALL files from the zip into that folder so
winhttp.dll,doorstop_config.ini,dotnet, andBepInExsit next toTaskBarHero.exe(choose "Yes" to overwrite if asked). - Launch through Steam (launching the exe directly will NOT load the plugin).
- First launch shows a black screen for 1–3 minutes (one-time setup). Then it's normal.
On CrossOver, Wine may load its built-in winhttp.dll instead of the BepInEx proxy, or macOS may
quarantine downloaded files. If no overlay appears and <game folder>\BepInEx\LogOutput.log is not
created, run this from the repo root:
bash scripts/repair-crossover-macos.sh --checkIf the check reports a missing winhttp override or quarantine marker, repair and relaunch through
Steam:
bash scripts/repair-crossover-macos.sh --repair --launchYou usually do not need to specify a bottle; the script scans for the CrossOver bottle containing
TaskBarHero.exe. If you have multiple CrossOver bottles, add --bottle "<your-bottle-name>"; for a
non-standard Steam library, add --game-dir "/path/to/TaskbarHero". --check is read-only.
--repair only clears macOS quarantine metadata and sets the scoped Wine override for
TaskBarHero.exe; it does not change game values or plugin code.
Yes — updating only needs the single DLL. BepInEx itself stays untouched.
Overwrite the new TBH.DpsMeter.dll into:
<game folder>\BepInEx\plugins\TBH.DpsMeter.dll
Close the game completely first — while it is running the DLL is locked and cannot be overwritten. Relaunch through Steam afterward.
File: <game folder>\BepInEx\config\tbh.dpsmeter.cfg (created after the first run)
[General]
Language = Auto # force a language: zh-Hant / zh-Hans / en / ja / es
[UI]
FontFamily = Auto # overlay font fallback; Auto tries CJK-capable fonts first
FontPath = # optional .ttf/.otf/.ttc path, e.g. C:\windows\Fonts\SourceHanSansTC-Regular.otf
On macOS/CrossOver, if overlay panels and charts render but all text is invisible, install Asian Fonts Component into the same bottle as Steam/TBH, then fully stop and restart that bottle. If text is still missing, set UI.FontPath to a CJK-capable font file such as C:\windows\Fonts\SourceHanSansTC-Regular.otf, or place a font under <game>\BepInEx\plugins\fonts\ and point UI.FontPath at it.
Delete from the game folder: winhttp.dll, doorstop_config.ini, .doorstop_version,
dotnet\, and BepInEx\. This fully restores the vanilla game.
dotnet build DpsMeter/DpsMeter.csproj -c Release
# output: DpsMeter\bin\Release\TBH.DpsMeter.dll
copy DpsMeter\bin\Release\TBH.DpsMeter.dll <game>\BepInEx\plugins\
Restart the game through Steam (on this Unity 6 build, launching the exe directly does not inject the BepInEx winhttp proxy).
- Damage dealt: Harmony postfix on
TaskbarHero.Monster.ebj(DamageInfo, bool), filtered to player-side hits viaUnit.b_isHero; readsOriginDamage/IsCritical/DamageType. - Damage taken: Harmony postfix on
TaskbarHero.Hero.ebj(DamageInfo, bool), counting any hit whose attacker is not a hero; readsOriginDamage/IsCritical/DamageType/DamageAttribute. - Wave boundaries: polls
StageManager.stageState(MONSTERSPAWN → BATTLE → REORGANIZATION); resets each MONSTERSPAWN, freezes at REORGANIZATION. - DPS / DTPS math lives in pure-C#
DpsTracker/DamageTakenTracker, unit-tested inTrackerTests.
This plugin injects via BepInEx, only reads damage data, does not modify any game value, and the game is single-player. Nevertheless, any third-party mod / injection tool may violate the game's or platform's (e.g. Steam) Terms of Service and carries a risk of account ban, save corruption, or other loss.
You use this software entirely at your own risk. The author is not liable for any account ban, suspension, data loss, or other direct or indirect damages arising from use of this plugin. If you do not accept these terms, do not use it.
MIT © 2026 WarmBed













