Search Unity

Card effects on Card Game, how?

Discussion in 'Scripting' started by MatheusCohen, Feb 2, 2018.

  1. MatheusCohen

    MatheusCohen

    Joined:
    Aug 24, 2017
    Posts:
    57
    Hi,

    i'm currently working on a small single-player card game, much like Meteorfall: Journey, and after reading quite a bit on how to make a CCG/Card game and what else i couldn't figure out how to make specific card effects.

    I see that people advice to create Scriptable Objects with the card status, so you just have to fill up the blanks every time (status and maybe some basic/frequent effects much like the keywords on Magic the Gathering).

    But when it comes to specific effects, that only that card will ever have, how should i do it?

    I can just create a script with this effect, and Add it based on it's name everytime the card is played, but that doesn't seem to be the optimal way to do that... Can anyone help?


    Thank you!
     
  2. Eric-Farraro

    Eric-Farraro

    Joined:
    Apr 23, 2013
    Posts:
    31
    Super cool to see people inspired by Meteorfall!

    I actually implemented each card as its own class. Here's an example of the Zap spell: https://gist.github.com/efarraro/8df5b3c81bce33c8592c77e5dfebd3c8

    All the abilities are based on a BaseEffect class. Here, I have a bunch of different methods I can override that give each card the unique combination of effects that are required: https://gist.github.com/efarraro/19ebf3c3c33aee24d6384f85a4a944a7

    For most abilities, I end up overriding the Apply() method, which is what gets called when card is actually played. If you look at the Zap example, you can see I call out to another class which ends up resolving the damage. That resolver method is quite complex, but basically it has a laundry list of methods it will call. If the ability overrides one of those methods, it gets executed; if it doesn't, it's just a no-op.

    Buffs work exactly the same way as abilities. Usually the buffs will have some trigger. For instance, to create a card that reads "Gain 1 action whenever you heal", I'd create a buff and override the OnHeal() method with some special logic. The only difference in Meteorfall between Buffs and regular card effects is that buffs have to be attached to a unit.

    Hope this helps, and best of luck in your goal! If you can't find Unity specific examples, you may just want to look at how RPG or other roguelike open source projects implement abilities, and get some ideas from there.
     
  3. MatheusCohen

    MatheusCohen

    Joined:
    Aug 24, 2017
    Posts:
    57
    Hi Eric, thank you for your answer!

    i have been working on this project for a while(mostly on a physical board game form), but meteorfall has given me the push and inspiration to put it on a mobile! it's really awesome!


    that said, if you could help me out some more!

    i understand the logic behind what you told me and how the effects works, but how does the zap get's called?

    most examples i found, normally we have a List of scriptable objects as the deck, and when we Draw we instantiate a new Card and "attach" the scriptable object to said Card, which normally provides most Data(name, values, image)..

    It may be my limited knowledge/experience in Unity/Programming, but am i wrong to assume that you are using a List of "BaseEffect" as the Deck?

    and then only showing the first card of the deck, and the card script executing all behaviors of said card?


    I apologize if anything wasn't clear, English is my second language, and thank you for any of your time!
     
  4. Eric-Farraro

    Eric-Farraro

    Joined:
    Apr 23, 2013
    Posts:
    31
    I actually didn't even know about ScriptableObjects when I started Meteorfall, so I don't use them. Even if I had known about them, I'm not sure if I would've used them.

    I started out with just a List<Card> that held the cards. I eventually abstracted that out into a 'Deck' class, because I wanted an object oriented way to interact with the list.

    What happens when the card is swiped in Meteorfall is that I have a coroutine called PlayCardTask that gets invoked. I store the current game state in a 'pure' data model (C# only - no Unity), that's accessible in a singleton. In PlayCardTask, I check the GameState to see what the the value of CurrentPlayer.CurrentCard is. CurrentCard is a data representation of the ability that I'm currently swiping, as I described with Zap above. I then call CurrentPlayer.CurrentCard.Apply(), which applies the effect. In the case of Zap, I again access the global game state and update the enemy's health.

    If I had to generalize, I have code in the GameObjects (which I call 'views') that await player actions. Actions the player takes, such as playing a card, getting communicated to the game state, which I store as a pure object in a singleton.
     
    umairwasim and Kurt-Dekker like this.