Decoupling the logic code was my attempt at taking some lessons from Web Development, and an attempt to build a game in Unity with a MVC (Model, View, Controller) approach. The most straight forwards way of working with Unity is to attach logic to Game Objects, and this works fairly well in games. However, the MonoBehaviour class that you build everything off is rather heavy, and in previous editions, I ran into performance issues generating temporary clones of objects, both because initializing new objects was costly, but also because the Garbage collector started to thrash.
A side benefit, was that decoupling from Unity meant I could build and extend the game logic in a terminal window on my breaks, without looking like I was playing games. It also means, the game itself could be spun up under anything that could talk to a c# library.
So, the structure in Unity is different from the usual GameObject=>Monobehaviour link, I have a secondary tree of objects, and the front-end pulls states from them so GameObject=>MonoBehaviour=>Card. This is a one way link, the Card object has no knowledge of the state of its related GameObject (although information can be pushed to it). This means that the game objects have no cross communication and are independent of the actual game state. Deleting them just means you can’t see what’s happening.
I also made the code work in distinct phases - not quite a finite state machine, as there is no pathing, but at any time, you could tell exactly what each element was doing, and when the phase changed, I could spit out debug information and gather metrics on how long it took.
The game was now back where I started, however it was decently engineered, and running on a supported platform, so adding new features became easy.
The first addition was the concept of a player; the original game just maintained a score, that got tapped at various points, a second player would have created a nightmare of pathing. But now I had a dedicate phase progression, adding a player was just a new phase, and a new object type. Once multiple player objects were supported, subclassing those to Human and AI, meant I could make player vs player, or player vs AI, and even AI vs AI matches.
All I had to do, was create an AI that could play poker.