The problem was that TrackableTypes were all global (held in static variables), but kept around state (objLookup maps) that shouldn't be global - e.g. that could contain per game data. Additionally, it seems this state wasn't always getting cleared correctly and thus would cause leaking of memory over multiple games - which would especially be a problem for Simulated AI code which created temporary games for simulation.
This change attempts to fix the issue by moving the storage of objLookup maps to the Tracker object, which corresponds to a single Game. This way, there is no cross-contamination between different games and the state is properly cleaned up when a Game goes away.
The problem was that during copying of SAs, the spabCache was not updated correctly due to the code being in the wrong order. A further problem was that activatingPlayer was not being correctly set on the new abilities, so you would end up referencing a Player from a different Game object from an SA that was in a spabCache, resulting in many previously-simulated Game objects being leaked through this reference chain.
This change fixes both of those problems and also adds a validation function that checks the contents of the spabCache at every game copy.
Its contents were never used and it was actually causing a problem for simulated AI when the current Combat was copied into a simulated game - as it would contain references to tokens that were killed that were no longer in the game and thus caused a mapping exception.
Revert to the original implementation of adding the ability to the Game cache in clone(), but now update this in setHostCard() if the new card comes from a different Game object.
Looks like setHostCard() is being called when the clone gets added to a card. However, previously the SpellAbility was being added to the Game in clone(), which doesn't work if the cloned ability should be part of a different Game - such as in simulation AI code. So, this change moves that to addSpellAbility().
Also fixes a bug in the main game code where if you have Clone try to copy a token with abilities, like an Eldrazi Scion, it would previously not get those abilities.
Adds a test for the game simulation/copy case.