Skip to main content

Gem — a Dota 2 replay parser for Python

Turn Dota 2 replays into analysis-ready Python data.
Parse Source 2 .dem files offline into typed models, pandas DataFrames, JSON, Parquet, and interactive HTML reports.

PyPI version Python versions CI status Coverage License

Documentation · Quickstart · API reference · Changelog


Install

Gem requires Python 3.10 or newer.

pip install gem-dota

Using another package manager? Run uv add gem-dota or poetry add gem-dota. Parquet export additionally requires pyarrow or fastparquet; see the DataFrame and export reference for current engine notes.

Quickstart

import gem

match = gem.parse("match.dem")

print(f"Score: {match.radiant_score}–{match.dire_score}")
for player in match.players:
    hero = gem.constants.hero_display(player.hero_name)
    print(f"{hero:20} {player.kills}/{player.deaths}/{player.assists}  {player.net_worth:,} NW")

# Convert the same structured result to JSON.
json_payload = gem.to_json(match, indent=2)

Need tables instead?

frames = gem.parse_to_dataframe("match.dem")
players = frames["player_summary"]     # one row per player
series = frames["player_timeseries"]   # sampled gold/XP/net worth
positions = frames["positions"]
combat = frames["combat_log"]

Or use the CLI:

python -m gem match.dem
python -m gem match.dem --format json --output match.json
python -m gem batch replays/ --format parquet --output out/ --workers 4

Why Gem?

🐍 Python-native
Typed match objects plug directly into notebooks, pandas, ML pipelines, and ordinary Python code.
🔎 Replay-first
Analyze local replays without depending on third-party match-history availability.
⚔️ Full-match context
Draft, combat, economy, vision, movement, objectives, items, chat, and fights in one model.
📦 Flexible outputs
Work with dataclasses, DataFrames, JSON, Parquet, batch exports, or a self-contained HTML report.

Gem is named after the Gem of True Sight: it reveals the structured match state hidden inside dense replay bytes. The parser is an independent Python implementation, cross-checked against Manta, Clarity, the OpenDota parser, and replay-derived validation fixtures.

Match reports

Gem can turn a parsed replay into a self-contained interactive report with overview, combat, laning, farming, fight, vision, economy, draft, and movement views.

Gem interactive Dota 2 match report overview
Interactive HTML report generated from a real .dem replay.

Gem interactive ward map at 16 minutes
Vision — scrub through observer and sentry ward activity.
Gem teamfight breakdown with map and combat statistics
Fights — inspect positions, damage, abilities, and reveals.
from gem.reports import write_html_report

write_html_report(match, "match-report.html")

Hero and item icons are optional local assets. See the asset-cache guide for setup and the report API for customization.

What you get

Domain Examples
Match and players Scores, winner, duration, teams, K/D/A, level, GPM/XPM, final net worth
Draft and objectives Picks/bans, towers, barracks, Roshan, Aegis, Tormentor, building status
Combat Normalized combat log, damage/healing, kills, ability and item usage, fights
Economy Gold, XP, net-worth and minute-aligned advantage curves, purchases, buybacks
Map state Player positions, lane heatmaps, wards, smoke groups, courier snapshots
Items Final inventories, neutral-item finds, consumed upgrades, Roshan drops and banner plants
Analysis Nearby heroes, point-in-time lookups, ability levels, smoke lifecycles, vision, Roshan conversion
Exports DataFrames, JSON, Parquet, multi-replay processing, interactive HTML reports

Useful entry points include:

  • gem.parse() → ParsedMatch
  • gem.parse_to_dataframe() / gem.to_json() / gem.to_parquet()
  • gem.parse_many*() for parallel replay batches
  • gem.find_player(), gem.position_at_tick(), and gem.fight_at_tick()
  • gem.fetch_replay() for OpenDota/Valve replay download and decompression

For current complete replays, Gem's minute curves are validated against OpenDota's effective sampling boundaries. Embedded MatchDetails data enables exact postgame duration, damage, healing, GPM, and XPM values. Older or incomplete replays use replay-derived fallbacks. Fields whose absence is meaningful—such as consumed-upgrade flags—remain None; other outputs use the documented defaults for their field type.

Documentation

The hosted documentation covers both the public API and the replay format itself:

New to replay internals? Start with the Bits & Bytes Primer, then continue into the parser and entity-system deep dives.

Performance and scope

Gem is a pure-Python parser optimized for research, batch analysis, and direct use in the Python data ecosystem. Multi-replay APIs distribute work across processes, while bounded Parquet export avoids retaining every completed match at once. The v0.8 performance study records the benchmark method, compatibility checks, and current optimization boundary without claiming an apples-to-oranges win over Go or Java parsers.

Some outputs are necessarily reconstructed:

  • Vision estimation, farming-pattern analysis, and Roshan conversion are experimental evidence layers. Prefer Roshan's raw signed profile and status; the legacy aggregate score and exclusive label are deprecated.
  • Incomplete replays can return partial output, and some exact postgame fields require embedded match details.
  • Reliable versus unreliable gold and Healing Lotus pickups are not available from the replay event stream.
  • Hero/item icons and map imagery are optional assets and are not shipped in the wheel.

See Replay Edge Cases and the experimental-feature guides for the detailed boundaries.

Development

git clone https://github.com/whanyu1212/gem-dota.git
cd gem-dota
uv sync --group dev

uv run pytest
uv run pytest -m "integration and not network"
uv run ruff check src/ tests/
uv run mypy src/gem/

Contributions are welcome. Read CONTRIBUTING.md for the workflow and PR checklist. Parser changes should be checked against the pinned upstream reference revisions listed in CLAUDE.md and accompanied by focused regression tests. Additional tool guidance is available in AGENTS.md.

Acknowledgements

Gem builds on years of open work by the Dota replay community: Manta, Clarity, OpenDota parser, and dotaconstants.

No source code was copied from these projects; they are reference implementations used to understand protocol behavior and validate Gem's independent Python implementation. See THIRD_PARTY_LICENSES for license texts.

Sponsor Gem

Metadata

Release files for gem-dota 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gem-dota 0.11.0
File Size Uploaded
gem_dota-0.11.0.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for gem-dota 0.11.0
File Interpreter ABI Platform
gem_dota-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.6 MB

Release files / gem_dota-0.11.0.tar.gz

Download URL gem_dota-0.11.0.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
f331bcf115838fa94132bb79651d6badce695dfd64c630020f660e0a9637fe0b
BLAKE2b-256 checksum
How to use checksums
d1e42f2a76eb8736aa4ce0d1658cf0100b0ad1898ab4fd96e3cf2d9f16f3a2eb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / gem_dota-0.11.0-py3-none-any.whl

Download URL gem_dota-0.11.0-py3-none-any.whl
Size 1.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
fb67d0b8c60efa36b1613e4be84fb31da79c0d3deb90caedb5a19252ca702a9f
BLAKE2b-256 checksum
How to use checksums
cd88f805515f6b97a56c3504c9297ff71d1b2f9e1817a863b8fc320a006e4715
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.13.0

2 release files

This release

0.11.0 This release

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page