Why does copyCard copy the UniqueNumber?
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
19 posts
• Page 1 of 2 • 1, 2
Why does copyCard copy the UniqueNumber?
by Chris H. » 29 Jul 2011, 12:58
In message:
viewtopic.php?f=26&t=787&start=5235#p66537
viewtopic.php?f=26&t=787&start=5235#p66537
Sloth wrote:I can confirm this. Using Momentary Blink to save a creature from Vindicate doesn't work at the moment.Almost_Clever wrote:I used Master Transmuter to bounce an artifact creature targeted by Excommunicate to my hand and returned it to play; however, Excommunicate still put it on top of my library (technically it was a different creature than the one the Excommunicate had targeted).
EDIT: Why does copyCard copy the UniqueNumber? Wouldn't this be fixed without copying it?
-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Why does copyCard copy the UniqueNumber?
by Chris H. » 29 Jul 2011, 12:59
In message:
viewtopic.php?f=26&t=787&start=5235#p66554
viewtopic.php?f=26&t=787&start=5235#p66554
Braids wrote:i am not particularly happy with the way Forge uses the term Card. also, there are too many ways to "copy" a Card. if someone could get a good grasp of these things, i think it would help the other developers.Sloth wrote:. . . Why does copyCard copy the UniqueNumber? Wouldn't this be fixed without copying it?
-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Why does copyCard copy the UniqueNumber?
by Chris H. » 29 Jul 2011, 13:00
In message:
viewtopic.php?f=26&t=787&start=5250#p66566
viewtopic.php?f=26&t=787&start=5250#p66566
Sloth wrote:I agree. We should at least split:Braids wrote:i am not particularly happy with the way Forge uses the term Card. also, there are too many ways to "copy" a Card. if someone could get a good grasp of these things, i think it would help the other developers.Sloth wrote:. . . Why does copyCard copy the UniqueNumber? Wouldn't this be fixed without copying it?
1. The card fully defined by name.
2. The card in a collection (with set and image info).
3. The card in a game.
I think using three classes that each "extend" the former would be helpful. (Maybe these posts should be moved to the developer corner).
-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Why does copyCard copy the UniqueNumber?
by Sloth » 29 Jul 2011, 13:03
Thanks for moving this Chris.
Maybe we can start with an answer for the headline.
Maybe we can start with an answer for the headline.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Why does copyCard copy the UniqueNumber?
by Chris H. » 29 Jul 2011, 13:17
You are welcome Sloth. For this topic I took the easy way out and did a quick copy and paste.
It looks like I can move topics far easier than individual messages. I might explore this in more detail at some point.
It looks like I can move topics far easier than individual messages. I might explore this in more detail at some point.

