gem
v0.13.0

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

Data flows top to bottom in a single pass. The schema layer feeds two parallel consumers — event processing and the extractors — which both fan back into assembly.

Entry point gem.parse() · gem.parse_to_dataframe()
Binary decoding Outer demo frames → bits, bytes, and varints
Schema & state Serializer tree, field decoders, string tables, entity deltas
Events Game events & the combat log (S1 + S2)
Extractors Players, objectives, wards, visibility, courier, draft, fights
Assembly Combat aggregation → typed result assembly
Output ParsedMatch → DataFrames · JSON · Parquet

Layers at a glance

Entry points
gem.parse() gem.parse_to_dataframe() gem.parse_to_json() gem.parse_to_parquet()
Binary decoding
binary/stream.py binary/packet.py binary/reader.py
Schema decoding
schema/sendtable/ schema/field_decoder/ schema/field_path/ state/string_table.py state/entities.py
Events
state/game_events.py combat/log.py
Extractors
extractors/players.py extractors/objectives.py extractors/wards.py extractors/visibility.py extractors/courier.py extractors/draft.py extractors/fights.py
Assembly
combat/aggregator.py results/assembly.py
Output
results/models.py · ParsedMatch results/dataframes.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.

Field Type What it contains
players list[ParsedPlayer] One entry per player — KDA, gold/XP series, purchases, runes, buybacks, positions
draft list[DraftEvent] Chronological pick and ban events with hero name and team
combat_log list[CombatLogEntry] Every damage, kill, heal, ability-use, and modifier event
towers / barracks list[TowerKill / BarracksKill] Objective deaths with tick, team, and killer
roshans list[RoshanKill] Roshan kills with kill number and killer slot
tormentors / shrines list[TormentorKill / ShrineKill] Tormentor and Shrine of Wisdom destruction events
wards list[WardEvent] Ward placements with exact map coordinates
fights list[Fight] Detected fight windows with per-player damage, kills, and healing
smoke_events list[SmokeEvent] Smoke activations with grouped heroes and centroid position
hero_visibility_events list[HeroVisibilityEvent] Change-only, per-team visibility states for each canonical player hero
entity_visibility_events list[EntityVisibilityEvent] Identity-safe visibility and lifecycle transitions for networked Dota NPCs
aegis_events list[AegisEvent] Aegis pickups, steals, and denies
courier_snapshots list[CourierSnapshot] Courier state sampled each tick
chat list[ChatEntry] All-chat and team-chat messages
radiant_gold_adv / radiant_xp_adv list[int] Per-minute Radiant gold and XP advantage curves

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