0012: File structure and tag roster
Status: Accepted. Amends decisions 0009, 0010, and 0011.
Context
The prototype writes one file per match: a match header (version, recorder, players, format, deck, score) followed by shorter game headers. PGN has no concept of a match. A PGN file is "a sequential collection of zero or more PGN games", and every game carries its own complete tag pair section, starting with the Seven Tag Roster. Any game can be extracted from a PGN file, or many combined into one, and each stays valid on its own.
.mtgr aims to stay as close to PGN as realistically possible (CONTRIBUTING.md, design principle 7).
Decision
File structure
- The game is the unit. Every game is a self-contained record: a complete tag pair section followed by the game's content. There is no match header.
- A file holds one or more games. A recorder normally writes one file per match, holding every game of that match. A file holding a single game, or games from several matches, is equally valid.
- Games from the same match share a
Matchtag value and are numbered by theGametag. Match-level facts (the match score, sideboarding between games) are derived from the games sharing aMatchvalue; nothing is stored only at match level.
Tag roster
Every game has these tags, in this order, before any other tags:
Tag Meaning MtgrFormat version, for example "0.3.0". First, so a parser knows the version before reading anything else.EventDescriptive event name, for example "Modern League","Modern Challenge 64","Casual".?if unknown.SiteWhere the game was played: a client such as "MTGO"or"Arena", or a venue and location for paper.?if unknown.DateStart date of the game, YYYY.MM.DD, with?for unknown digits.RoundTournament round. -where rounds do not apply (leagues, casual play);?if unknown; multipart values such as3.1allowed.Player1First player in the match's fixed seat order. Player2Second player in the match's fixed seat order. Result1-0(Player1 won),0-1(Player2 won),1/2-1/2(draw), or*(unfinished, abandoned, or unknown).FormatGame format, for example "Modern".?if unknown.MatchIdentifier shared by every game of the same match. GameGame number within the match, starting at 1. PerspectiveThe player whose seat the game is recorded from (decision 0001). Must equal Player1orPlayer2.Seat order is fixed for the whole match.
Player1andPlayer2do not swap between games. Who plays first in each game is recorded in the game (decision 0010), not in the player tags.Other tags follow the roster. PGN supplemental tags are used where they fit:
UTCDateandUTCTimefor the start time in UTC,Terminationfor why the game ended,Annotatorfor who annotated it. For online sites with no meaningful local time,Dateis the UTC date.Tag names follow PGN: letters, digits, and underscore only, and no tag name appears twice in a game. Extension tag names therefore use an underscore after the prefix (for example
MTGO_Version), not a colon.
Amendments
- Decision 0009, item 2 (header times are absolute ISO 8601 UTC) is replaced by PGN's
Date,UTCDate, andUTCTimetags. - Decision 0010, item 1 (a match is a match header followed by games) is replaced by items 1 to 3 above. Per-game decklists and the rest of 0010 stand.
- Decision 0011, item 1: extension tag names use
PREFIX_Name. Theprefix:form remains for values that are not tag names, such as source card IDs (mtgo:19683).
Rules basis
The Comprehensive Rules (effective 2026-09-25) do not cover file formats; this decision is a format choice.
PGN basis, checked against "Standard: Portable Game Notation Specification and Implementation Guide" (Steven J. Edwards, 1994), https://www.saremba.de/chessgml/standards/pgn/pgn-complete.htm:
- Section 8: "A PGN database file is a sequential collection of zero or more PGN games", each with a tag pair section and a movetext section.
- Section 8.1: tag names are "composed exclusively of letters, digits, and the underscore character", and "the same tag name should not appear more than once in a tag pair section".
- Section 8.1.1: the Seven Tag Roster (Event, Site, Date, Round, White, Black, Result) is mandatory for archival storage, in a fixed order, before any other tags.
- Sections 8.1.1.1 to 8.1.1.7:
?for unknown values;DateasYYYY.MM.DDwith?for unknown digits;Roundas-where inappropriate and multipart values such as3.1;Resultas1-0,0-1,1/2-1/2, or*. - Sections 9.5.2, 9.5.3:
UTCTimeandUTCDategive the start time and date in UTC. - Section 9.8.1:
Termination"describes the reason for the conclusion of the game". Magic termination values are defined in the spec (decision 0010), reusing PGN's values (such asabandoned,time forfeit,unterminated) where they apply.
Alternatives rejected
- A match header with short game headers (the prototype). Rejected: a game cannot be extracted on its own, and match-level data can disagree with the games.
- One file per game. Rejected: sharing a match would mean uploading several files. PGN allows many games per file, and recorders naturally produce a match at a time.
White/Blacktags. Rejected: Magic has no colours, and who plays first changes between games.- A single
Playerstag listing both names (the prototype). Rejected: PGN uses one tag per side, andResultneeds a fixed first and second player to be meaningful. Mtgrafter the roster, as PGN export ordering would put it. Rejected: a parser needs the version before interpreting anything else.
Consequences
- The prototype tags map as follows:
Mtgrstays (first);PlayersbecomesPlayer1/Player2;LocalbecomesPerspective;WinnerandScorebecomeResultper game;StartedbecomesDate,UTCDate,UTCTime;Matchstays;MatchId,GameId,MtgoVersion,SdkVersion,FormatCodebecomeMTGO_-prefixed tags;Recorder,DeckId,DeckName,Clock,Complete,Issue,ResultFromare redefined in the spec or by their own decisions. - The spec must define the order of tags beyond the roster, and the Magic
Terminationvalues.