Skip to main content

mgz-fast

A stripped-down version of aoc-mgz, tailored specifically for the needs of AoE2Insights. It contains only the bare essentials required for fast header and body parsing -- everything else has been removed.

Supported Formats

  • Userpatch 1.5 (.mgz)
  • HD Edition 5.8 (.aoe2record)
  • Definitive Edition (.aoe2record)

Installation

pip install mgz-fast

Usage

Parsing the Header

Extract game metadata like players, map, version, and settings from a recorded game file.

from mgz.fast.header import parse

with open("match.aoe2record", "rb") as f:
    header = parse(f)

print(header["version"])          # Version.DE
print(header["game_version"])     # e.g. "7.7"
print(header["save_version"])     # e.g. 13.34

Players

from mgz.fast.header import parse

with open("match.aoe2record", "rb") as f:
    header = parse(f)

for player in header["players"]:
    print(player["name"])
    print(player["civilization_id"])
    print(player["color_id"])
    print(player["position"])     # {"x": ..., "y": ...}

For Definitive Edition recordings, additional player data is available:

for de_player in header["de"]["players"]:
    print(de_player["name"])
    print(de_player["censored_name"])
    print(de_player["team_id"])

Map and Game Settings

from mgz.fast.header import parse

with open("match.aoe2record", "rb") as f:
    header = parse(f)

print(header["scenario"]["map_id"])
print(header["lobby"]["seed"])
print(header["lobby"]["population"])
print(header["lobby"]["game_type_id"])
print(header["metadata"]["speed"])

Parsing the Body (Actions)

Iterate over in-game operations like player actions, chat messages, and sync ticks.

import os
from mgz.fast import operation, meta
from mgz.fast.header import parse
from mgz.fast.enums import Operation, Action

with open("match.aoe2record", "rb") as f:
    eof = os.fstat(f.fileno()).st_size
    header = parse(f)
    meta(f)

    while f.tell() < eof:
        try:
            op_type, payload = operation(f)
        except EOFError:
            break

        if op_type == Operation.ACTION:
            action_type, action_data = payload
            if action_type == Action.RESIGN:
                print(f"Player {action_data['player_id']} resigned")
            elif action_type == Action.RESEARCH:
                print(f"Player {action_data['player_id']} researched {action_data['technology_id']}")
            elif action_type == Action.BUILD:
                print(f"Player {action_data['player_id']} built {action_data['building_id']}")

        elif op_type == Operation.CHAT:
            print(f"Chat: {payload}")

Extracting Chat Messages

import os
from mgz.fast import operation, meta
from mgz.fast.header import parse
from mgz.fast.enums import Operation

with open("match.aoe2record", "rb") as f:
    eof = os.fstat(f.fileno()).st_size
    header = parse(f)
    meta(f)

    while f.tell() < eof:
        try:
            op_type, payload = operation(f)
        except EOFError:
            break

        if op_type == Operation.CHAT:
            print(payload.decode("utf-8", errors="replace"))

Calculating Game Duration

import os
from mgz.fast import operation, meta
from mgz.fast.header import parse
from mgz.fast.enums import Operation

with open("match.aoe2record", "rb") as f:
    eof = os.fstat(f.fileno()).st_size
    header = parse(f)
    meta(f)

    elapsed_ms = 0
    while f.tell() < eof:
        try:
            op_type, payload = operation(f)
        except EOFError:
            break

        if op_type == Operation.SYNC:
            increment, checksum, data = payload
            elapsed_ms += increment

    minutes = elapsed_ms / 1000 / 60
    print(f"Game duration: {minutes:.1f} minutes")

CLI Tools

Installing mgz-fast also provides four command-line utilities for working with recorded game files.

mgz-parse-header

Parse the header of a recorded game and output it as JSON.

# Parse header and write JSON to file
mgz-parse-header match.aoe2record -o header.json

# Parse with debug logging (useful for troubleshooting)
mgz-parse-header match.aoe2record --debug

# Also works with ZIP archives
mgz-parse-header match.zip -o header.json

mgz-parse-body

Parse the body (actions/events) of a recorded game. Expects an extracted body file as input (see mgz-extract) and outputs JSON Lines to stdout.

# Parse body and print operations as JSON Lines
mgz-parse-body match.body.bin

# Pretty-print each operation
mgz-parse-body match.body.bin --indent 2

mgz-extract

Extract the header and body from a recorded game into separate binary files. The header is automatically decompressed.

# Extract to default paths (<name>.header.bin, <name>.body.bin)
mgz-extract match.aoe2record

# Specify custom output paths
mgz-extract match.aoe2record --header h.bin --body b.bin

mgz-dump

Hex-dump arbitrary byte ranges from a recorded game's header or body. Useful for reverse engineering and debugging.

# Dump first 256 bytes of the decompressed header
mgz-dump match.aoe2record header

# Dump 128 bytes starting at offset 0x2e0
mgz-dump match.aoe2record header --offset 0x2e0 --length 128

# Dump the beginning of the body
mgz-dump match.aoe2record body --offset 0 --length 64

Header Fields Reference

The dictionary returned by parse() contains:

Key Type Description
version Version Game version (USERPATCH15, DE, HD)
game_version str Version string
save_version float Save file version
players list[dict] Player info (name, civ, color, position, diplomacy)
map dict Map dimensions and tile data
scenario dict Map ID, difficulty, scenario filename
lobby dict Seed, population, game type, chat, lock teams
metadata dict Game speed, perspective owner, cheats
de dict|None DE-specific data (extended player info, settings)
hd dict|None HD-specific data

License

MIT

Metadata

Release files for mgz-fast 1.0.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 mgz-fast 1.0.0
File Size Uploaded Provenance
mgz_fast-1.0.0.tar.gz 20.4 MB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mgz-fast 1.0.0
File Interpreter ABI Platform
mgz_fast-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.4 MB

Release files / mgz_fast-1.0.0.tar.gz

Download URL mgz_fast-1.0.0.tar.gz
Size 20.4 MB
Tags Source
SHA-256 checksum
How to use checksums
9d111dfe66a2306c161901546693be97b33d72334a6daa76f42d7a16c047b435
BLAKE2b-256 checksum
How to use checksums
0036f338800447e64614b2abac883091098d9f2ac7fdcad7b47227e9d6ca4db6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / mgz_fast-1.0.0-py3-none-any.whl

Download URL mgz_fast-1.0.0-py3-none-any.whl
Size 30.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
79489857034cce6ff4acd68fdb247241fa5ff5408cccdeb307996b609568257e
BLAKE2b-256 checksum
How to use checksums
4afe5fb1da9950cd9c58f63a19e4e19c9893c25064570e5dbe41527a2ac6b979
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for mgz-fast 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files No provenance

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