Game metadata is the header side of scid::core::Game. It is not a separate aggregate root: Game owns the GameHeader, while GameHeader groups the typed values that identify the event, players, result, ratings, ECO code, and supplemental PGN tags.
The header tag mapping separates structured fields from free-form PGN tags. The Seven Tag Roster fields are represented by typed accessors on Game: event, site, date, round, white, black, and result. Other known tags are also typed when libscid can use them directly: EventDate, player rating tags, ECO, and the FEN tag that creates a non-standard start position.
Supplemental tags remain as TagPair values. This lets the game preserve PGN metadata that libscid does not interpret, without forcing every tag into the typed model. pgn::parseGame() reads both sides of that mapping; pgn::encode() writes the Seven Tag Roster every time and writes supplemental tags when the encode policy allows them.
This diagram expands the metadata model into the public values programmers handle. The important distinction is not whether a value came from PGN; it is whether libscid understands the value enough to store it in a typed field.
GameHeader::event holds the event name, site, round, game date, and event date. The game date is the PGN Date tag; the event date is the optional EventDate tag. Both are stored as dateT, whose year, month, and day fields may be partially unknown. Player stores the display name and one Rating. The rating value zero means unknown, and the rating type names are the suffixes used for tags such as WhiteElo, BlackRapid, or WhiteUSCF.
Game::addTag() and Game::findOrCreateTag() recognise the simple string fields Event, Site, Round, White, and Black. PGN parsing handles the other typed metadata explicitly: dates, result, ratings, ECO, and FEN. Tags outside those known cases remain in GameHeader::tags as supplemental TagPair values and are emitted after the known supplemental tags.