You can't build a game without giving some thought to what the play experience should be like. In our case, the play experience is largely set by the individual CCG that the user wants to play, but we have to make sure that we can reproduce that play experience using our program. To that end I have acquired a fairly large set of rulebooks and cards for various CCG games over the years. The list I referred to when I did the design work below included:
This is by no means a comprehensive list of all the collectible card games
available today or those produced over the last six or seven years. I can name
at least a couple of dozen more I don't have rulebooks or any cards for that I
would like to try out or at least make sure can be played using this tool. If
you have a set of rules for another game and/or some cards for it you wouldn't
mind parting with you can send them to:
|
John Munsch 5425 Glen Canyon Rd. Fort Worth, TX 76137 |
Each set of rules was examined with an eye toward what I call "mechanics" and not the rules themselves. For example, Magic: The Gathering (M:TG) has a concept of "tapping" a card. This involves rotating the card 90 degrees clockwise so our program has to allow the user to rotate a card in 90 degree increments and be able to provide enough information about the card to draw it properly for those rotations.
This isn't to say that the program is designed to deal with any eventuality. Here is another example, M:TG has a card called "Chaos Orb". This card has the following rather unique set of rules associated with its use, "Flip Chaos Orb onto the playing area from a height of at least one foot. Chaos Orb must turn completely over at least once or it is discarded with no effect. When Chaos Orb lands, any cards in play that it touches are destroyed, as is Chaos Orb." Clearly this is not the kind of thing we want to provide special code to simulate. It is a unique feature of just one card in just one game and it is probably better that users just not play with that one card online. For the most part an examination of the rule sets and cards available to me indicated that this kind of thing was the exception rather than the rule and most games expected the user to interact with cards, counters, coins, and dice in a pretty standard set of ways.
Model-View-Controller is a way of developing programs which have user interaction. It separates what a program is doing (e.g. editing a document, playing a game, creating music, etc.) from how the user interacts with the program.
The model is the guts of the program, it is the data that is being worked with (for example, the
With the research done, it is pretty easy to figure out what classes the game needs to deal with. They are:
In order to work with the model in a purely conceptual manner and make
changes more easily I use the free edition of Poseidon to build
a UML diagram of the classes. On that diagram I can add functions, class
relationships, methods, etc. and then when I'm pleased with the results have
Poseidon generate Java classes for each of the objects I created in my charts.
Here's a screenshot of Poseidon at work on my UML diagram for the model
discussed below:
![]()
A much harder problem than what classes we should have is what methods they should support and data they should have in order to support different games.
The game should keep track of all of the elements that the players are using to play the game. In effect, every token, die, and card should be owned by the game class. Saving and loading a game would be accomplished through this class by serializing all of the various play pieces to a file and restoring them later.

These are the "permanent" card piles on the playing surface. They might not actually have any cards in them yet (e.g. a discard pile at the beginning of the game). This is as opposed to ad hoc card groups that spring up during the course of the game. Those are handled by simply attaching cards to one another via a feature of the cards themselves.

addCard removeCard drawCard
With all of the above known let's give some further thought to what our "card" looks like. We know it contains a reference to a "master" card in our card dictionary. It should contain binary indicators that tell us whether its reference has been encrypted by a key on this machine or a key on the other machine or both. It should have the ability to encrypt and decrypt the reference given a key. Lastly it should have functions which allow us to access all the data that is on a card without it being clear that it is simply defererencing through our card dictionary to look it up. Those data access functions should only operate if the reference is completely unencrypted and should throw an exception otherwise.

opponentEncrypted iEncrypted reference orientation

A simple numerical counter used to keep track of hit points, mana, or whatever a given game may need to keep count of. It provides basic functions to make incrementing and decrementing easy as well as setting it to a specific value.

A simple flippable coin.

Simulates a multisided die with equal chance of getting any value within the range it can roll. The range of the die (e.g. 1-6) should be set when the die is created.



The game will keep track of a minimal amount of information that is usually
made available to other players in any online game and any information which
may be of use to us in the game itself. For example, it can be handy to have a
handle (aka. a nick, or nickname) for each player so we can issue messages which
say:
Neo shuffled his library card group
rather than:
Player one shuffled his library card group

Here's a UML diagram of our classes at this point:

In truth you could build a system which ignored all four of the following issues and it would still be useful. So while I'm going to look at a couple of these topics in the next couple of chapters, you can go ahead and just skip on to rendering because the instant-messaging and fairness won't be implemented in our first crude version of UberCard.
If I take a program and run it from inside a debugger I can watch all the memory locations within that program. In most debuggers I can also search for specific patterns within memory so I can easily find data structures stored there because they will likely contain strings or specific numbers I know.
Boiled down to its basics, its easy to cheat and hard to detect cheating on the other players part. Once players realize that it can really destroy a user's confidence in whether he or she really lost or was cheated.
It's not going to be much fun to play UberCard unless you can talk to the person with whom you are playing. There are a lot of potential solutions to this problem, including not solving it at all and requiring the players to use an instant messaging system like ICQ or MSN Messenger to communicate.
The best overall play experience though will be if there is communications between the players built right into UberCard. Then a transcript of a game could include not only the players actions but also their conversation back and forth.
The cards in collectible card games are attractive. It would be a shame to strip every card of its colors, symbols, and pictures to reduce every card to just numbers and text. I believe we shouldn't have to and would like to build a system capable of rendering cards at a variety of different resolutions (smaller for the card table itself and full size for zoomed in views of a stack of cards).
The number one site for game development.
Home of the author's weblog and all his projects (including this one).
Covers many major design patterns in sufficient detail for you to be able to use them in your programs. If you had to distill all of software development down to ten reference books, I'm thinking this would be one of the ten.