I've been thinking about a tool that doesn't really exist in the YuGiOh community: something that takes an opening hand and maps out every possible line of play as an interactive graph. Not just one optimal line, but the full decision tree — every branch, every choice, every possible end board you can reach from a given five-card hand.
The vision is a web app where you input a hand, hit go, and watch a live graph expand in your browser as the engine explores possible plays. Click any node to highlight the full sequence of actions that led there. Tag end boards as "good" or "dead". Eventually, layer in probability data so you can see how often each branch is actually reachable.
To make this real, I needed two things: a proper game engine that understands YuGiOh rules, and a way to drive that engine programmatically. Today was about getting those two pieces to shake hands.
After some research, the plan came together around two core decisions.
Language: Go. The heart of this tool is a graph explorer that needs to fan out across hundreds or thousands of game state branches simultaneously. Go's goroutines make that kind of concurrency nearly free — you can spawn thousands of lightweight branches without the overhead of OS threads. It also produces a single deployable binary and has straightforward interop with C libraries via CGo, which matters for the next decision.
Engine: ygopro-core. Every major YuGiOh simulator — EDOPro, YGO Omega, Percy — runs on the same underlying C++ game engine called ygopro-core. It handles all the actual rules: card effect resolution, turn structure, priority windows, the works. Crucially, it's open source and exposes a clean C API (OCG_CreateDuel, OCG_DuelProcess, OCG_GetMessage, etc.) that we can call directly from Go via CGo. I looked at YGO Omega as an alternative, but it's a Unity-based client sitting on top of the same engine — so there was no advantage there. The engine itself, specifically edo9300/ygopro-core, is the right target.
On Windows, building C++ projects requires a Linux-like toolchain. The standard solution is m, which gives you GCC, G++, and a package manager (pacman) all in one. After installing MSYS2 and grabbing the necessary packages:
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-cmake \\
mingw-w64-ucrt-x86_64-meson mingw-w64-ucrt-x86_64-ninja \\
mingw-w64-ucrt-x86_64-lua
The key step is adding C:\\msys64\\ucrt64\\bin to the Windows system PATH so that Go's CGo toolchain can find GCC from a regular PowerShell window.
git clone <https://github.com/edo9300/ygopro-core.git>
cd ygopro-core
git submodule update --init --recursive
That last line is critical — the repo has a bundled Lua interpreter as a git submodule. Without initializing it, the build will compile against the wrong Lua headers and fail at link time with a wall of undefined reference errors. Ask me how I know.
The repo uses Meson as its build system, which required a small fix — the dependency name in meson.build uses lua-5.4 (with a hyphen) but the MSYS2 package registers itself as lua5.4 (no hyphen). A one-line sed fixed that. There was also a reference to a group.cpp file that doesn't exist in the current codebase, so that was removed from the source list too.
After those two fixes, Meson configured cleanly. But then the linker failed — it was trying to link against the system Lua shared library, which had symbol mismatches with the bundled Lua headers the source code was compiled against.