Wednesday, August 13, 2008

Error Checking

Most computer programs have some sort of error checking. In the world of computers, errors are a fact of life. Error checking is complicated because you have to guess where errors might occur.

MTG Forge does some very simple error checking, sometimes also called “sanity check.” This type of error checking just checks for the most outrageous types of errors, like if a creature is being destroyed but that creature is not found. If an error is found, a short message is shown to the user. The user can continue playing MTG Forge if the error is small or the user can restart. Restarting doesn’t fix all of MTG Forge’s errors but it will reset the program. The idea is that hopefully the error was a fluke and it won’t happen again for awhile.

Every computer program could have more error checking. In some computer programs the error checking can be 50 percent of the overall code. Many errors occur when the program is reading or writing a file. File operations are complicated and can generate many different types of errors. File operations may work correctly when the file is small but fail once the file gets bigger.

MTG Forge has an architectural error that causes it to slow down after a few games. I didn’t discover this error until the program was almost finished. Some errors, like this one, are hard to find and impossible to fix. This mistake is like if the foundation of a house was cracked, the foundation is the one of the most important parts of a house. All computer programmers try to write error free code, but errors are bound to occur.


Incantus said...

Hi Forge,

So why does the program slow down as you play? Do you have circular references so that java can't clean up the objects (although i believe that java's garbage collector is sophisticated enough for that). It's sad that you decided to abandon python - i'm finding it really fruitful for doing complicated cards. For example, Lee Sharpe of MTGO said that Profane Command was the most difficult card he recently had to code. Yesterday I tried to implement it in incantus, and this is what it looks like: And it works (alhough i don't have fear implemented yet ;)

Forge said...

Hi Incantus,

Your program looks great, you are very good with user interfaces and your card code is easy to understand. Your Python Profane Command is very readable.

The reason I abandoned writing MTG Forge version 2 in Python is because I had too many questions. If I had a Python programmer at my elbow, I would probably use Python. I am very familiar with Java. I know a ton of trivia about Java and when I have to look something up it makes sense. Python (and any computer language) is great it you know it backwards and forwards.

“So why does the program slow down as you play?”

Because of global variables. I keep calling Phase.nextPhase() and the stack keeps getting bigger and bigger. (This took me forever to figure out.) The stack keeps track of all the previous method calls and as the stack gets bigger MTG Forge gets slower. Basically this is a memory leak in Java and shows why global variables (objects) are bad. If Phase wasn’t a global object the stack would “unwind” when a new Phase object was created. (After thinking about it, I might be able to fix this by creating a new Phase object for each game. Even though Phase is global, creating a new object would let the stack unwind.)

As a side note, a reader (Nantuko) updated MTG Forge to make it look like this screenshot which I think looks great. (Me sent me the code so look for an update soon.)

Incantus said...

Oops, that link should be

Incantus said...

So you call Phase.nextPhase() from within the previous call? Sounds like you have a recursive problem. The easiest fix is to move it to an outside loop:

while game.is_running:

WilLoW said...

Forge, I feel your pain!
But at least, high level languages such as Python and Java exit with nice error messages ;)
I've been struggling with awful errors on my own project... and the PSP doesn't forgive, it just stupidly crashes !

Regarding your memory leak bug, although I guess it's not "that" easy, I think you should limit the number of events you store in your Phase history object...

@Incantus: nice piece of code. Makes me wanna try to implement that card in my game, just to see how complex that would be for me ! (damn, choose 2 ?)

Forge said...

Well fixing Phase.nextPhase() is complicated. Every "regular" phase, like Main 1, Combat, calls Phase.nextPhase(). The "loop" is the whole program.

I tried creating a new Phase object but the program doesn't work. I didn't figure out that MTG Forge slowed down until very late in developement.

Forge said...

I added the worst card of the "Command pick 2 cycle", Incendiary Command. That card really sucks for being a rare.

The reason I programmed it was because I was asked about it during my phone interview with Wizards, which didn't go anywhere.

Gando the Wandering Fool said...

Im not knowledgable about Java at all but couldnt you just clean up the phase object manually at the end of each turn? phase object = null? something like that?

Forge said...

I tried reseting Phase but it breaks the program (nothing works). So version 1 has a fatal error. Lets just hope that your computer has lots of memory, lol.