Tuesday, August 7, 2007

Bug Hunting: Akroma

Sometimes I wish I was a treasure hunter that searched for Spanish gold hidden deep in the watery deeps but instead I have to search through text (Java programming code). Hi all, this column will be about how I found and fixed a bug in MTG Forge. For some reason Akroma, Angel of Fury can be blocked by non-flyers which truly puzzles me. The original, Akroma, Angel of Wrath, and other flyers have no problems and work correctly. But why is that red Akroma troublesome, who knows? Even as I am writing this I don’t know the answer and now I will go and hunt for bugs.

The first step in any bug hunt is to recreate the board position so that the error is reproducible. If the bug isn’t reproducible, how do you know if it is really fixed? Ok, the board position is setup in Run.java and it proves the computer does indeed block the red Akroma with Enormous Baloth but doesn’t block the regular white Akroma.

Second step, try to check the most brain dead, easiest thing first (i.e. The computer is not working because it is not plugged in). So I checked the card definition of Akroma in the file “cards.txt” I’m looking for any obvious mistakes like misspelling the keyword flying, not capitalize flying, etc… (Keywords like flying must be capitalized in MTG Forge.) WOW, the definition of Akroma looks like below.

Akroma, Angel of Fury
5 R R R
Legendary Creature Angel
no text
6/6
Flying, Trample

As you may or may not notice, keywords should go on separate lines, so it should look like this.

Akroma, Angel of Fury
5 R R R
Legendary Creature Angel
no text
6/6
Flying
Trample

Last step (hopefully), check to see if the computer does not block Akroma. YEAH!!! It is working like it should. It took 6 minutes total, which is a short amount of time to fix one small bug, but most bugs take at least 30 minutes. Hopefully this gives you an indication of the number of hours that I have put into this project.

I thought the problem might be in the file CombatUtil canBlock method, which says whether card A can block card B. This code has gotten a little messy considering keywords like fear, flying, abilities like “this creature cannot block” (Daggerclaw Imp) and unblockable (Phantom Warrior). As well as the cards like Cloud Sprite which can only block other creatures with flying and Skirk Shaman that has some sort of red fear and can only be blocked by artifact or red creatures. Thankfully I didn’t have to change any Java code and the listing for the canBlock method is shown below for interest value.

Well thanks for coming along with me on my little safari. Initially I didn’t know how long it would take. I’ll probably have more adventures in bug hunting. And remember a bug that isn’t fixed is a feature. Tromp the Domains incorrectly counts the number of lands and not land types. Remember that Tromp the Domains is a feature, ok :)

What “features” have you found in MTG Forge?


//taken from CombatUtil
//can “blocker” block attacker?
public static boolean canBlock(Card attacker, Card blocker)
{
if(blocker.getName().equals("Cloud Sprite") && !attacker.getKeyword().contains("Flying"))
return false;

if(attacker.getKeyword().contains("Unblockable"))
return false;

if(blocker.getKeyword().contains("This creature cannot block"))
return false;

if(attacker.getKeyword().contains("Flying"))
{
return blocker.getKeyword().contains("Flying")
blocker.getKeyword().contains("This creature can block as though it had flying.");
}

if(attacker.getKeyword().contains("Fear"))
{
return blocker.getType().contains("Artifact")
CardUtil.getColors(blocker).contains(Constant.Color.Black)
CardUtil.getColors(blocker).contains(Constant.Color.Colorless);
}

if(attacker.getName().equals("Skirk Shaman"))
{
return blocker.getType().contains("Artifact")
CardUtil.getColors(blocker).contains(Constant.Color.Red);
}

return true;
}

4 comments:

Forge said...

Posting code is awkward. The || and && get stripped out, its a HTML thing I know.

//taken from CombatUtil
//can “blocker” block attacker?
public static boolean canBlock(Card attacker, Card blocker)
{
if(blocker.getName().equals("Cloud Sprite") && !attacker.getKeyword().contains("Flying"))
return false;

if(attacker.getKeyword().contains("Unblockable"))
return false;

if(blocker.getKeyword().contains("This creature cannot block"))
return false;

if(attacker.getKeyword().contains("Flying"))
{
return blocker.getKeyword().contains("Flying") ||
blocker.getKeyword().contains("This creature can block as though it had flying.");
}

if(attacker.getKeyword().contains("Fear"))
{
return blocker.getType().contains("Artifact")
||
CardUtil.getColors(blocker).contains(Constant.Color.Black)
||
CardUtil.getColors(blocker).contains(Constant.Color.Colorless);
}

if(attacker.getName().equals("Skirk Shaman"))
{
return blocker.getType().contains("Artifact")
||
CardUtil.getColors(blocker).contains(Constant.Color.Red);
}

return true;
}

Phil said...

This part of the fear logic is not correct:
CardUtil.getColors(blocker).contains(Constant.Color.Colorless);

Here's the comp rules bit:
502.25. Fear
502.25a Fear is an evasion ability.
502.25b A creature with fear can't be blocked except by artifact creatures and/or black creatures. (See rule 309, "Declare Blockers Step.")

And here is counter example:

Ghostflame Sliver can't block dross Dross Golem.

Just trying to set up my IDE so I can have a crack at writting some cards, any tips?

Anonymous said...

Cool article as for me. I'd like to read a bit more about that matter. The only thing this blog misses is a few photos of some devices.
Katherine Kripke
Cell phone blocker

Viagra Online said...

this creature is almost similar to her white cousin, the same abilities and power, for disgrace for this beautiful brunette angelical women her cousin have protection from red so white Akroma doesn't even stop to say "hello cousin"
Generic Viagra Buy Viagra.