Skip to content

Python replay parsing for Dota 2

Turn Source 2 .dem files into analysis-ready Python data.

gem reads Dota 2 replay files and returns typed match objects, pandas DataFrames, JSON, Parquet, and self-contained HTML reports.

InstallOn PyPI as gem-dotaRuntimePure Python · 3.10+ReadableImplementation you can read end-to-end
bash
pip install gem-dota
bash
uv add gem-dota

Requires Python 3.10+. The import name is gem; the PyPI package is gem-dota.

python
import gem
from gem.constants import hero_display

# Parse a local replay into a typed ParsedMatch object.
match = gem.parse("replay.dem")
print(match.duration_minutes, "min ·", len(match.players), "players")

# Every field is a real Python attribute — inspect players directly.
for p in match.players:
    print(hero_display(p.hero_name), p.net_worth, p.kills, p.deaths)

# Or pull analysis-ready pandas DataFrames in one call.
frames = gem.parse_to_dataframe("replay.dem")
frames["combat_log"].head()

What you can do

Common workflows

python
# Export to analysis formats
frames = gem.parse_to_dataframe("replay.dem")
json_str = gem.parse_to_json("replay.dem", indent=2)
gem.parse_to_parquet("replay.dem", "./out")

# Batch across processes
gem.parse_many_to_parquet(["a.dem", "b.dem"], "./out", workers=8)
bash
# Same workflow from the terminal
python -m gem parse replay.dem --format json --output out.json
python -m gem batch replays/ --format parquet --output ./out --workers 4

Where to start

Project status

gem is published to PyPI as gem-dota. The full parsing pipeline and every extractor are complete and stable. It is a pure-Python parser: the Go (Manta) and Java (Clarity) reference parsers are faster in raw throughput; gem optimizes instead for Python-native ergonomics and an implementation you can read end-to-end.

See the Changelog for the latest parser, validation, and report changes.