In a way Forge is very simple. Each part does only one thing. The deck editor reads and writes decks. The card factory creates new cards and Magic zones are only arrays (more specifically Java ArrayLists). The three main classes that do the most work are: Card, SpellAbility, and GameAction.
The card class is fairly easy to explain even though the implementation itself keeps growing. The card class is used wherever a physical card is used in Magic, which includes: in your hand, graveyard, library, exiled, or battlefield. The card class has become complicated because it is hard to keep track of everything that can happen like various counters, equipment, auras, damage that the card has received this turn, mana abilities so they can be copied, along with obscure data like "did this creature attack this turn?" or "did this creature deal damage to an opponent this turn?".
The SpellAbility class is used to represent all spells and abilities and a Card object holds one or more SpellAbility objects. This class hasn't changed much and hasn't grown like the card class. SpellAbility has an abstract method called resolve() which is where the effect of the card takes place, like actually destroying all creatures for Wrath of God.
GameAction does "game actions" like drawing a card or dealing damage. This class does not hold all of the game information, like zones and life points, but it does things like move creatures to the graveyard when they have enough damage or implementing state effects for Glorious Anthem. I created this class out of convenience because I didn't want to copy and paste code for every card that does damage or draws a card. All of Forge's game information like zones and life points are global, public variables which any part of the code can access or change. This was done in order to get things working quickly without a long design period. Generally cards should not access the global, public data and should use GameAction instead.
Even though I designed Forge on-the-fly, the overall design has withstood the test of time as well as the additional complexity of several thousand cards. Forge's design was "good enough" and got things working quickly.
And as always I want to thank the current design team. They have done a great job updating Forge and understanding my wonky, undocumented code.
Keep on forging,