-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Why does copyCard copy the UniqueNumber?
by friarsol » 29 Jul 2011, 13:42
I don't think we necessarily need to copy over the UniqueNumber from copyCard. The moveTo() functions are returning the new card, so as long as whatever calls moveTo() uses the returned Card for any further calculation/manipulation we should be fine.
I just cleaned up some unnecessary member variables in Card. I've also made a list of how we could split up the class, along with some commentary:
I just cleaned up some unnecessary member variables in Card. I've also made a list of how we could split up the class, along with some commentary:
- CardData | Open
- private Map<String, Object> triggeringObjects = new TreeMap<String, Object>();
private ArrayList<Trigger> triggers = new ArrayList<Trigger>();
private ArrayList<String> intrinsicAbility = new ArrayList<String>();
// (SOL: I don't think we need Static Ability Strings AND StaticAbilities, just the Abilities should be fine)
private ArrayList<String> staticAbilityStrings = new ArrayList<String>();
private ArrayList<String> intrinsicKeyword = new ArrayList<String>();
private ArrayList<String> type = new ArrayList<String>();
// (SOL: I don't think ManaAbilities necessarily need their own ArrayList)
private ArrayList<SpellAbility> spellAbility = new ArrayList<SpellAbility>();
private ArrayList<Ability_Mana> manaAbility = new ArrayList<Ability_Mana>();
private ArrayList<StaticAbility> staticAbilities = new ArrayList<StaticAbility>();
// (SOL: CanPlay() Should handle along with StaticAbilities that effect players
private boolean unCastable;
private boolean levelUp = false;
// (SOL: Flashback and Unearth can be converted to have an ActivatingZone probably)
private boolean flashback = false;
private boolean unearth = false;
private boolean madness = false;
private boolean suspend = false;
// (SOL: Why do we have both baseAttack and baseAttack String? Can everything just use Card_PT now?)
private int baseAttack = 0;
private int baseDefense = 0;
private ArrayList<Card_PT> newPT = new ArrayList<Card_PT>(); // stack of set power/toughness
private int baseLoyalty = 0;
private String baseAttackString = null;
private String baseDefenseString = null;
// (SOL: owner/controller are game specific, but might cause issues if not available here)
private Player owner = null;
private Player controller = null;
private String name = "";
private String imageName = "";
private String rarity = "";
private String text = "";
private String manaCost = "";
// (SOL: More things I'd love to see moved somewhere else)
private String echoCost = "";
private String madnessCost = "";
private Map<String, String> SVars = new TreeMap<String, String>();
private String ImageFilename = "";
private ArrayList<Ability_Triggered> zcTriggers = new ArrayList<Ability_Triggered>();
- CardCollectionData | Open
- private long value;
private ArrayList<SetInfo> Sets = new ArrayList<SetInfo>();
private String curSetCode = "";
- CardGameData | Open
- private long timestamp = -1; // permanents on the battlefield
private static int nextUniqueNumber;
private int uniqueNumber = nextUniqueNumber++;
private ArrayList<String> extrinsicKeyword = new ArrayList<String>();
private ArrayList<String> HiddenExtrinsicKeyword = new ArrayList<String>(); //Hidden keywords won't be displayed on the card
private ArrayList<String> prevIntrinsicKeyword = new ArrayList<String>();
// (Note: equipping and enchanting should just be Card not ArrayList<Card>
private ArrayList<Card> attached = new ArrayList<Card>();
private ArrayList<Card> equippedBy = new ArrayList<Card>(); //which equipment cards are equipping this card?
//equipping size will always be 0 or 1
private ArrayList<Card> equipping = new ArrayList<Card>(); //if this card is of the type equipment, what card is it currently equipping?
private ArrayList<Card> enchantedBy = new ArrayList<Card>(); //which auras enchanted this card?
//enchanting size will always be 0 or 1
private ArrayList<Card> enchanting = new ArrayList<Card>(); //if this card is an Aura, what card is it enchanting?
private ArrayList<String> prevType = new ArrayList<String>();
private ArrayList<String> ChoicesMade = new ArrayList<String>();
// (SOL: This seems to be used with Modal spells, but I'm not sure why it's a List of strings)
private ArrayList<String> Targets_for_Choices = new ArrayList<String>();
// (SOL: I wonder if we should combine these "tracking" variables into a Map of Lists)
private ArrayList<Object> rememberedObjects = new ArrayList<Object>();
private ArrayList<Card> imprintedCards = new ArrayList<Card>();
private Card championedCard = null;
private CardList devouredCards = new CardList();
private Map<Card, Integer> receivedDamageFromThisTurn = new TreeMap<Card, Integer>();
private Map<Card, Integer> dealtDamageToThisTurn = new TreeMap<Card, Integer>();
private Map<Card, Integer> assignedDamageMap = new TreeMap<Card, Integer>();
private boolean drawnThisTurn = false;
private boolean tapped;
private boolean sickness = true; //summoning sickness
private boolean token = false;
private boolean copiedToken = false;
private boolean copiedSpell = false;
private boolean creatureAttackedThisTurn = false;
private boolean creatureAttackedThisCombat = false;
private boolean creatureBlockedThisCombat = false;
private boolean creatureGotBlockedThisCombat = false;
private boolean dealtDmgToHumanThisTurn = false;
private boolean dealtDmgToComputerThisTurn = false;
//(SOL: Siren's Call should be able to convert to an Effect)
private boolean sirenAttackOrDestroy = false;
private boolean faceDown = false;
private boolean kicked = false;
private boolean evoked = false;
private boolean bounceAtUntap = false;
private boolean finishedEnteringBF = false;
private boolean unearthed;
private boolean suspendCast = false;
private boolean isImmutable = false;
private int damage;
//(SOL: This really should be regenerationShield)
private int nShield; // regeneration
private int preventNextDamage = 0;
private int turnInZone;
private int tempAttackBoost = 0;
private int tempDefenseBoost = 0;
private int semiPermanentAttackBoost = 0;
private int semiPermanentDefenseBoost = 0;
private int randomPicture = 0;
private int xManaCostPaid = 0;
private int xLifePaid = 0;
private int multiKickerMagnitude = 0;
private int replicateMagnitude = 0;
// (SOL: There's a better/more robust way to handle this situation)
private int sunburstValue = 0;
private String colorsPaid = "";
private String chosenType = "";
private String chosenColor = "";
private String namedCard = "";
private Card cloneOrigin = null;
private ArrayList<Card> clones = new ArrayList<Card>();
private Card currentlyCloningCard = null;
private Command cloneLeavesPlayCommand = null;
private ArrayList<Card> gainControlTargets = new ArrayList<Card>();
private ArrayList<Command> gainControlReleaseCommands = new ArrayList<Command>();
// (SOL: Not sure where these Commands are created.)
private ArrayList<Command> turnFaceUpCommandList = new ArrayList<Command>();
private ArrayList<Command> equipCommandList = new ArrayList<Command>();
private ArrayList<Command> unEquipCommandList = new ArrayList<Command>();
private ArrayList<Command> enchantCommandList = new ArrayList<Command>();
private ArrayList<Command> unEnchantCommandList = new ArrayList<Command>();
private ArrayList<Command> untapCommandList = new ArrayList<Command>();
private ArrayList<Command> changeControllerCommandList = new ArrayList<Command>();
private ArrayList<Command> replaceMoveToGraveyardCommandList = new ArrayList<Command>();
private ArrayList<Command> cycleCommandList = new ArrayList<Command>();
private Map<Counters, Integer> counters = new TreeMap<Counters, Integer>();
// (SOL: Outdated I'm going to remove this in a little bit)
private int abilityUsed;
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Why does copyCard copy the UniqueNumber?
by Sloth » 29 Jul 2011, 14:01
My concern is that some triggers might be unable to find the triggered card. But I'm not an expert of trigger logic.friarsol wrote:I don't think we necessarily need to copy over the UniqueNumber from copyCard. The moveTo() functions are returning the new card, so as long as whatever calls moveTo() uses the returned Card for any further calculation/manipulation we should be fine.
I've also removed quite a few unnecessary variables and functions from the card class (the most funniest one was storing the name of the top card of the libraryfriarsol wrote:I just cleaned up some unnecessary member variables in Card.

