AI Decklists - Zero-to-Heroes/firestone GitHub Wiki
Starting with 4.3, Firestone supports showing the decklists for some AI opponents. As of the writing of this page (30/01/2020), the following decklists are supported:
- Tombs of Terror, Normal and Heroic
- Galakrond's Awakening, Normal and Heroic
- Innkeeper, Normal and Expert
Data collection
The contents of each decklist is built by parsing all the games I have that feature this specific opponent (and games are split by scenarioId as well, which among other things separate Normal from Heroic difficulties).
When parsing a game, I do a few things (you can find the source code here):
- I assign each entity to a player. The first player to be declared a controller of an entity is considered the owner of that entity
- I parse all the cards that have a revealed card ID. Then I filter them to keep only the cards that are controlled by the opponent
- I filter out a few cards to try and keep only the cards that started in the player's deck. This means that I:
- Remove entities that have a CREATOR or CREATOR_DBID tag
- Remove entities that have a TRANSFORMED_FROM_CARD tag
- Remove entities that have a TOPDECK tag. These usually are cards revealed in joust-like mechanics, and I found a few instances where they would show irrelevant cards
- I also filter out a few cards, like Spellstone upgrades. This means that if one day an AI has an upgraded version of the spellstone in their starting deck, I won't be able to list it.
- After the full data is collected, I do some cleaning to try and remove errors (the rule is that a card is seen less than 1/100th the time of the most seen card in the deck, it's an error).
There is also some handling for bosses that have different phases, like the Plague Lords in ToT, to try and assign a specific deck to each phase.
Caveats
There are two main caveats with the AI decklists:
- We have no single source as to what is in an AI's deck. The decklists are reconstructed by parsing all the matches that Firestone players have played against the AI, and guessing what the possible decklist could be. As a result, the fewer encounters there has been against an AI (like Pyramad), the less reliable the decklist is. Also, it's possible that some errors have crept in the processing itself :)
- The Dungeon Run-like encounters like Tombs of Terror sometimes seem to run pseudo-randomized decks. This means that there is a known pool of cards from which the AI deck is built, but the exact composition of the deck is unknown. The tracker thus shows the cards that might be in the deck, rather than the definite content.
Known bugs
- Puppetmaster Lazul (in Galakrond's Awakening) does not have an unambiguous trigger in the logs when she switches form and gets the new deck. I don't really want to hard-code the behavior for this encounter yet, so for now the decklist is not available
- Reno's deck (in GA, Heroic) is missing a card, probably Raid the Sky Temple
Data
Getting data
The contents of all the decklist is publicly available for you to play with. To get the data:
- Download the file at https://static.zerotoheroes.com/hearthstone/data/ai_decks/all_files.json. It lists all the files that contain AI deck data
- Download each separate file, e.g. https://static.zerotoheroes.com/hearthstone/data/ai_decks/innkeeper_expert.json
The format of each file is not fixed (meaning I don't guarantee any kind of backward compatibility), but it roughly looks like this:
[
{
"comment": "Tombs of Terror Vesh, Plague Lord of Murlocs deck (Normal) (120 games)", // A description of the deck, usually also an indication of how many games were parsed to build the list
"opponentCardId": "ULDA_BOSS_39h", // The ID of the opponent's hero cardID
"scenarioIds": [ // The scenario in which this deck is valid. Mostly for normal vs heroic distinction
3428
],
"deckstring": "AAEBAfC2AwjgBdoP0hatvALzvQLjvgKcmwObqQMKpwjmf5GtAvmzAuO7ApHBAobEAoyUA6+nA8qrAwHhpQMD", // The deckstring of the AI starting deck
"totalCardsInDeck": 31,
"cards": { // The list of cards with the number of copies
"EX1_507": 2,
"EX1_062": 1,
...
},
"totalCardsSeen": { // The number of times each card has been seen
"EX1_507": 142,
"EX1_062": 66,
...
},
"cardNames": { // Card names, for debugging purposes mostly
"Murloc Warleader": 2,
"Old Murk-Eye": 1,
...
},
"decks": { // Some bosses can change forms and gain new decks. This is indicated by a HERO_DECK_ID tag, and you can fetch the deck information from this ID in the following structures
"2238": "AAEBAfC2AwjgBdoP0hatvALzvQLjvgKcmwObqQMKpwjmf5GtAvmzAuO7ApHBAobEAoyUA6+nA8qrAwHhpQMD",
"2239": "AAEBAfC2AwPjvgKRwQKcmwMN4AX4B8ET3xTSFr8Xka0C2q0Cib8CutIC4okD4aUDr6cDAZrEAgM=",
"2240": "AAEBAfC2AwTgBdoPuhTjvgIO+AfSFr8X2q0Ct68ChsQCmsQC4okDjJQDnJsD4aUDr6cDm6kDyqsDAA=="
},
"deckTotalCardsInDeck": {
"2238": 31,
"2239": 32,
"2240": 32
},
"deckCards": {
"2238": {
...
},
...
},
"deckTotalCardsSeen": {
"2238": {
...
},
...
},
"deckCardNames": {
"2238": {
...
},
...
}
}
]
Data correctness
One of my first checks was to compare the data produced to the decklists filled in the Hearthstone wiki. And they did not match :)
More specifically, the wiki assumes that each card has a known number of copies (usually 1 or 2, maybe more). However, I found instances of games were the actual number of copies played differed from what was in the wiki.
For instance, if you look at Vesh, first phase, in Normal at https://hearthstone.gamepedia.com/Vesh,_Plague_Lord_of_Murlocs. The wiki says that there is only one copy of Mrgl Mrgl Nyah Nyah in its first phase, and one copy of Plagues of Murlocs. However:
- http://replays.firestoneapp.com/?reviewId=5dc84b893f588f000107998f&turn=14 shows 2 copies of Mrgl Mrgl Nyah Nyah being played
- http://replays.firestoneapp.com/?reviewId=5dc7aa21b42e09000168a3fb shows 3 copies of Plagues of Murlocs being played
So this has led me to think that the decks are always somewhat randomized. Let me know if you can prove me wrong though :)