Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

13 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

EXEC_MAGICA

A card-game engine and AI research framework

Unity Platforms License Play on itch.io Thesis API Docs

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 β€” AI vs AI


EXEC_MAGICA β€” the reference game built on this engine (AI-vs-AI spectator)

Screenshots

EXEC_MAGICA β€” the reference game built on this engine:


Gameplay β€” play against an AI opponent.

AI-vs-AI spectator β€” watch two agents play, both hands revealed.

Pre-game setup β€” pick the opponent agent and decks.

Deck editor β€” build and save custom decks.

β–Ά Play the game

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.

Table of Contents

About

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.

Highlights

  • 🧠 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

β˜… Key Results

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.

Rating ladder (top)

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.

Architecture

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
Loading
  • Logic Layer (pure C#) β€” GameEngine / GameState / EffectEngine hold all rules and emit a GameEvent stream. No Unity dependency β†’ runs and tests headless.
  • AI agents plug in behind one IGameActionPolicy (Random / Greedy / MCTS).
  • UnityGameEngineAdapter is 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).

Use it as a framework

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.

AI Models

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.

Build from source

Requires Unity 2021.3.32f1. The optional headless runner (bench/) needs the .NET 8 SDK.

  1. Clone the repo and open it via Unity Hub (it offers to install 2021.3.32f1).
  2. The engine + experiment tooling compile out of the box β€” no extra assets needed.
  3. 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).
  4. 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.

Project structure

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/.

Tech stack

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

Documentation

πŸ“– 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

Academic context

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.

License

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.

About

Headless C# card-game engine + AI research framework: heuristic, ISMCTS, and an AlphaZero-style self-play NN+MCTS agent, benchmarked by a reproducible Elo ladder under imperfect information.

Topics

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages