Class CardDesc

  • All Implemented Interfaces:, java.lang.Cloneable, HasEntrySet<CardDescArg,​java.lang.Object>

    public final class CardDesc
    extends java.lang.Object
    implements, java.lang.Cloneable, HasEntrySet<CardDescArg,​java.lang.Object>
    The class that card JSON files deserialize (get decoded) into.

    All types of cards are encoded as a CardDesc; spells, secrets, hero cards, hero powers, minions, etc. This class should only store the data related to the card, not card functionality itself.

    Each of the fields in this class correspond exactly to the fields in a .json file located in the cards directory. A card JSON looks like:

                 "name": "Angry Primate",
                 "baseManaCost": 1,
                 "type": "MINION",
                 "heroClass": "ANY",
                 "baseAttack": 1,
                 "baseHp": 2,
                 "rarity": "COMMON",
                 "race": "BEAST",
                 "description": "Battlecry: Add a Banana to your hand.",
      line 63:   "battlecry": {
                   "targetSelection": "NONE",
                   "spell": {
                     "class": "ReceiveCardSpell",
      line 67:       "cards": [
      line 72:   "attributes": {
                   "BATTLECRY": true
                 "collectible": true,
                 "set": "CUSTOM",
                 "fileFormatVersion": 1
    Observe that each of the keys in the JSON, or the text matching the quotation marks, matches a field in this class. So "name" corresponds to the name field, "battlecry" corresponds to the battlecry field, etc.

    To figure out the format of the value of complex objects like "battlecry" on line 63 in the example above, look at the type of the field in this class. In the case of battlecry, the type is a BattlecryDesc, and it appears to also have fields that exactly correspond to the keys that appear in the JSON object that is the value of "battlecry."

    Some objects, like "spell", are Desc classes: these use a corresponding "argument" enumeration to determine the names and types of the fields. In the case of SpellDesc, the keys are SpellArg names, except written in camelCase. In the example of Angry Primate above, the "cards" key on line 67 inside the SpellDesc corresponds to the SpellArg.CARDS enum name. Observe that "cards" is just SpellArg.CARDS except lowercase.

    The only exception to this rule is the AttributeMap object located on line 72 in the example above. The keys (left hand part in quotation marks of the JSON object) should always be capitalized, and correspond exactly to the names in Attribute.

    See Also:
    for the gameplay functionality of a card that consults data stored in a ., for a walk through on how deserialization of card JSON works on complex types like spells, value providers, etc., Serialized Form
    • Constructor Detail

      • CardDesc

        public CardDesc()
    • Method Detail

      • create

        public Card create()
        Creates a Card entity with no ID or location backed by this CardDesc.
        A card.
      • getCollectible

        public boolean getCollectible()
      • getBattlecryAction

        public BattlecryAction getBattlecryAction()
        Retrieves a battlecry action specified on this card.
        A battlecry action.
      • clone

        public CardDesc clone()
        clone in class java.lang.Object
      • getId

        public java.lang.String getId()
        The ID of the card when referred to by other cards and other places in the game engine.

        Typically, the ID is not specified inside the card file. It is assumed to be the file name of the card file, minus the JSON extension. For example, the card minion_bloodfen_raptor.json will have its ID field assigned to minion_bloodfen_raptor.

        IDs should not be changed after a public server release is made, even when there is a misspelling or other issue. Player's inventories store references to the underlying cards using the IDs, and changing the IDs will damage those references. The Spellsource migrations system provides a mechanism for changing IDs of cards after they have been given to players; see the net module's Spellsource class for details.

      • setId

        public void setId​(java.lang.String id)
      • getName

        public java.lang.String getName()
        The name of the card that should be rendered in the client. The name is also used for some card mechanics, like The Caverns Below. The name can be overridden by Attribute.NAME on the card entity.
        See Also:
        for the complete usage of the name field.
      • setName

        public void setName​(java.lang.String name)
      • getDescription

        public java.lang.String getDescription()
        A description of the card that should be rendered in the client. This field does not support formatting specifiers like bolding, italics, etc.
        See Also:
        for the complete usage of the description field.
      • setDescription

        public void setDescription​(java.lang.String description)
      • getLegacy

        public java.lang.Boolean getLegacy()
        Indicates whether this card will participate in the determination of legacy mechanics, the storing of data about cards across all matches.
        See Also:
        for an example of a legacy mechanic.
      • setLegacy

        public void setLegacy​(java.lang.Boolean legacy)
      • getType

        public CardType getType()
        The type of card this instance describes.
      • setType

        public void setType​(CardType type)
      • getHeroClass

        public HeroClass getHeroClass()
        The hero class this card belongs to.

        Choose HeroClass.ANY for a neutral card.

      • setHeroClass

        public void setHeroClass​(HeroClass heroClass)
      • getHeroClasses

        public HeroClass[] getHeroClasses()
        For tri-class cards from the MSOG Hearthstone expansion, this field contains their three classes. Typically uninteresting to use for custom cards.
      • setHeroClasses

        public void setHeroClasses​(HeroClass[] heroClasses)
      • setRarity

        public void setRarity​(Rarity rarity)
      • getSet

        public CardSet getSet()
        The set this card belongs to. Unless the card's author designed this card in the context of a greater set, use CardSet.CUSTOM for community cards.

        Eventually, a set will be immutable and represent a particular release or expansion, while a DeckFormat will represent a certain set of rules of play.

      • setSet

        public void setSet​(CardSet set)
      • getBaseManaCost

        public int getBaseManaCost()
        The base mana cost of the card. All cards should have this field set, even if they are virtual / non-acting cards. Use 0 as the cost of those cards.

        Choice cards for CardType.CHOOSE_ONE cards and CardType.MINION cards with choose-one battlecries that transform into another Minion should have the same cost as the parent card. For example, the choice card of Wrath should still have Wrath's cost, not 0.

      • setBaseManaCost

        public void setBaseManaCost​(int baseManaCost)
      • isCollectible

        public boolean isCollectible()
        Indicates whether or not the card should appear in discovers and in the collection browser. Choose one choice cards, virtual choice cards, tokens, base heroes, and previous versions of other cards ("unnerfed" cards) should not be collectible.
      • setCollectible

        public void setCollectible​(boolean collectible)
      • setAttributes

        public void setAttributes​(AttributeMap attributes)
      • getFileFormatVersion

        public int getFileFormatVersion()
        Indicates the version of this card description. Defaults to 1. When new expansions are released, this number should be incremented for the new cards to help the game record traces and reproduce bugs (only the cards that were around for a particular release of the code should participate in a game trace's lookup of cards in the CardCatalogue, for example).
      • setFileFormatVersion

        public void setFileFormatVersion​(int fileFormatVersion)
      • getManaCostModifier

        public ValueProviderDesc getManaCostModifier()
        Indicates an amount the card's cost should be subtracted by while the card is in the player's hand.

        For example, to decrease the card's cost for each other card in the player's hand, the "manaCostModifier" field in the CardDesc would look like:

         "manaCostModifier": {
              "class": "PlayerAttributeValueProvider",
              "offset": -1,
              "playerAttribute": "HAND_COUNT",
              "targetPlayer": "SELF"
      • setManaCostModifier

        public void setManaCostModifier​(ValueProviderDesc manaCostModifier)
      • getPassiveTrigger

        public EnchantmentDesc getPassiveTrigger()
        Describes an Enchantment that is active while the card is in the player's Zones.HAND.

        For example, to reduce the cost of a card each turn the card is in the player's hand, the "passiveTrigger" field should look like:

             "passiveTrigger": {
                  "eventTrigger": {
                      "class": "TurnStartTrigger",
                      "targetPlayer": "SELF"
                  "spell": {
                      "class": "CardCostModifierSpell",
                      "target": "SELF",
                      "cardCostModifier": {
                          "class": "CardCostModifier",
                          "target": "SELF",
                          "value": 1,
                          "operation": "SUBTRACT"
        See Also:
        for more about enchantments.
      • setPassiveTrigger

        public void setPassiveTrigger​(EnchantmentDesc passiveTrigger)
      • getPassiveTriggers

        public EnchantmentDesc[] getPassiveTriggers()
        Describes an array of Enchantments that are active while the card is in the player's Zones.HAND.

        Arrays in JSON are specified using []. Place what you would ordinarily put in the value part (to the right of the colon) for passiveTrigger into the brackets here. For example:

             "passiveTriggers": [
      • setPassiveTriggers

        public void setPassiveTriggers​(EnchantmentDesc[] passiveTriggers)
      • setDeckTrigger

        public void setDeckTrigger​(EnchantmentDesc deckTrigger)
      • getGameTriggers

        public EnchantmentDesc[] getGameTriggers()
        Indicates an Enchantment that is active as soon as the game begins (just after GameLogic.handleMulligan(Player, boolean, List), in the GameLogic.startGameForPlayer(Player) phase.

        Note that the GameStartEvent is raised twice, once for each player, so your EventTriggerDesc should specify a EventTriggerArg.TARGET_PLAYER.

        For example, consider the text, "Passive: You draw an extra card at the start of every turn." A passive is implemented as a game trigger, and typically it puts another enchantment into play. Observe that the GameStartTrigger is used to do something when the game starts, while the actual effect is implemented by a different enchantment:

             "gameTriggers": [{
                 "eventTrigger": {
                     "class": "GameStartTrigger",
                     "targetPlayer": "SELF"
                 "spell": {
                     "class": "AddEnchantmentSpell",
                     "trigger": {
                         "eventTrigger": {
                             "class": "TurnStartTrigger",
                             "targetPlayer": "SELF"
                         "spell": {
                             "class": "DrawCardSpell"
      • setGameTriggers

        public void setGameTriggers​(EnchantmentDesc[] gameTriggers)
      • getAuthor

        public java.lang.String getAuthor()
        Indicates the author of this card.

        This field will be migrated to indicate where this username originated from (e.g., Discord versus Reddit versus Spellsource).

      • setAuthor

        public void setAuthor​(java.lang.String author)
      • getFlavor

        public java.lang.String getFlavor()
        Stores flavor text provided by the author.
      • setFlavor

        public void setFlavor​(java.lang.String flavor)
      • getWiki

        public java.lang.String getWiki()
        Stores notes about the card's implementation or behaviour. Use this field to explain surprising rules or to do a FAQ.

        This field will be migrated to support Markdown syntax in the future for better rendering controls in the client.

      • setWiki

        public void setWiki​(java.lang.String wiki)
      • setBattlecry

        public void setBattlecry​(BattlecryDesc battlecry)
      • setDeathrattle

        public void setDeathrattle​(SpellDesc deathrattle)
      • getTriggers

        public EnchantmentDesc[] getTriggers()
        Multiple trigger objects that should come into play whenever the actor comes into an in-play zone.
      • getAura

        public AuraDesc getAura()
        The aura that is active whenever the actor is in a in-play zone (Zones.BATTLEFIELD, Zones.WEAPON, Zones.HERO). Card entities do not support auras, since they are not in play.

        Auras describe ongoing effects on other cards. They are updated at the end of a sequence (i.e., when actors are removed from the battlefield) and whenever the "board" (the three in-play zones) change. Updated means the affected actors are recalculated.

        Auras are appropriate for effects like Ironwood Golem, which reads "Taunt. Can only attack if you have 3 or more Armor.":

              "aura": {
                  "class": "AttributeAura",
                  "target": "SELF",
                  "condition": {
                      "class": "AttributeCondition",
                      "target": "FRIENDLY_HERO",
                      "value": 3,
                      "attribute": "ARMOR",
                      "operation": "LESS"
                  "attribute": "AURA_CANNOT_ATTACK",
                  "secondaryTrigger": {
                      "class": "ArmorChangedTrigger",
                      "targetPlayer": "SELF"
        Observe that this aura, an AttributeAura, has a condition to indicate when the specified attribute should or should not be present on the target (EntityReference.SELF). Also observe that the attribute is prefixed with AURA_ indicating that, as opposed to an effect that is applied once (e.g Attribute.CANNOT_ATTACK), it is an "aura" effect, and it won't be removed by a silence.
        See Also:
        for more about auras.
      • setAura

        public void setAura​(AuraDesc aura)
      • getAuras

        public AuraDesc[] getAuras()
        The auras that are active whenever the actor is in play.
      • setAuras

        public void setAuras​(AuraDesc[] auras)
      • getRace

        public Race getRace()
        The actor's race, or "tribe."
      • setRace

        public void setRace​(Race race)
      • getCardCostModifier

        public CardCostModifierDesc getCardCostModifier()
        A card cost modifier that is active whenever the actor is in play.
      • getBaseAttack

        public int getBaseAttack()
        The base attack of the minion. This will be the Actor.getBaseAttack() value.
      • setBaseAttack

        public void setBaseAttack​(int baseAttack)
      • getBaseHp

        public int getBaseHp()
        The base HP of the minion. This will be the Actor.getBaseHp() value.
      • setBaseHp

        public void setBaseHp​(int baseHp)
      • getChooseOneBattlecries

        public BattlecryDesc[] getChooseOneBattlecries()
        Whenever a CardType.MINION has choose one battlecries, the player will be given an option of which battlecry will be played for the minion.

        Typically, choose one battlecries that put a "different" minion into play will be implemented using a TransformMinionSpell. In this common situation, the client will render the choice card as the SpellArg.CARD argument of the spell, i.e., the minion the base minion will transform into.

        The SpellArg.CARD specified by the transform spell should not be collectible.

      • setChooseOneBattlecries

        public void setChooseOneBattlecries​(BattlecryDesc[] chooseOneBattlecries)
      • setChooseBothBattlecry

        public void setChooseBothBattlecry​(BattlecryDesc chooseBothBattlecry)
      • setChooseOneCardIds

        public void setChooseOneCardIds​(java.lang.String[] chooseOneCardIds)
      • getChooseBothCardId

        public java.lang.String getChooseBothCardId()
        Indicates the spell card that will be cast when Fandral Staghelm is in play, if this is a CardType.CHOOSE_ONE card.
      • setChooseBothCardId

        public void setChooseBothCardId​(java.lang.String chooseBothCardId)
      • getDamage

        public int getDamage()
        Indicates the amount of damage this CardType.WEAPON will deal (add to the attack of the equipping Hero).
      • setDamage

        public void setDamage​(int damage)
      • getDurability

        public int getDurability()
        Indicates the durability of this CardType.WEAPON.
      • setDurability

        public void setDurability​(int durability)
      • getOnEquip

        public SpellDesc getOnEquip()
        Indicates a spell that should be cast when the weapon enters the battlefield/an in-play zone, regardless of how it is put into play (i.e., unlike a battlecry, which is only activated by cards played from the hand).

        Contemporaneously, such effects are better implemented by aura.

      • setOnEquip

        public void setOnEquip​(SpellDesc onEquip)
      • getOnUnequip

        public SpellDesc getOnUnequip()
        Indicates a spell taht shoudl be cast when the weapon exits the battlefield/an in-play zone, regardless of how it is removed.

        Contemporaneously, such effects are better implemented by aura.

      • setOnUnequip

        public void setOnUnequip​(SpellDesc onUnequip)
      • setHeroPower

        public void setHeroPower​(java.lang.String heroPower)
      • getTargetSelection

        public TargetSelection getTargetSelection()
        Indicates what kind of target selection this CardType.SPELL or CardType.HERO_POWER has. Any choice other than TargetSelection.NONE will prompt the user to pick a target as filtered by the spell field's SpellArg.FILTER field.

        For example, to indicate a spell should prompt the user to choose any Murloc on the battlefield:

             "targetSelection": "MINIONS",
             "spell": {
                 "class": "...",
                 "filter": {
                     "class": "RaceFilter",
                     "race": "MURLOC"
        Observe that a "target" of EntityReference.ALL_MINIONS is not specified on the "spell" field; the target is set to the player's choice, as filtered by "filter".
      • setTargetSelection

        public void setTargetSelection​(TargetSelection targetSelection)
      • setSpell

        public void setSpell​(SpellDesc spell)
      • setCondition

        public void setCondition​(ConditionDesc condition)
      • getGroup

        public SpellDesc[] getGroup()
        Indicates the subspells/subcards of this CardType.GROUP.

        Used for Adaptation effects.

      • setGroup

        public void setGroup​(SpellDesc[] group)
      • getCountUntilCast

        public int getCountUntilCast()
        Indicates the number of times the quest trigger needs to fire until this quest's spell is cast.
      • isCountByValue

        public boolean isCountByValue()
      • setCountUntilCast

        public void setCountUntilCast​(int countUntilCast)
      • entrySet

        public java.util.Set<java.util.Map.Entry<CardDescArg,​java.lang.Object>> entrySet()
        This makes it possible to iterate through a CardDesc.
        Specified by:
        entrySet in interface HasEntrySet<CardDescArg,​java.lang.Object>
        An entry set for this instance.
      • revealsSelf

        public boolean revealsSelf()
        Indicates whether, based on the code written on this card, this card ever reveals itself.
        true if any spell written on the card is a RevealCardSpell with target EntityReference.SELF