[{"content":" Placeholder. This page exists to validate the site setup (layout, code highlighting, the series hub). Replace the body with the real write-up.\nMagic: The Gathering has tens of thousands of unique cards, each carrying rules text written in a semi-formal natural language (\u0026ldquo;Oracle text\u0026rdquo;). A first taste of the data we are working with:\ncard = { \u0026#34;name\u0026#34;: \u0026#34;Lightning Bolt\u0026#34;, \u0026#34;oracle_text\u0026#34;: \u0026#34;Lightning Bolt deals 3 damage to any target.\u0026#34;, } To generate new cards with a language model and have them actually parse and resolve, free-form text isn\u0026rsquo;t enough — you need a grammar and a typed representation to constrain the output. That is what mtg-compiler builds: a typed AST, a symbolic DSL, and a cost model. Why each piece is needed is the subject of this series.\n","date":"26 June 2026","permalink":"https://blog.deadgate.fr/mtg-compiler/01-why-compile-mtg/","section":"mtg-compiler","summary":"\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003ePlaceholder.\u003c/strong\u003e This page exists to validate the site setup (layout, code\nhighlighting, the series hub). Replace the body with the real write-up.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eMagic: The Gathering has tens of thousands of unique cards, each carrying rules\ntext written in a semi-formal natural language (\u0026ldquo;Oracle text\u0026rdquo;). A first taste of\nthe data we are working with:\u003c/p\u003e","title":"Why compile Magic: The Gathering?"},{"content":" Placeholder. This page validates Mermaid diagram rendering. Replace the body with the real write-up.\nThe front end turns raw Oracle text into a typed abstract syntax tree:\nflowchart LR A[Oracle text] --\u003e B[Lexer] B --\u003e C[Tokens] C --\u003e D[Parser] D --\u003e E[Typed AST] Each stage gets its own treatment: how the lexer handles reminder text and mana symbols, and how the grammar copes with the long tail of one-off templating while still producing a well-typed tree.\n","date":"26 June 2026","permalink":"https://blog.deadgate.fr/mtg-compiler/02-parsing-oracle-text/","section":"mtg-compiler","summary":"\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003ePlaceholder.\u003c/strong\u003e This page validates Mermaid diagram rendering. Replace the\nbody with the real write-up.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe front end turns raw Oracle text into a typed abstract syntax tree:\u003c/p\u003e\n\u003cdiv class=\"mermaid\" align=\"center\"\u003e\n  \nflowchart LR\n    A[Oracle text] --\u003e B[Lexer]\n    B --\u003e C[Tokens]\n    C --\u003e D[Parser]\n    D --\u003e E[Typed AST]\n\n\u003c/div\u003e\n\n\u003cp\u003eEach stage gets its own treatment: how the lexer handles reminder text and mana\nsymbols, and how the grammar copes with the long tail of one-off templating\nwhile still producing a well-typed tree.\u003c/p\u003e","title":"Parsing Oracle text into a typed AST"},{"content":" Placeholder. Scaffolding for the series. Replace the body with the real write-up.\nThe typed AST round-trips to a compact symbolic DSL — the surface an LLM generates against, then back to an AST that is guaranteed to parse:\n# Oracle text -\u0026gt; AST -\u0026gt; DSL (and back) \u0026#34;Lightning Bolt deals 3 damage to any target.\u0026#34; # ⇣ compile DealDamage(amount=3, target=AnyTarget()) # ⇣ render \u0026#34;(deal-damage 3 any-target)\u0026#34; Because the DSL is a small, closed grammar, generation can be constrained to it — so the model can only emit cards that are well-formed by construction.\n","date":"26 June 2026","permalink":"https://blog.deadgate.fr/mtg-compiler/03-symbolic-dsl/","section":"mtg-compiler","summary":"\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003ePlaceholder.\u003c/strong\u003e Scaffolding for the series. Replace the body with the real\nwrite-up.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe typed AST round-trips to a compact symbolic DSL — the surface an LLM\ngenerates against, then back to an AST that is guaranteed to parse:\u003c/p\u003e","title":"A symbolic, LLM-facing DSL"},{"content":" Placeholder. This page validates KaTeX math rendering. Replace the body with the real write-up.\nOnce a card is a typed tree, we can score it. Model a card\u0026rsquo;s cost as the sum of its effects\u0026rsquo; costs, each weighted by how often it triggers:\n$$ C_{\\text{card}} = \\sum_{i=1}^{n} w_i \\cdot c(e_i) $$where \\( c(e_i) \\) is the learned cost of effect \\( e_i \\). Fitting \\( c \\) to the existing card pool gives a cost surface that generated cards can be checked against — so a new card lands near the power level its mana cost implies.\n","date":"26 June 2026","permalink":"https://blog.deadgate.fr/mtg-compiler/04-effect-cost-model/","section":"mtg-compiler","summary":"\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003ePlaceholder.\u003c/strong\u003e This page validates KaTeX math rendering. Replace the body\nwith the real write-up.\u003c/p\u003e\n\u003c/blockquote\u003e\n\n\n\u003cp\u003eOnce a card is a typed tree, we can score it. Model a card\u0026rsquo;s cost as the sum of\nits effects\u0026rsquo; costs, each weighted by how often it triggers:\u003c/p\u003e","title":"Modeling effect cost"},{"content":"I build things and write up what I learn along the way. This site collects those notes.\nmtg-compiler → #A series on compiling Magic: The Gathering card text into an executable representation — parsing Oracle text, modeling the rules, and turning cards into runnable code.\nMore topics will land here over time.\n","date":null,"permalink":"https://blog.deadgate.fr/","section":"Arthur Baboin","summary":"\u003cp\u003eI build things and write up what I learn along the way. This site collects those notes.\u003c/p\u003e\n\u003ch3 id=\"mtg-compiler-\" class=\"relative group\"\u003e\n      \n    \u003ca href=\"https://blog.deadgate.fr/mtg-compiler/\"\u003emtg-compiler →\u003c/a\u003e \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#mtg-compiler-\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h3\u003e\u003cp\u003eA series on compiling Magic: The Gathering card text into an executable\nrepresentation — parsing Oracle text, modeling the rules, and turning cards\ninto runnable code.\u003c/p\u003e","title":"Arthur Baboin"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/ast/","section":"Tags","summary":"","title":"Ast"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/codegen/","section":"Tags","summary":"","title":"Codegen"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/cost-model/","section":"Tags","summary":"","title":"Cost-Model"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/dsl/","section":"Tags","summary":"","title":"Dsl"},{"content":"mtg-compiler turns the natural-language rules text printed on Magic: The Gathering cards — their Oracle text — into a typed AST and a symbolic, LLM-facing DSL, and back again. That representation is what makes grammar-constrained card generation possible: an LLM emits structured, valid cards instead of free-form text that may not parse or resolve.\nThis series documents the research behind it. The articles are meant to be read in order:\n","date":null,"permalink":"https://blog.deadgate.fr/mtg-compiler/","section":"mtg-compiler","summary":"\u003cp\u003e\u003cstrong\u003emtg-compiler\u003c/strong\u003e turns the natural-language rules text printed on Magic: The\nGathering cards — their \u003cem\u003eOracle text\u003c/em\u003e — into a \u003cstrong\u003etyped AST\u003c/strong\u003e and a \u003cstrong\u003esymbolic,\nLLM-facing DSL\u003c/strong\u003e, and back again. That representation is what makes\n\u003cem\u003egrammar-constrained\u003c/em\u003e card generation possible: an LLM emits structured, valid\ncards instead of free-form text that may not parse or resolve.\u003c/p\u003e","title":"mtg-compiler"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/series/mtg-compiler/","section":"Series","summary":"","title":"Mtg-Compiler"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/mtg-compiler/","section":"Tags","summary":"","title":"Mtg-Compiler"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/overview/","section":"Tags","summary":"","title":"Overview"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/parsing/","section":"Tags","summary":"","title":"Parsing"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/series/","section":"Series","summary":"","title":"Series"},{"content":"","date":null,"permalink":"https://blog.deadgate.fr/tags/","section":"Tags","summary":"","title":"Tags"}]