Good work removing some more.
I think imageName can be moved to CardCollectionData.friarsol wrote:I've also made a list of how we could split up the class, along with some commentary:
- CardData | Open
- private Map<String, Object> triggeringObjects = new TreeMap<String, Object>();
private ArrayList<Trigger> triggers = new ArrayList<Trigger>();
private ArrayList<String> intrinsicAbility = new ArrayList<String>();
// (SOL: I don't think we need Static Ability Strings AND StaticAbilities, just the Abilities should be fine)
private ArrayList<String> staticAbilityStrings = new ArrayList<String>();
private ArrayList<String> intrinsicKeyword = new ArrayList<String>();
private ArrayList<String> type = new ArrayList<String>();
// (SOL: I don't think ManaAbilities necessarily need their own ArrayList)
private ArrayList<SpellAbility> spellAbility = new ArrayList<SpellAbility>();
private ArrayList<Ability_Mana> manaAbility = new ArrayList<Ability_Mana>();
private ArrayList<StaticAbility> staticAbilities = new ArrayList<StaticAbility>();
// (SOL: CanPlay() Should handle along with StaticAbilities that effect players
private boolean unCastable;
private boolean levelUp = false;
// (SOL: Flashback and Unearth can be converted to have an ActivatingZone probably)
private boolean flashback = false;
private boolean unearth = false;
private boolean madness = false;
private boolean suspend = false;
// (SOL: Why do we have both baseAttack and baseAttack String? Can everything just use Card_PT now?)
private int baseAttack = 0;
private int baseDefense = 0;
private ArrayList<Card_PT> newPT = new ArrayList<Card_PT>(); // stack of set power/toughness
private int baseLoyalty = 0;
private String baseAttackString = null;
private String baseDefenseString = null;
// (SOL: owner/controller are game specific, but might cause issues if not available here)
private Player owner = null;
private Player controller = null;
private String name = "";
private String imageName = "";
private String rarity = "";
private String text = "";
private String manaCost = "";
// (SOL: More things I'd love to see moved somewhere else)
private String echoCost = "";
private String madnessCost = "";
private Map<String, String> SVars = new TreeMap<String, String>();
private String ImageFilename = "";
private ArrayList<Ability_Triggered> zcTriggers = new ArrayList<Ability_Triggered>();
- CardCollectionData | Open
- private long value;
private ArrayList<SetInfo> Sets = new ArrayList<SetInfo>();
private String curSetCode = "";
- CardGameData | Open
- private long timestamp = -1; // permanents on the battlefield
private static int nextUniqueNumber;
private int uniqueNumber = nextUniqueNumber++;
private ArrayList<String> extrinsicKeyword = new ArrayList<String>();
private ArrayList<String> HiddenExtrinsicKeyword = new ArrayList<String>(); //Hidden keywords won't be displayed on the card
private ArrayList<String> prevIntrinsicKeyword = new ArrayList<String>();
// (Note: equipping and enchanting should just be Card not ArrayList<Card>
private ArrayList<Card> attached = new ArrayList<Card>();
private ArrayList<Card> equippedBy = new ArrayList<Card>(); //which equipment cards are equipping this card?
//equipping size will always be 0 or 1
private ArrayList<Card> equipping = new ArrayList<Card>(); //if this card is of the type equipment, what card is it currently equipping?
private ArrayList<Card> enchantedBy = new ArrayList<Card>(); //which auras enchanted this card?
//enchanting size will always be 0 or 1
private ArrayList<Card> enchanting = new ArrayList<Card>(); //if this card is an Aura, what card is it enchanting?
private ArrayList<String> prevType = new ArrayList<String>();
private ArrayList<String> ChoicesMade = new ArrayList<String>();
// (SOL: This seems to be used with Modal spells, but I'm not sure why it's a List of strings)
private ArrayList<String> Targets_for_Choices = new ArrayList<String>();
// (SOL: I wonder if we should combine these "tracking" variables into a Map of Lists)
private ArrayList<Object> rememberedObjects = new ArrayList<Object>();
private ArrayList<Card> imprintedCards = new ArrayList<Card>();
private Card championedCard = null;
private CardList devouredCards = new CardList();
private Map<Card, Integer> receivedDamageFromThisTurn = new TreeMap<Card, Integer>();
private Map<Card, Integer> dealtDamageToThisTurn = new TreeMap<Card, Integer>();
private Map<Card, Integer> assignedDamageMap = new TreeMap<Card, Integer>();
private boolean drawnThisTurn = false;
private boolean tapped;
private boolean sickness = true; //summoning sickness
private boolean token = false;
private boolean copiedToken = false;
private boolean copiedSpell = false;
private boolean creatureAttackedThisTurn = false;
private boolean creatureAttackedThisCombat = false;
private boolean creatureBlockedThisCombat = false;
private boolean creatureGotBlockedThisCombat = false;
private boolean dealtDmgToHumanThisTurn = false;
private boolean dealtDmgToComputerThisTurn = false;
//(SOL: Siren's Call should be able to convert to an Effect)
private boolean sirenAttackOrDestroy = false;
private boolean faceDown = false;
private boolean kicked = false;
private boolean evoked = false;
private boolean bounceAtUntap = false;
private boolean finishedEnteringBF = false;
private boolean unearthed;
private boolean suspendCast = false;
private boolean isImmutable = false;
private int damage;
//(SOL: This really should be regenerationShield)
private int nShield; // regeneration
private int preventNextDamage = 0;
private int turnInZone;
private int tempAttackBoost = 0;
private int tempDefenseBoost = 0;
private int semiPermanentAttackBoost = 0;
private int semiPermanentDefenseBoost = 0;
private int randomPicture = 0;
private int xManaCostPaid = 0;
private int xLifePaid = 0;
private int multiKickerMagnitude = 0;
private int replicateMagnitude = 0;
// (SOL: There's a better/more robust way to handle this situation)
private int sunburstValue = 0;
private String colorsPaid = "";
private String chosenType = "";
private String chosenColor = "";
private String namedCard = "";
private Card cloneOrigin = null;
private ArrayList<Card> clones = new ArrayList<Card>();
private Card currentlyCloningCard = null;
private Command cloneLeavesPlayCommand = null;
private ArrayList<Card> gainControlTargets = new ArrayList<Card>();
private ArrayList<Command> gainControlReleaseCommands = new ArrayList<Command>();
// (SOL: Not sure where these Commands are created.)
private ArrayList<Command> turnFaceUpCommandList = new ArrayList<Command>();
private ArrayList<Command> equipCommandList = new ArrayList<Command>();
private ArrayList<Command> unEquipCommandList = new ArrayList<Command>();
private ArrayList<Command> enchantCommandList = new ArrayList<Command>();
private ArrayList<Command> unEnchantCommandList = new ArrayList<Command>();
private ArrayList<Command> untapCommandList = new ArrayList<Command>();
private ArrayList<Command> changeControllerCommandList = new ArrayList<Command>();
private ArrayList<Command> replaceMoveToGraveyardCommandList = new ArrayList<Command>();
private ArrayList<Command> cycleCommandList = new ArrayList<Command>();
private Map<Counters, Integer> counters = new TreeMap<Counters, Integer>();
// (SOL: Outdated I'm going to remove this in a little bit)
private int abilityUsed;
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Why does copyCard copy the UniqueNumber?
by Hellfish » 29 Jul 2011, 23:54
Trigger logic should be pretty much unaffected as long as Card.IsValid(...) is. That's the only place I can think of in trigger code that uses card IDs.My concern is that some triggers might be unable to find the triggered card. But I'm not an expert of trigger logic.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-
Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Why does copyCard copy the UniqueNumber?
by Sloth » 30 Jul 2011, 10:18
As I expected removing the copying of the UniqueNumber will cause a ton of problems. Moving cards to the stack in addAndUnfreeze does throw a NPE for targeted spells and Remembered doesn't work any more.
I guess the whole structure is not ready for this.
I guess the whole structure is not ready for this.

