Skip to content

Architecture

gem turns a raw .dem binary into structured Python objects in a single pass. This page shows how the modules fit together and what each layer produces.


Pipeline

mermaid
flowchart TD
    A(["gem.parse()  /  gem.parse_to_dataframe()"])

    subgraph BINARY ["Binary decoding"]
        direction LR
        B["stream.py\nouter frames"] --> C["reader.py\nbits & varints"]
    end

    subgraph SCHEMA ["Schema & state"]
        direction LR
        D["sendtable.py\nserializer tree"] --> E["field_decoder.py\ntype dispatch"]
        D --> F["field_path.py\nHuffman paths"]
        G["string_table.py\nkey-value tables"]
        H["entities.py\ndelta updates"]
    end

    subgraph EVENTS ["Events"]
        direction LR
        I["game_events.py"]
        J["combatlog.py"]
    end

    subgraph EXTRACT ["Extractors"]
        direction LR
        X1["players"]
        X2["objectives"]
        X3["wards"]
        X4["courier"]
        X5["draft"]
        X6["teamfights"]
    end

    subgraph ASSEMBLE ["Assembly"]
        K["combat_aggregator.py"] --> L["match_builder.py"]
    end

    O(["ParsedMatch"])
    P(["dict[str, DataFrame]  /  JSON  /  Parquet"])

    A --> BINARY
    BINARY --> SCHEMA
    SCHEMA --> EVENTS
    SCHEMA --> EXTRACT
    EVENTS --> ASSEMBLE
    EXTRACT --> ASSEMBLE
    ASSEMBLE --> O
    O --> P

Layers at a glance

Entry points
gem.parse()gem.parse_to_dataframe()gem.parse_to_json()gem.parse_to_parquet()
Binary decoding
stream.pyreader.pysendtable.pyfield_decoder.pyfield_path.pystring_table.pyentities.py
Events
game_events.pycombatlog.py
Extractors
extractors/players.pyextractors/objectives.pyextractors/wards.pyextractors/courier.pyextractors/draft.pyextractors/teamfights.py
Assembly
combat_aggregator.pymatch_builder.py
Output
models.py · ParsedMatchdataframes.py

Output model

gem.parse() returns a single ParsedMatch. Every field is either a scalar or a list of typed dataclasses — no raw dicts, no untyped payloads.

FieldTypeWhat it contains
playerslist[ParsedPlayer]One entry per player — KDA, gold/XP series, purchases, runes, buybacks, positions
draftlist[DraftEvent]Chronological pick and ban events with hero name and team
combat_loglist[CombatLogEntry]Every damage, kill, heal, ability-use, and modifier event
towers / barrackslist[TowerKill / BarracksKill]Objective deaths with tick, team, and killer
roshanslist[RoshanKill]Roshan kills with kill number and killer slot
tormentors / shrineslist[TormentorKill / ShrineKill]Tormentor and Shrine of Wisdom destruction events
wardslist[WardEvent]Ward placements with exact map coordinates
teamfightslist[Teamfight]Detected fight windows with per-player damage, kills, and healing
smoke_eventslist[SmokeEvent]Smoke activations with grouped heroes and centroid position
aegis_eventslist[AegisEvent]Aegis pickups, steals, and denies
courier_snapshotslist[CourierSnapshot]Courier state sampled each tick
chatlist[ChatEntry]All-chat and team-chat messages
radiant_gold_adv / radiant_xp_advlist[int]Per-minute Radiant gold and XP advantage curves

For the full field listing see the Models reference and Full Match Data guide.