The Blizzard team has realized that WoW players love to reminisce about their game. We love to play old dungeons, level more characters, and collect appearances from this legacy content. Last summer, Blizzard introduced a gameplay mode called "Remix". This limited-time playstyle encouraged leveling new characters in order to collect all of the available items. Each of these collectable items provided a cosmetic appearance that all of your characters could use. The interesting dilemma here is tracking appearances your account still needed to collect.
For many, the UI was the easiest method to track. You could walk up to a vendor and compare what your account 'knew' versus what was available. "Easy" except the UI required that you change your class to see what you collected. Does my druid have this set? Open appearances, change class to druid, scroll until finding Mists of Pandaria collections, check the various raid-tier levels. Second option was a spreadsheet variant. Some diligent people went through all the vendor offerings, got the names and cost of all the items. When you went to the vendor, you'd mark off all the items you purchased. Neither of these options really appealed to me.
In an effort to find a better way, I investigated coding against the API. Could a Google Sheets make a call and populate the completion statistics for me? Would it be easier to code against WoWhead's api and query data? I even investigated learning LUA and writing my own addon that would help. This lead to my own analysis paralysis and soon after the end of the Remix event.
Fast forward 6 months and Blizzard introduces two new achievements based on past expansions. "A Farewell to Arms" and "A World Awoken" are meta-achievements that require completing a number of events, reputation grinds, and collecting treasures in the game. Completing each of these achievements, rewards the grand prize of an iconic mount from that expansion. I mean, who wouldn't want to transform into "Jani Lord of Thieves, God of Garbage, Master of Minions, and Ruler of Rubbish". This, along with my current work with python had peaked my interest.
Project plan: Using local copy of Python, connect to Blizzard's API and query the character achievement tree. Look for any achievements that are marked as incomplete and provide them as a simple HTML page.
Step 1: Create an account on Blizzard's
developer portal. After agreeing to all the legal things, you're provided with a client id and secret. These credentials are passed in the headers to the authentication portal and a refresh token is provided. This refresh token is put into a JSON structure to create a bearer token. The bearer token is passed each time calling the Blizzard API. All this is identical to how to authenticate with Aria. So far so good.
Step 2: Read character's achievement stack. This is an easy call to the API. The returned JSON provides (almost) every achievement that is available and their status. Issues I found:
- Achievements are presented in a flat format. The main meta-achievement has 8 child criteria. The child criteria, while listed there are not achievement ids, they are criteria ids. Took me awhile to figure that out.
- There are holes in the results. None of my characters have completed the "Storm Chaser" achievement. This meta-achievement is to complete all 4 different 'elemental storms' events in all 4 zones. This achievement doesn't show in the API results for the characters. (I bet if I complete one of the 4 zone achievements, Storm Chasers will appear in my query.)
- Last, some of the achievements are character-based. So, while my main character may have petted all the dogs in DragonFlight, my new alt still shows the achievement incomplete.
New Step 2: Read the generic achievements stack from the API. Using a recursive loop, go through the achievement id by id and pull all children. Return all of the child achievement ids in an array. Loop through the character achievement results for completed achievements and report back on what is incomplete. This solution avoided the holes in the API. I was able to query the entire tree and present a high-level result. Unfortunately, it looks like I still have close to 70 achievements to complete. I decided to implement a few optimizations:
- While querying the achievements tree, I now build a dictionary (ie PowerShell hash table). The dictionary equates parent achievements to its children. This allowed me to optimize the code to say, if you completed this parent, all the children can be assumed completed.
- Everything is written to the local drive. I was having issues where the time between runs was several minutes, especially when recursing the achievement tree. So on initial run, each achievement JSON, the achievement tree and the achievement dictionary is written locally. At the moment, I am also reusing old character achievement JSON dumps, but that may be updated. The final report now completes in seconds instead of minutes.
- The final report only includes items with no children. Using the dictionary, I look for achievement entries that don't have children listed and focus on those. My report that used to show I needed "Storm Chasers" and "Chasing Storms in Waking Shores" and "Firestorms in Waking Shores", now it only shows the "Firestorms" entry.
This leaves one issue unresolved. Some of the incomplete achievements are character based. As of writing this, my solution is to run the same code against my alternates that played through that expansion and manually compare notes. The druid leveled via hunts, where the paladin favored the pvp type activities and so on. My plan is to pull all my max level toons from my account, query their completion status and combine into a master list. If any of these 8 characters says this achievement is complete, then consider it complete. I am running into a permissions issue as my developer credentials do not allow querying private account details.
With the Legion Remix on the books for "soon"(tm), I am that much closer to achieving my goal of a dynamic shopping list. Once I have code, need to consider how I can share it. I personally like the idea of an external website that I can review from outside the game (while here in office). I'll try to keep you posted.