0

I am making a card game, it is similar to Bang. You have a boss, which has some HP and you are getting cards with abilities, HP,DMG, etc. I want to make it as a .io game or maybe just a web application, it doesn't matter now. So the language I am building it in is Javascript + Node. But I ran into a problem with structure of game logic - abilities. The abilities of the cards are really hard to describe as a structure, sometimes they consist of "if enemy attacks you and his boss is fire type he does 50% less damage" or "every round you get 2 coins of this type" or "if he dies, after 5 rounds you can make him alive again, but this works only once". It is similar to hearstone/bang cards, but these have their own unique abilities and that's really amazing, when you play it with friends as cards, but I have no idea, how do i implement this as a program.

So as a game logic, I would like to make classes like Game - game controller + game info, Player - player controller + player info, but I don't really like my first and only idea of making the card abilities. It's basically saving the abilities as functions(in database as strings!), which are then run by the Game class somehow(using eval?/making them real functions and saving them to some array and then running them every time something happens?). It has to be really really dynamic and flexible, because new cards are being produced and so new abilities are. What are your thoughts of structure in this type of game? What is the cleanest way to make game logic of this game? How would you implement this?

2

You need to flesh out the structure of the basic game a bit more. This gives you the structure of the possible card effects.

For example you might have

Player Turn
   player draws x cards from pile to a maximum hand size of xmax
   player picks up z coins
   player plays 0-1 cards from hand paying the coin cost for the card
   loop until no more cards can be played or player chooses to end turn
   play passes to next player

Now you have some stuff that cards can do

  1. change number of cards drawn
  2. change number of coins picked up
  3. change cost of cards played
  4. change the next player

etc

The more detail you add the more possible rules there are, but they still fit a structure. So we could add attributes to cards and or players

Card
    element type
    cost
    damage

now you can add conditions to your card effects "make fire cards 50% cheaper" and its possible to store that rule as a structured object and have the program apply the rule

  • That's pretty cool, I didn't think about corelation of the possible card effects and game rules. But you can have many different rules, how would you store it as a object. Some cards can make themselves alive after certain amount of time. How would you implement the structure, when you know that there is a card with this ability: "if he dies, after 5 rounds you can pay 5 coins and make him alive again". Also some of the abilities are usable only once and also might not expire after the card is dead. – lika8545 Apr 26 at 12:32
  • the struct is just a list of the actions from the possible list with the value against each. So to do your make card alive again effect, you first need have something in the player turn that defines what dead and alive mean "move dead creatures to the graveyard". Then you can have a card effect "move X creatures, with type Y from {graveyard} to {hand}" with a structure MoveCardEffect { from,to,validCardFilter} – Ewan Apr 26 at 12:41
  • I think that is the answer. It is amazing, I am going to try implement that. Thanks very much. – lika8545 Apr 26 at 12:52
1

If your cards have complex behavior such as the examples you gave, the best solution is probably to create a little domain specific language.

Card behaviors are defined as programs in this language, and the game contains an interpreter for this language.

You need to make the language powerful enough to be able to express any reasonable in-game logic that might be needed by newly defined card types, and programs need to be able to access and manipulate game state.

Possible implementation options for a DSL are a Forth-like system (incredibly simple) or an embedded Lua interpreter (also relatively simple), but as you use JavaScript/NodeJS you already have a nice language to use as basis.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.