Skip to content

Gem

Gem reads Dota 2 .dem replay files and turns them into structured Python objects — named after the Gem of True Sight, which reveals what is hidden.


What you can do

  • Parse in seconds


    A typical 45-minute replay parses in 2–4 seconds in pure Python — no compiled extensions required.

    import gem
    match = gem.parse("my_replay.dem")
    
  • Full match data


    Players, draft, combat log, wards, objectives, teamfights, couriers, smoke events, aegis, chat — everything in one call.

    Full Match Data →

  • Export anywhere


    Convert to pandas DataFrames, JSON, or Parquet with a single function.

    gem.parse_to_dataframe("replay.dem")
    gem.parse_to_json("replay.dem", indent=2)
    gem.parse_to_parquet("replay.dem", "./out")
    
  • Batch processing


    Parse hundreds of replays in parallel using all CPU cores. Failed replays are captured, not raised.

    gem.parse_many_to_parquet("replays/", "./out", workers=8)
    
  • Exact ward coordinates


    Ward placements carry precise map coordinates extracted from the entity stream — not approximations.

    Ward extractor →

  • CLI included


    Parse, export, and batch-process replays directly from the terminal — no Python code needed.

    python -m gem batch replays/ --format parquet --output ./out
    

Where to start

Jump to the Guides — start with the Quickstart for install-to-KDA in 10 lines, or go straight to Full Match Data for a walkthrough of everything in ParsedMatch.

Read Understanding the Format. It explains the Dota 2 replay binary format from scratch — magic bytes, outer message framing, protobuf payloads, the entity delta system, field path Huffman coding, string tables, and the combat log. Each page builds on the previous.

Go to the API Reference. Every public class and function has a Google-style docstring.


Install

pip install gem-dota
uv add gem-dota

Python 3.10 or later required.