Nyx13 said:
i was wondering if there were any other (better) options, but thank you very much
The cards themselves are little more than collections and arrays.
For example, the cards have a name, a description, some ability text, some artwork, a type of card like permanent or spell, all of these come in standard forms for your game as a simple array of structures.
Cards have a cost, so you have an array of cost functions to play the card. Abilities may have a cost, and they use the same cost functions. It may be “pay 4 mana”, it may be “tap this card”, it may be “sacrifice a card you control”, it may have multiple costs. That's an array.
Cards have zero or more abilities, and each ability has an array of actions. Each of those abilities is an array of composition. Costs and targeting need to be part of those arrays and collections, too.
For for example, a card ability array for this card might conceptually look like this:
[ [ Cost: [ Tap this card; Exile: self, target land; ]
Ability: [ Add mana of any color ]
]
[ Cost: [ Pay Mana: black; Tap this card; Exile: target any player's graveyard, target any instant or sorcery ]
Ability: [ Change life: all opponents, -2 ]
]
[ Cost: [ Pay mana: green; Tap this card; Exile: target any player's graveyard, target any creature card ]
Ability: [ Change life: self, 2 ]
]
]
Or maybe an ability array for this card:
[ [ Cost: [ ]
Ability: [ Deal damage: any target, 5; Draw cards: self, 5; Change armor: self, 5; Summon creature: self, card 731 ]
]
]
Or maybe an ability array for this card:
[ [ Cost: [ Triggered ability: Object destroyed: any ally, landmark ]
Ability: [ Change Power+Health: this card, 1, 1 ]
]
]
Exactly how you implement that array would be up to you, but it could easily be a pattern of tokens you build and parse. It could be a mapping of functions to numbers, it could be function pointers, it could be text strings.
The detail about the cards can live in one array in memory, and really won't be that big. If you're storing just IDs you're looking at perhaps a few kilobytes even for hundreds of card definitions. Cards in play only need a reference to the card definition.
The questions about where card data lives, meaning if you keep them in a database, if you keep them in data files, if you keep them static in code, that's almost irrelevant to the card game. A statically compiled array is super easy for a single programmer as I wrote, since you can build up a single file that is easy to use with simple arrays for all the information about every card. Keeping them in data files means leading it every time, but it still boils out to the same arrays of data. A deck system like we used on Hearthstone will query the server for the definitions for the cards in use, but they're still fundamentally the same data arrays. You could build a huge architecture about real-time updates of card definitions held around the world, but it would still ultimately boil down to arrays of attributes like above.
And the cards themselves, they're a reference to the card definition, plus an array of whatever modified local things have adjusted it.
It is easy to over-think this kind of thing. It takes time to build up all the various cost functions, the targeting functions, the ability functions, but once you have enough of them, composing those into interesting cards is straightforward.