EXEC_MAGICA is a turn-based collectible card game. This repository is its open-source engine, game-playing AI agents, and reproducible benchmark for decision-making under hidden information. The playable game built on it is on itch.io.
EXEC_MAGICA β the reference game built on this engine:
This repository is the engine + AI framework β it does not contain the playable client (the Unity visual layer and its third-party art are not included). The full game built on this engine is on itch.io:
| Platform | Download |
|---|---|
| πͺ Windows | Play on itch.io |
| π macOS | Play on itch.io |
macOS: the build is unsigned. On first launch right-click the app β Open, or allow it in System Settings β Privacy & Security.
To use the engine itself β Use it as a framework Β· Build from source.
- βΆ Play the game
- About
- β Key Results
- Architecture
- Use it as a framework
- AI Models
- Build from source
- Project structure
- Tech stack
- Documentation
- Academic context
- License
This repository is the engine and research framework behind the card game EXEC_MAGICA β a controlled, reproducible environment for studying how AI agents make decisions under hidden information and randomness.
Game rules, keywords, effects and deck presets β RULES.md.
Collectible card games are a hard, realistic testbed: unlike perfect-information games such as chess or Go, a player cannot see the opponent's hand or deck (imperfect information), draws and random effects introduce stochasticity, and the number of possible plays each turn is large. This makes a CCG a natural domain for comparing decision-making algorithms beyond classic search settings.
The framework pits families of agents β from simple heuristics to search-based planners β against each other and measures them with a reproducible self-play pipeline (Elo ratings, win-rate curves, deterministic seeds). The goal is to understand how different approaches trade playing strength against compute budget, and to build a learned evaluation function (a distilled policy + value network) that guides the search.
- π§ Pure-C# game engine β full CCG rules, runs and unit-tests headless (no Unity for logic)
- π€ Pluggable AI agents behind one interface (
IGameActionPolicy) β swap or compare freely - π Reproducible experiments β headless batch self-play, Elo ladder, fixed seeds
- π Build your own frontend β drive the engine via a thin Unity adapter (the reference game is one such frontend)
- π Hearthstone-style ruleset β mana, minions, spells, triggered & on-death effects, summons, silence
- π Data-driven cards β define new cards in JSON with a composable effect system (damage Β· heal Β· buff Β· summon Β· silence Β· keywords)
- 𧬠Self-improving agent β AlphaZero-style loop distils MCTS self-play into a policy + value network across generations
Agents are ranked with a reproducible self-play pipeline β round-robin over six decks, Wilson 95% CIs, BradleyβTerry / Elo anchored at Random = 0, time-matched at 1 s/move. Full ladder & matchup matrix β LADDER.md Β· generational training β GENERATIONS.md Β· agent configs β MODEL_TUNING.md.
6 decks Β· 100 games/pair Β· fatigue-on Β· Elo (Random = 0) Β· time-matched 1 s/move
| Rank | Agent | Elo | 95% CI |
|---|---|---|---|
| π₯ | MCTS + NN (gen3) | 877 | 852β903 |
| 2 | MCTS + NN (gen2) | 860 | 832β884 |
| 3 | MCTS + NN (gen1) | 856 | 828β883 |
| 4 | MCTS + NN (gen0) | 794 | 767β820 |
| 5 | MCTS Β· Random rollout | 741 | 718β767 |
| 6 | MCTS Β· Greedy rollout | 722 | 697β746 |
| 7β9 | NN (gen3) Β· Greedy Β· β¦ | 501 Β· 492 Β· β¦ | |
| 12 | Random (baseline) | 0 | β |
Key findings.
- NN-guided search tops the field β every NN+MCTS generation beats plain MCTS at equal time.
- The self-improvement loop works, then plateaus β a decisive first-generation jump (gen0βgen1, +62 Elo) then diminishing returns; the standalone policy network crosses the tuned-Greedy baseline at gen2.
- A compute-scaling test locates the ceiling β extra search still lifts play on positional decks (Control: 73% at 16Γ time) but not on fast ones (Token: flat ~50%), so the generational plateau is a ceiling of the method (representation/distillation), not of the game.
Full analysis β GENERATIONS.md.
A strict logic / visual split: a pure-C# game engine that runs headless, with a thin Unity adapter as the only bridge to a frontend. This makes the engine unit-testable and lets the same rules drive thousands of reproducible self-play games.
graph TD
R[Random] --> P
G[Greedy] --> P
M[MCTS] --> P
N[NN / NN+MCTS] --> P
P[IGameActionPolicy] -->|GameAction| E
E["GameEngine Β· GameState Β· EffectEngine<br/>(pure C#, headless)"] -->|GameEvent stream| A & T
A["UnityGameEngineAdapter<br/>(thin bridge)"] -.-> F["Your frontend / the reference game<br/>(not in this repo)"]
T["Telemetry Β· BatchRunner β Runs/*.jsonl"]
F -->|player input| A
- Logic Layer (pure C#) β
GameEngine/GameState/EffectEnginehold all rules and emit aGameEventstream. No Unity dependency β runs and tests headless. - AI agents plug in behind one
IGameActionPolicy(Random / Greedy / MCTS). UnityGameEngineAdapteris the thin bridge a frontend drives β see Use it as a framework. The visual client (the reference game) is not in this repo.- Telemetry drives headless self-play via
BatchRunnerβRuns/*.jsonl(see DATA_FORMAT.md).
The engine is frontend-agnostic. To build your own card game on it, drive the
UnityGameEngineAdapter and render the GameEvent stream however you like:
var adapter = new UnityGameEngineAdapter();
adapter.Initialize(initialState); // a GameState (cards + decks)
while (!adapter.State.IsGameOver)
{
var side = adapter.State.ActiveSide;
var legal = adapter.GetLegalActions(side);
var action = policy.ChooseAction(adapter.State, legal, side); // AI, or your player input
var result = adapter.ApplyAction(action); // result.Events β render your view
}- Plug in any AI via
IGameActionPolicyβ Random / Greedy / MCTS are included. - The reference game (on itch.io) is one frontend built exactly this way.
- Full guide β FRAMEWORK.md.
Each agent plugs into the engine behind a single IGameActionPolicy. Full algorithm descriptions and parameters β AGENTS.md.
How they are tuned and frozen β MODEL_TUNING.md; full rankings β LADDER.md.
| Agent | Approach |
|---|---|
| Random | Uniform-random legal moves β the baseline floor. |
| Greedy | One-ply heuristic: picks the move maximizing a tuned board-evaluation. |
| MCTS Β· Random rollout | ISMCTS with random playouts β cheap, many simulations. |
| MCTS Β· Greedy rollout | ISMCTS with greedy playouts β high per-rollout quality. |
| NN | A distilled policy + value network β plays without search. |
| MCTS + NN | ISMCTS guided by the network (policy prior + value at the leaf) β AlphaZero-style. |
The NN and MCTS + NN agents evolve by generation (gen0βgen3), each trained by self-play under the previous generation's champion β see GENERATIONS.md and
ml/train_generations.ipynb. All MCTS agents are ISMCTS (information-set MCTS): each iteration they re-deal the opponent's unplayed cards into a plausible hand/deck split (determinization) and search over the resulting information set. The decklist is assumed known β the same card counting a human could do β but which cards are currently in hand is hidden.
Requires Unity 2021.3.32f1. The optional headless runner (bench/) needs the .NET 8 SDK.
- Clone the repo and open it via Unity Hub (it offers to install 2021.3.32f1).
- The engine + experiment tooling compile out of the box β no extra assets needed.
- Run experiments from the EXEC_MAGICA menu β Ladderβ¦, Run Batchβ¦ and Self-Play Dataβ¦. Each window offers two buttons: Run (Unity) for an in-editor run, and Run (.NET) to launch the standalone headless runner β parallel, all-cores, and non-blocking (Unity stays responsive).
- Run the headless unit tests: Window β General β Test Runner β EditMode.
To build a playable client on top of the engine β Use it as a framework. The reference game is on itch.io.
Prefer a ready binary? Download it from itch.io β no Unity needed.
Assets/
βββ _Project/
β βββ Scripts/
β β βββ Gameplay/LogicLayer/ # pure-C# engine β Engine Β· State Β· Rules Β· Effects Β· Cards Β·
β β β # Events Β· Decks Β· Telemetry Β· AI (agents + StateEncoder + NeuralNet)
β β βββ UnityBridge/ # UnityGameEngineAdapter β the frontend hook
β β βββ Editor/ # research tooling β Batch / Ladder / Self-Play windows,
β β βββ Ladder/ # Elo rating; BenchLauncher launches the .NET runner
β βββ Tests/ # EditMode unit tests (90, headless logic)
βββ Resources/
βββ CardsInfo/ # card data + deck presets (JSON)
βββ CardsLogos/ # AI-generated card art (PNG)
βββ Models/ # distilled networks β InGame/ (shipped) Β· Experimental/ (research)
βββ OpponentModels/ # AI model configs (.asset)
bench/ # standalone .NET headless runner β generate Β· batch Β· ladder Β· duel Β· ceiling
ml/ # training β train.py Β· train_generations.ipynb (self-play distillation)
docs/ # RULES Β· AGENTS Β· GENERATIONS Β· MODEL_TUNING Β· LADDER Β· METRICS Β· DATA_FORMAT Β· FRAMEWORK Β· TESTING
ProjectSettings/ # Unity project config
Packages/ # Unity package manifest + lock
The logic / visual split maps directly to Gameplay/LogicLayer (pure C#, headless, unit-tested)
vs Gameplay/VisualLayer (Unity, no rules β not in this repo). The AI agents live in LogicLayer/AI;
Unity experiment tooling in Scripts/Editor; the standalone parallel runner in bench/; and the
self-play training pipeline in ml/.
| Area | Tech |
|---|---|
| Engine / language | Unity 2021.3.32f1 (LTS) Β· C# |
| Serialization | Newtonsoft.Json (card data, telemetry) |
| Testing | Unity Test Framework (EditMode β headless logic) |
| Data / telemetry | JSON Β· JSON Lines (Runs/) |
| Analysis / ML | Python Β· PyTorch (self-play distillation) Β· matplotlib |
| AI | Information-Set MCTS Β· heuristic & random agents Β· distilled policy+value network (NN, NN+MCTS) |
| Parallel experiments | standalone .NET headless runner (server GC) β same engine, ~10Γ throughput |
π Live API reference β auto-generated from the engine's XML docs (DocFX).
| Document | Contents |
|---|---|
| RULES.md | Game rules, keywords, effects, deck presets |
| AGENTS.md | How each AI agent works and its parameters |
| MODEL_TUNING.md | How agent parameters were tuned and frozen |
| LADDER.md | Rating ladder β Elo and matchup matrix |
| METRICS.md | Metric definitions and formulas |
| DATA_FORMAT.md | Serialized game/session schema for analysis & ML |
| GENERATIONS.md | Per-generation NN training, strength & the ceiling analysis |
| FRAMEWORK.md | How to build on the engine + the .NET experiment runner |
| TESTING.md | The headless unit-test suite (90 tests) |
ml/train_generations.ipynb |
Reproducible generational training pipeline |
EXEC_MAGICA is the software artifact of a Master's thesis at the National Technical University of Ukraine "Igor Sikorsky Kyiv Polytechnic Institute" (NTUU "KPI"), 2026.
Methods and software tools for decision-making by game agents in collectible card games using artificial neural networks
It studies how decision-making approaches β from simple heuristics to search-based planning, and toward a learned value function β cope with the hidden information and stochasticity of a collectible card game. The game doubles as a reproducible benchmark; quantitative results are in MODEL_TUNING.md and LADDER.md.
If you use this work, please cite it β see CITATION.cff.
Released under the MIT License β see LICENSE. This covers the engine, the AI agents, and the bundled (AI-generated) card art.
The playable reference game uses additional third-party assets (art, audio, fonts) that are not part of this repository; they remain under their own licenses and are credited on the game's itch.io page.





