Model - HearthSim/SabberStone GitHub Wiki

Entities

class dependency diagram Entities are basic objects representing all things in Hearthstone Game, including the Game itself and Controller. All attributes of an entity is stored as a related GameTag and its value. Some static attributes like name and type of the entity should be derived from Card, which contains all primitive data and Tags for a particular card from the Hearthstone.

To create an entity we need Card object, which contains all data directly parsed from CardDefs.xml. Each entities references the base Card when a user requests Tags information about the entity.

Each entities has its own container for Tags. SabberStone leaves Card as immutable object and saves any variations on Tags in each entities. So, any acquired tags and attributes that are different from the original card value are stored in the container.

Entity has an additional container for recording Tag variations from external Auras.

Ultimately, to gain a particular tag value from an entity, we have to look into these three containers. First, we seeks the non-static container first. If it does not have one, we have to search Tags in the Card object which is used to create the entity. If it also do not have the tag, we finally gets a value of 0. If there exists any external aura related to this tag, we add the aura value to the acquired value.

The Tags and values can be referenced by indexer, or iterated through foreach, as IEntity interface inherits IEnumerable<KeyValuePair<GameTag ,int>> and has int this[GameTag t].

Example: How Faceless Manipulator copies and transforms into an another entity?

First, we should think about which kind of data the manipulator needs to transform. Maybe it includes the name, unique card effects of the given target, current ATK, HEALTH, and applied enchantments such as Ancestral Spirit or Corruption. Let's separate information into three kinds.

  • Static data from the card underneath the target entity.
  • Changed or given attributes as an entity.
  • Applied Enchantments

To get the first data, Manipulator have to seek which card is used to create the target entity, and should take it as a base. The attributes in Card is essentially immutable, so that he don't suffer from nerves when he gets the data. So, the Manipulator just looks into the Cards class and obtain the proper card data. He also needs some information about variations in attributes. This category of data contains Tags like "NUM_TURNS_ATTACK_THIS_TURN", "ZONE_POSITION". In this moment, we naturally figure out that there should be a container for this kind of information in each entity object. So, the manipulator should take these 'acquired data' from the container of the target entity and copy to its own container. Finally he makes clones of the applied enchantments of the target and re-applied them to the transformed self.

In Hearthstone, Faceless Manipulator is not really transformed into the target. What happens under the hood is he creates new entity with the acquired information and replace himself with the new entity. So, What Sabber does is

  1. Gets the Card, all GameTag values, and applied Enchantments from the target entity.
  2. Create new entity with the Card and Tags.
  3. Replace the Manipulator with the new Entity.
  4. Re-apply the enchantments to the new Entity.