-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Why does copyCard copy the UniqueNumber?
by friarsol » 30 Jul 2011, 13:49
I should have some time today to tweak at this. I have some ideas about how it might work without overhauling the whole structure.Sloth wrote:As I expected removing the copying of the UniqueNumber will cause a ton of problems. Moving cards to the stack in addAndUnfreeze does throw a NPE for targeted spells and Remembered doesn't work any more.
I guess the whole structure is not ready for this.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Why does copyCard copy the UniqueNumber?
by friarsol » 30 Jul 2011, 15:55
My simple solution for this didn't work the way I was hoping.friarsol wrote:I should have some time today to tweak at this. I have some ideas about how it might work without overhauling the whole structure.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Why does copyCard copy the UniqueNumber?
by mtgrares » 08 Aug 2011, 18:41
Conceptually I thought of a card's unique number equals one cardboard physical card but with Momentary Blink + Vindicate this clearly isn't true. A physical card "changes" each time it is played. One possible suggestion is that when a card is put onto the battlefield is gets a new unique card number, that way the card's unique number stays the same when the card is in hand and on the stack. This still might cause a some errors.
Just my 2 cents.
Just my 2 cents.

- mtgrares
- DEVELOPER
- Posts: 1352
- Joined: 08 Sep 2008, 22:10
- Has thanked: 3 times
- Been thanked: 12 times
Re: Why does copyCard copy the UniqueNumber?
by Braids » 08 Aug 2011, 22:26
is this because Vindicate targets a permanent, and Momentary Blink causes the card to leave play and come back as a separate permanent, causing Vindicate to fizzle?mtgrares wrote:Conceptually I thought of a card's unique number equals one cardboard physical card but with Momentary Blink + Vindicate this clearly isn't true. A physical card "changes" each time it is played. One possible suggestion is that when a card is put onto the battlefield is gets a new unique card number, that way the card's unique number stays the same when the card is in hand and on the stack. This still might cause a some errors.
Just my 2 cents.
"That is the dumbest thing I've ever seen." --Rob Cashwalker, regarding Innistrad double-sided cards. One of the first times he and I have ever agreed on something. 

