Monday, January 30, 2012

Browsing Forge’s Source Code

Source code is great. Similar to a the relation between a cooking recipe and a cake, source code “creates” a program. I like the think of source code as the secret internal guts of a program that you never get to see. I have not looked at Forge’s source code in a long, long time, so I’m just going to randomly pursue it. (You can view the source code yourself here.)

(A class is just a bunch of related Java statements.)

I’m always drawn to the class Card but I see the class ColorChanger so I’m going to look at that first. ColorChanger is very basic but it lets you change the color of any card. ColorChanger also uses a time stamp to keep track of the color changes. Below is the most important method. I understand most of the code but bIncrease is interesting because it changes the time stamp. I think the time stamp is important because two cards may change all of the other card colors in the game but the card that is played last takes priority and “overrides” any previous cards.
public final long addColorChanges(final String s, final Card c, final boolean addToColors, final boolean bIncrease) 
   if (bIncrease) 

   this.globalColorChanges.add(new CardColor(new ManaCost(s), c, addToColors, false));
   return CardColor.getTimestamp();
The Card class is used everywhere in Forge and I have fond memories of creating it from scratch. Currently the Card class is 8,800 lines long (including blank lines) and you can view it here. The most important methods are:

getName() : returns String
isSick() : returns boolean – Does this creature have summoning sickness?

getOwner() : return Player – Who owns this card?
getController() : return Player – Who is currently using this card?

getManaCost(): returns String represent the cost of this card. Even though not every card has a mana cost, most cards do.

One of the longest methods is hasProperty() which covers many additional sources of information like does this card have one color or multiple colors? Is this card double-faced? Is this card a flip card? Is this card enchanted? Is this card haunted by any other cards?

hasProperty(final String property, final Player sourceController, final Card source)

And finally I will look at IPlayerZone, which implements all of the zones in Magic: battlefield, graveyards, exiled, in hand, or in your library. IPlayerZone is technically an interface and just outlines what methods it need and does not contain any working code. IPlayerZone is just a thin wrapper for ArrayList and has the regular, boring methods like add(Card), remove(Card), size(), isEmpty(), and contains(Card) : boolean. I did not directly create IPlayerZone but I indirectly created it. To easily filter cards I created a different, yet similar class named CardList which easily lets you do common task such as find all elves or Forests in play.

Much of Forge has changed since I worked on it and just browsing through the source code, Forge looks very impressive. Just looking at individual classes is just a glimpse of the program’s overall form and structure but it shows just how many details have to be laboriously spelled out so the computer can process them. And yes I do understand that Forge has its share of errors but Forge really is a work of art.

Forge is the best videogame ever created. (Well next to Minecraft…)

Humble scribe,

Just in case my previous link doesn't work, you can view Forge's Java source code here.


KamiKazeKenji said...

I don't know that much about Java, but the guts of Forge is interesting in itself. I'd love to learn Java soon, if I can find a good way to learn it (I tried a few months ago but it was too convoluted).

I'm glad there's another who shares my opinion of Minecraft (being the best game ever)!

Mikol Faro said...

Hi, I was trying to CO the source (I spent about 4hours to fetch all the libs, still missing jyield).
Suggestion/good practice: when using SVN, everyone should be able to compile the code just after the CO.

Anonymous said...

Miss Urge to feed;
Blood Tribute;

thanks to resolve that fast =D