Page 1 of 1

Card Cloning

PostPosted: 17 Sep 2010, 17:49
by mtgrares
Rob Cashwalker wrote:I'm just saying that the card objects created on startup should somehow be off limits to modification, and all future cards should be cloned from the originals.
Yeah probably. Copying objects is just complicated. I've read some about cloning objects and it is a very murky subject, no one has any real answers. That is why I just created new objects and created the monstrosity that is CardFactory. At least conceptually I could understand a new object and knew that it wouldn't generate any errors.

I have no idea how Wagic or other Magic project create new card objects.

Re: Card Cloning

PostPosted: 17 Sep 2010, 19:11
by Rob Cashwalker
Just as The SpellAbility object became cloneable without too much hassle, I'm thinking the Card object should be nearly as simple.... That's the easy part. The hard part is actually making sure that cards are cloned correctly anywhere where new cards are created.

Ideally, I would think the deck editor should work from a plain data list of cards as opposed to the global card object list. Main reason we can't do that in the current architecture, is that the card text isn't always raw text, it's dynamically assembled from the SpellAbility objects and keywords, and/or raw text.... Going back to raw text means that it can be automatically updated as Oracle text is updated. The spell mechanics don't usually change, but their wording does... easier to change card text than source code.

Re: Card Cloning

PostPosted: 17 Sep 2010, 22:45
by zerker2000
So, should we add a copy of OracleAll.txt to res, and pull info from that by card name(along with all "NOTE" lines from cardname.txt)?

Re: Card Cloning

PostPosted: 18 Sep 2010, 02:38
by Rob Cashwalker
No, just that the Text field for each card can be automatically kept up to date by the python script.

Re: Card Cloning

PostPosted: 21 Sep 2010, 03:55
by frwololo
mtgrares wrote:I have no idea how Wagic or other Magic project create new card objects.
In Wagic we have 3 classes:
CardPrimitive is a class that hold all the basic data (power/toughness...) Basically the cardPrimitives represent our database. An example of Card Primitive is the data representing Llanowar Elves.
CardPrimitive Llanowar Elves:
Code: Select all
name=Llanowar Elves
power=1
toughness=1
auto={t}:Add{G}
...
Card is a class that represent reprints. It has a cardPrimitive as an attribute, but everything specific to a reprint (id, picture, rarity,...) are distinct. So, for example, Llanowar Elves in 10E point to the "Llanowar Elves" primitive data, but additionally have rarity information (Common), a specific id (the id from gatherer) etc...
Card Llanowar Elves 10E:
Code: Select all
primitive=Llanowar elves
id=12345
rarity=C
Technically, Card objects also represent our database, or rather, what cards are contained in what sets.

Then, in the game itself, we have MTGCardInstance. This class inherits from both CardPrimitive AND Card (which is kind of dirty). Every time I put a new "Llanowar Elf" in play, a new MTGCardInstance is created, and we manually copy the contents of the CardPrimitive and the Card it inherits from.
http://code.google.com/p/wagic/source/b ... nce.cpp#25 (but the copy of the actual contents happens in the Constructors of CardPrimitive and Card).
MTGCardInstance Llanowar Elves 1:
Code: Select all
power=1
toughness=1
rarity=C
auto={T}:Add{G}
id=12345
...
Additionally, when a card changes zone, we create a new MTGCardInstance from its matching CardPrimitive. And we put a "backtrack" pointer to the previous MTGCardInstance.
For example, if my Llanowar Elves currently in play is called MTGCardInstance[1], then if it goes to the graveyard, I will create a MTGCardInstance[2] that points to MTGCardInstance[1]. This pointer is for abilities that say things like "when this card is put into a graveyard, if it was a creature, then...". It basically allows to look at what the card was in previous zones, without any major headache. (We didn't do that initially, but Incantus convinced me a while ago that a new object for every zone change is the good solution)
MTGCardInstance Llanowar Elves 2:
Code: Select all
power=1
toughness=1
rarity=C
auto={T}:Add{G}
id=12345
previous=Llanowar Elves 1
...
To preserve ram, we delete as much "old" copies as possible at the end of each turn.

So, to summarize: we handle our copies manually in game.
(all code above is of course pseudo code)