I am trying to write a kind of a trading card game here, in some way, it is similar to Magic The Gathering, or the Yu-Gi-Oh! card game.
For those of you who are not familiar with it, basically, in the game, there is a special kind of card (Spell cards/ Trap cards/ etc.), which have special effects that can bend the rules of the game. What I totally have no idea is, how to implement the logic of these cards. I have some idea of storing the card's data with some flags that can signal what kind of ability it has, but that would be very limited in what it can do (only some simple stats modification, maybe).
To give you an idea of what kind of effects these cards can have, here is some example of the spell card effects that are present in the Yu-Gi-Oh! card game:
- Revive a creature that has been destroyed
- Take control of the opponent's creature
- Modify stats of the creature based on some conditions (e.g. Number of creature with certain names that have been destroyed)
- Special summon a certain creatures if the some conditions are fulfilled.
- Fuse two or more creatures into a stronger creature.
- Immunity to some of the special cards' effect.
Konami has made several video games of the game, complete with the AI and thousands of cards variety. I don't think it is actually possible to hard-code the entire database, is it?
Now, of course what I am trying to do is in no where as complex as those games, but I am curious, how do they implement these?
Answer
There are several open-source projects of this nature, with different approaches to implementing the rules. Here is a blog entry from the creator of one of the more well-known MtG implementations, CardForge. It may not be a complete list, but it contains several open-source projects where you can simply browse the code, or visit the forums for specific questions.
As an actual answer: Your best bet for a robust framework is to strictly employ Object-Oriented Programming. Every Action, every Trigger, every Ability is an object. Zones like Hand, Library are objects too, needless to say. In the Rules engine, never pass around dumb objects like strings or integers to describe game objects, but your objects only.
Every action puts a number of trigger on a stack, where every other ability can check whether or not they care about that particular trigger, and if they do, they fire their own actions, potentially creating new triggers, and so on.
Then you work down those stacks according to the game's rules, until the stack is empty, at which point new actions can be taken etc.
Ideally, if you perfectly implement the game's rules, your rules code does not contain a single hardcoded card. Hardcoding cards can create convenient shortcuts, but in the long run, this will bloat your code and create potential pitfalls, such as when new cards are released that interact with those cards in a novel way. In a game like MtG with over 12,000 unique cards and no end in sight, there are MANY such interactions.
No comments:
Post a Comment