-
Braids - Programmer
- Posts: 556
- Joined: 22 Jun 2011, 00:39
- Location: Unknown. Hobby: Driving myself and others to constructive madness.
- Has thanked: 1 time
- Been thanked: 1 time
Re: Why does copyCard copy the UniqueNumber?
by Sloth » 09 Aug 2011, 11:40
This is what should be happening, but does not.Braids wrote:is this because Vindicate targets a permanent, and Momentary Blink causes the card to leave play and come back as a separate permanent, causing Vindicate to fizzle?
This sounds like it will work as a temporary fix.mtgrares wrote:Conceptually I thought of a card's unique number equals one cardboard physical card but with Momentary Blink + Vindicate this clearly isn't true. A physical card "changes" each time it is played. One possible suggestion is that when a card is put onto the battlefield is gets a new unique card number, that way the card's unique number stays the same when the card is in hand and on the stack. This still might cause a some errors.
Just my 2 cents.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Why does copyCard copy the UniqueNumber?
by Braids » 09 Aug 2011, 18:40
i would tend to think that a card on the battlefield should be some sort of Permanent instance, with a reference to the Card that it embodies. tokens would have no such reference.Sloth wrote:This is what should be happening, but does not.Braids wrote:is this because Vindicate targets a permanent, and Momentary Blink causes the card to leave play and come back as a separate permanent, causing Vindicate to fizzle?This sounds like it will work as a temporary fix.mtgrares wrote:Conceptually I thought of a card's unique number equals one cardboard physical card but with Momentary Blink + Vindicate this clearly isn't true. A physical card "changes" each time it is played. One possible suggestion is that when a card is put onto the battlefield is gets a new unique card number, that way the card's unique number stays the same when the card is in hand and on the stack. This still might cause a some errors.
Just my 2 cents.
"That is the dumbest thing I've ever seen." --Rob Cashwalker, regarding Innistrad double-sided cards. One of the first times he and I have ever agreed on something. 

-
Braids - Programmer
- Posts: 556
- Joined: 22 Jun 2011, 00:39
- Location: Unknown. Hobby: Driving myself and others to constructive madness.
- Has thanked: 1 time
- Been thanked: 1 time
19 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 19 guests