AGPL-3.0-licensed open source
Nobody has taught an AI to hold a trading card game’s response timing. We are trying.
Public research on card-game AI stops where the opponent starts acting on your turn. This project is building the bounded version of what comes after that — and it is open, so you can check every line of it.
Why this is hard, and why almost nobody has done it
Board games are perfect information. The position is on the table, so it can be searched. Card games break that on the first move: the deck is random and the opponent’s hand is hidden, so “the current position” is not one thing.
The second barrier is the one that decides which games get solved. It is whether the opponent can act on your turn. Hearthstone is where public research has got furthest, and the smaller card pool is the lesser reason. The real one is that there is almost no space for the opponent to act during your turn, which makes a turn a closed sequence you can search to the end. Even there the research does not run against the shipped client; it runs on reimplementations written by the community. Somebody has to write the rules down as a program before there is anywhere to stand, and that is true of every game on this list.
Magic is where that was attempted at the largest scale, and the result deserves to be stated exactly. In 2016 Google DeepMind published Latent Predictor Networks for Code Generation, whose benchmark task was precisely this: read a card’s printed text, emit the code that implements it. The targets were real engines — 11,969 Magic cards from XMage in Java, and 533 Hearthstone cards from hearthbreaker in Python. The best model got 4.8% of the Magic cards exactly right. Its BLEU score was 61.4: the code it wrote looked a great deal like the code it should have written. Those two numbers together are the whole problem. Plausible and correct are different properties, and only one of them runs.
That was ten years ago, and nothing since has claimed the gap closed. What exists is hand-written and community-maintained: XMage and Forge on the Magic side, and Yu-Gi-Oh’s ygo-agent, which can train only because ygopro-core exists underneath it. Recent benchmarks on both games — MTG-Causal-RL and PTCG-Bench — show LLM agents can play a non-zero game, and neither shows a reliable one. Both put a bounded set of archetypes into a fixed observation space to compare methods: a research benchmark, not a world you can self-play inside.
Riftbound sits on the hard side. It has a chain, it passes priority and focus, it has reaction timing — the position changes in between the other player’s actions. Attempts exist: there is at least one open Riftbound simulator with tree-search bindings, and it takes chain resolution head-on rather than avoiding it.
What none of them carries is a conformance suite — a way to check, clause by clause, that the timing implemented is the timing the rules describe, and to say which parts are not implemented at all. Without that, “illegal” and “not modelled” are the same answer. For playing, that is fine; both mean you cannot do it. For anything that is going to learn from the environment or cite it as evidence, it is the difference between a result and a guess.
So the barrier was never that models are not clever enough. The barrier is that somebody has to turn the rules into a program first. What changed since 2016 is who does that. The kernel described on this page was not hand-written by a person: it was written by language-model agents, reviewed by a human, and held to a conformance suite tied to numbered clauses. That is DeepMind’s 2016 task, running as ordinary engineering instead of as a one-shot benchmark — and the suite is what stands in for exact-match against a reference implementation, which matters here because Riftbound has no authoritative implementation to match against.
The other half is that the target no longer has to be twenty thousand cards. Riftbound inherits Magic’s structure — the chain, priority, reaction timing — so the hard mechanic is fully present at a fraction of the printed size. Small enough to finish; structured enough that finishing it means something.
The bet: bounded, and allowed to say it does not know
You do not have to model every card. In practice a format leans on a fraction of what is printed, and the honest engineering translation of that is a bounded scope: implement the mechanics that are actually reached, and mark the rest as not modelled.
That only works under one condition. The system has to be allowed to answer unsupported — and that answer has to be a first-class result, not a swallowed failure. The moment abstention is treated as something to paper over, a bounded scope quietly becomes a system pretending to cover everything, which is worse than not building it.
So the division of labour is fixed: the program owns the mechanical layer and the model reasons inside what that leaves. Not the rules translated into a prompt so a model can read them — the rules executed, so there is a space it cannot argue its way out of.
Exactly where it is today
The goal above is stated at full size. This part is stated exactly, and the two are not the same thing. Every line here is checked by a conformance suite in the repository; if the suite changes, this page is wrong.
- Running Timing and permission kernel. Four turn states, action and reaction timing, priority and focus, pending and finalized chain items. 21 executable cases, each carrying the official clause it encodes.
- Running Typed effect IR. 12 operations plus sequencing, targets, linked effects, lethal cleanup and trigger emission. No card-name conditionals in the interpreter: a card composes from typed operations or it is not modelled, and the second case says so.
- Running Shared result envelope. Five outcomes — supported, illegal, unsupported, decision_required, invalid_input — carried with the coverage limits they were produced under. Two of the three consuming systems are wired to it.
- Partial Card behaviour packs. The contract for per-card clause coverage exists and is validated. No production pack is bundled yet, so for a real deck the honest answer is still “unavailable”, and the tooling says so rather than rounding up.
- Open Legal-action enumeration. Blocked on conformance coverage, not on collecting game records. This is the piece that would let anything downstream search or learn.
- Open A game that finishes. Combat, cleanup, showdown resolution, battlefield control, and — the item everything else waits on — conquer resolution, scoring and win determination. Without a win signal there is nothing to evaluate against, so this one bullet gates every downstream question about how a deck actually performs.
- Open Replay reconstruction and post-game review. Specified in full and deliberately not routed until its activation gates pass.
What made us build a kernel at all
The project started as a derived knowledge base: every entry written from card text and game mechanics rather than summarised from someone else’s guide, which makes entries cheap to regenerate and, on their own, unproven. So all 46 were checked against established play. Three needed no changes.
The most useful catch was not a Legend at all. A ban-list substitution routine swapped a card that hands a rune to every player unconditionally for one that only pays out to whoever holds the point — same domain, same currency, entirely legal, and it would have funded the opponent in a deck that concedes the early board on purpose. A player outside the project found it before any internal check did.
That audit is the reason the kernel exists. Derivation from card faces holds up. The moment the question becomes what a deck is actually trying to do, or what is mechanically legal right now, it stops holding — and the mechanical half of that cannot be derived, only executed.
The line we are aiming at
Go AI is worth its funding because it beats every human. A trading card game is not that shape, and a superhuman player would not be worth much even if someone built one. The line here is deliberately different and, in its own way, harder:
Not to beat people. To teach them correctly — to be able to say what a deck is doing, show what that claim rests on, and stop at the point where it genuinely does not know.
Learning to play turns out to be the easy half. The hard half is building, reading a format, and knowing what to swap when a card is banned — which is exactly where our own substitution routine failed, on a deck it had every legal reason to be confident about. That failure is the shape of the problem, not an embarrassment to be tidied away.
Whether this ever grows into a full rules engine or a learning system, we do not know. What it is accumulating in the meantime — structured state, executable conformance cases, an evidence trail — is the groundwork either of those would need.
Where it came from, and where the output goes
This did not start as an AI project looking for a use. It started as a content problem on Riftbound Chronicle, a Traditional Chinese Riftbound site: writing a deck guide means claiming how a deck actually plays, and there was no way to check such a claim. Players were separately asking for something that could explain a rules interaction and show what the answer rested on. Deck Coach and Rule Consult are those two questions, in that order.
The site is still the first production user, which is what keeps this from being a demo. Deck guides there have their play analysis generated from this knowledge base, each carrying an explicit AI-analysis badge and a link to the methodology. Problems hit while writing guides go back into the skill, and the audit above is what happened the first time that loop was taken seriously.
What would actually help
This is too slow for one person, and the parts that are missing are the parts that need people who know either the game or the engineering. Nothing here needs permission to start — fork it, break it, or open an issue.
- Break a derivation
- The substitution bug was found by a player who knew a deck better than the routine did. That is still the highest-value contribution available, and it needs no code.
- Write mechanics into the kernel
- Typed operations and conformance cases, each tied to an official clause. This is the bottleneck: rule-ification is the whole barrier, and it parallelises.
- Close the loop on a finished game
- Scoring and win determination are the single blocking item above, and they are ordinary, testable work rather than research. Everything that could evaluate a deck is behind them.
- Take the method to another game — Magic included
- Nothing in the approach is Riftbound-specific, and the obvious target is Magic: The Gathering itself. XMage and Forge have implemented Magic for two decades, and neither carries a clause-tied conformance suite — so neither can separate “illegal” from “not modelled”, which is the distinction anything learning from them depends on. Beyond Magic, the last few years have produced more Western trading card games than any decade since the nineties: Flesh and Blood, Star Wars: Unlimited, Disney Lorcana, Sorcery: Contested Realm, Altered, Grand Archive. They differ enormously in how much the opponent may act on your turn, which is the exact axis this project is organised around, and for none of them have we found a public rules kernel with a conformance suite. A second game is the real test of whether the method generalises — and the first one to get a suite makes every one after it cheaper.
What is refused, and what is merely not built yet
A rules engine, an AI agent, and a trained player model are three different things. This began as the second and has since written a bounded piece of the first. There is no trained policy, no self-play corpus, no complete state machine and no full card-effect engine.
That is an ordering, not a refusal. A learned policy is downstream of a correct environment: train one against rules nobody verified and it learns that environment’s bugs — confidently and invisibly, because it really is winning the game it was handed. A conformance suite is not an obstacle placed in front of learning. It is the thing that would make a learned result mean anything at all.
What is actually refused is narrower, and stays refused. It does not play for you. Everything here sits in the preparation phase — building, understanding, practising, reviewing. In the Player 2 mode a human owns hidden information, legality, resolution and every state update, and no engine outcome moves any of that. It publishes no win rates, play rates, tier rankings or matchup tables. An authoritative rules engine, including an official digital client if one ever ships, would make this more useful rather than redundant: that engine serves play, this serves preparation.
Riot’s Digital Tools Policy is open to deck managers and educational tools, and explicit that it does not pre-approve automated rule execution or gameplay simulators. That boundary shaped the design before ambition did: every play suggestion waits on a human to confirm it. It is built for research and educational use, and using it during an event is against tournament rules.