A World of Warcraft combat-log damage meter for Linux. A headless daemon tails the combat log; a Wayland layer-shell overlay, a windowed GUI and a TUI are thin clients over a unix socket.
The meter reads WoWCombatLog-*.txt from disk, outside the game process.
No addon, no injection, no screen reading.
- Live meter. Damage, healing, interrupts, crowd control, dispels and deaths, per player, with class colors, crests and spec icons. Updates at 10 Hz.
- Overlay. A wlr-layer-shell surface for Hyprland, sway and other wlroots compositors. It starts with the game, follows the game's workspace, and shrinks to a 1x1 click-through pixel when hidden.
- Segments. Pulls split into encounters and trash the same way the game does. Mythic+ runs group into instance visits with a Σ overall view and keystone par timers. Arena matches are titled as wins or losses.
- Drill-down and comparison. Per-spell breakdowns (hits, crit%, average), death recaps, and a two-player side-by-side with rolling or cumulative DPS graphs marked with trinket uses, procs and consumables. Both panes share one scale, so the comparison stays honest.
- Big logs. A structural index lists the segments of a 300 MB+ log in under a second. A segment is parsed only when opened. Index checkpoints persist across restarts, so only the tail is rescanned.
- History. Every past pull in the log is browsable in the same UI.
The daemon/TUI binary is pure Rust with no system library dependencies:
cargo build --release # everything
cargo run --bin wowdps # daemon + TUI, finds the game install itselfOn Nix, the flake packages the daemon/TUI and exports a Home Manager module and a NixOS module. Each runs the daemon as a user service:
nix build .#wowdps # two derivations: .#wowdps-deps (the dependency
# tree, keyed on Cargo.lock) + the workspace crates
# home-manager:
# imports = [ wowdps.homeManagerModules.default ];
# services.wowdps.enable = true;
# or NixOS:
# imports = [ wowdps.nixosModules.default ];
# services.wowdps.enable = true;The GUI and overlay need pkg-config and libxkbcommon to build, and wayland,
vulkan-loader and libGL at runtime. On NixOS use the dev shell (nix develop
or devenv).
wowdps # follow the configured or discovered logs dir
wowdps --file some-log.txt # follow a specific log
wowdps status # daemon state
wowdps stop # stop the daemon
wowdps-gui # windowed client
wowdps-gui --overlay # layer-shell overlay (the daemon starts this
# itself when the game launches)
wowdps mcp # MCP server over stdio: fight data as tools for
# an LLM. claude mcp add wowdps -- wowdps mcp
wowdps <cmd> [args...] # runs wowdps-<cmd> (next to the binary, else
# on $PATH), e.g. `wowdps extract ...`The daemon starts on demand, is shared by every client, and exits about 10 s
after the last client disconnects. Configuration is
~/.config/wowdps/config.toml: logs_dir, auto_overlay, overlay placement,
Hyprland workspace following, and the history store's history_* keys (fights
persist across sessions as JSON under ~/.local/share/wowdps/history/;
wowdps history sql "…" runs DuckDB over them, and the MCP server exposes the
same store as history, progression, trend, stored_fight, pin_fight
and history_sql). Log discovery checks $WOWDPS_WOW_DIR, then
scans Steam/Proton prefixes for the newest install.
Class crests, spec icons and spell icons come from your own game install,
extracted into ~/.local/share/wowdps/ by tools/gen-icons.sh and
tools/gen-spell-icons.sh (in the dev shell: wowdps gen-icons,
wowdps gen-spell-icons). Without them the meter draws class-colored discs
and no ability icons. Extracted artwork never enters this repository.
The MCP server's talent tools (talent_tree, decode_talents,
encode_talents) read ~/.local/share/wowdps/talents.json, generated by
tools/gen-talent-trees.sh once per game patch.
Press t in the meter window. Paste an in-game talent import string or a
SimulationCraft addon export and the build is drawn the way the game draws
it: class and spec panes, the chosen hero tree between them, gold paths and
rank pills. A SimC export also brings its saved loadouts, gear, bags and
currencies. Pastes are remembered per character, so opening the viewer on a
player's meter row restores their build. Opening it on a player with
COMBATANT_INFO in the log shows their actual logged talents and gear instead.
The pane artwork comes from tools/gen-talent-art.sh; without it the trees
draw on plain panels.
CONTRACT.md is the binding interface spec: parser, meter and index
signatures, the semantic rulings (what counts as damage, absorb attribution,
segment boundaries, pet attribution, class inference) and the wire protocol.
Fixture golden values are computed from the rulings and checked independently
of the parser:
cargo test # workspace: parity, IPC, fixture gates
crates/core/fixtures/verify.sh # gawk recomputes the golden totals
cargo clippy && cargo fmt # clippy denies panics in production codeDependency policy: model has no dependencies; core, proto and daemon
are stdlib only. The TUI uses ratatui and crossterm; the GUI uses iced and
iced_layershell. No tokio, no chrono, no serde outside the GUI.
docs/roadmap.md lists what comes next.
This project was built with Claude Code. Contributions made with an LLM are welcome under the same rules as any other:
- The project's standards apply: idiomatic Rust, the no-panic lint, CONTRACT.md, the dependency policy, and test coverage.
- No copyrighted material. Nothing copied from other codebases, and no running someone else's code through a model to strip its license. You must have the right to contribute what you submit, and it lands under this project's MIT/Apache-2.0 terms.
- You are responsible for what you submit: review it, test it, and be able to explain it.
This project is not affiliated with, endorsed by, or sponsored by Blizzard Entertainment. World of Warcraft® and Blizzard Entertainment® are trademarks or registered trademarks of Blizzard Entertainment, Inc.
The repository contains no Blizzard-owned assets. The generated tables
(class_spells.rs, item_spells.rs, keystone_timers.rs) hold only factual
identifiers (spell ids, class and spec mappings, dungeon timers) extracted from
the user's own game installation. Artwork is likewise extracted locally into
per-machine caches and never committed or distributed. The screenshots above
show the application rendering the author's own combat logs; the small game
icons visible in them remain Blizzard's property and appear only to depict the
software in use.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.





