Blue Dismantler AutoHotkey Script
Desktop Application — Multiplatform
March 2021 - April 2021
Solo Project
March 2021 - April 2021
Solo Project
The Problem
I have played loads of MMOs throughout my life, but something that has always annoyed me about some popular MMOs is vendor trash. Despite its disparaging name, vendor trash does serve a purpose in the many games you might encounter it in. In most games, it serves as a steady stream of game currency to reward players with for playing the game regardless of what they are doing. These items are typically generic, low-level equivalents of more sought after gear or unequipable, untradable items whose sole purpose is to be sold to an item vendor for a small amount of currency. Hence the name Vendor Trash.
In my latest MMO endeavor, Destiny 2, vendor trash takes the form of low rarity items that players receive as random drops from enemies or as a rewards for playing playlist activities. Thankfully, the white-rarity items (the lowest rarity in the game) aren't awarded outside of scripted new-player experiences. The lowest rarity item regularly rewarded in game are Rare (blue) items. In Destiny, blue items have a chance to drop at a higher Power level than what a player has in their inventory; however, this is only true if a player's overall Power level is below a certain threshold called the Powerful Cap. Above this level, only rewards from "Powerful" sources drop gear above the player's current level rendering random blue drops basically vendor trash. With the sole exception of a pair of Hunter gloves with the strange ability to drop with a unique stat spread, having to regularly dismantle Rare drops (or "blues" as we call them) manually gets tedious.
Since a player inventories in Destiny are relatively limited, blues can take up valuable space quickly and overflow into the Postmaster (Destiny's "Hey, you forgot this," and inventory overflow solution) if not dismantled with some regularity. There is no "dismantle all" or "mass dismantle" function in Destiny and no way to mark items for dismantling; everything must be broken down manually, one at a time.
In unrelated news, I recently discovered AutoHotkey, a specialized scripting language designed specifically for automating tasks on the desktop. I wonder if I could use it to solve my vendor trash problem...?
In unrelated news, I recently discovered AutoHotkey, a specialized scripting language designed specifically for automating tasks on the desktop. I wonder if I could use it to solve my vendor trash problem...?
Why AutoHotkey?
Around the time I started this project, I was in the mood to learn some new tools. While I was comfortable making tools as desktop applications, console applications, and scripts for commercial game engines, I had yet to dip my toes into more lightweight utilities. AutoHotkey (AHK) is built with this exact use case in mind while still offering enough control and performance to build out heavier standalone applications. In fact, the IDE I use to write AutoHotkey scripts, AHK Studio, is built with AutoHotkey and is an open source project on GitHub. Once I had discovered AHK and the flexibility and power it offered me, I went to work automating every little inconvenience I encountered on the desktop for fun. Eventually, I figured I could use this new tool to rid myself of the inconvenience of manually dismantling vendor trash in games ever again.
|
|
Detecting Items
My first major hurdle in this project was detecting the rarity of an item in an inventory slot. While this might seem trivial at first, remember that AHK is not being used as a plugin or mod for Destiny 2 in this case; I do not have access to any information about the game state. I could have used the Bungie.net API to fetch the relevant inventory information before dismantling, but that has two main problems.
- Bungie's API does not allow you to initiate any destructive action such as dismantling an item.
- I would have to interface with a whole mess of authentication and security just to fetch some information about the character I am currently logged into.
My method for identifying item rarity is simple. I inspect a single pixel from the screen and see if it's the right color. Ingenious, I know. Unfortunately, given my limitations this was about all I could do. If I were to release this script to a wider audience, I would jump through the hoops necessary to fetch the relevant item information via the Bungie.net API. For now, though, this would have to do.
My first step would be to figure out where in screen space inventory slots would appear and which pixel within each item frame I should sample. This first part of this step was soon plagued by a problem that I will talk about in more detail later, but finding which pixel to sample within an item frame was mercifully simple thanks to the UI/UX team at Bungie adhering to consistent design patterns.
My first step would be to figure out where in screen space inventory slots would appear and which pixel within each item frame I should sample. This first part of this step was soon plagued by a problem that I will talk about in more detail later, but finding which pixel to sample within an item frame was mercifully simple thanks to the UI/UX team at Bungie adhering to consistent design patterns.
All equippable items in Destiny are split up into two major categories: Weapons and Armor. Weapons show up to the left side of your character and armor to the right. Within these categories are yet more classifications. Weapons have three slots they can occupy: kinetic (the top slot), energy (the middle slot), and power (the bottom slot). Most importantly, the item icons within each of these classifications are consistently oriented in the same direction. Kinetic weapons always face left, energy and power weapons always face right. This combined with the fact that the art team at Bungie have chosen to display an item's rarity via its icon's background color meant that item frames had dead zones where I could reliably expect an item icon's background color to be showing through.
Within each character class, character armor is also consistent in which direction it faces for each sub classification of armor slot. Helmets on Warlocks always face right, gloves always face left, and so on. |
Once I knew where to look, all that was left was for me to sample the correct area of each item's frame and see if it was blue. If it was, I could safely dismantle that item. If it wasn't, I could move on. While I was at it, I also took the time to sample the color of "Rare" rarity items while using different colorblind modes so that I could send this utility to my colorblind friends and not worry about accidentally dismantling something valuable of theirs.
Cursor Placement
Now that I knew where within each item frame I could look, I could set my cursor on top of the currently equipped item in any slot and scan across that slot's sub menu in search of blues.
At first, this wasn't a huge problem for me. While testing, I settled on some hard-coded values that were close enough for me to test the rest of my code knowing that I would later have to find a generalized approach for placing the cursor around the screen that adapted to different screen resolutions and aspect ratios. What I failed to immediately recognize was a subtle UI effect Bungie had built into nearly every menu in Destiny. UI elements have a slight parallax effect to them that follows the cursor's position on screen. To make matters worse, the rate of the parallax motion is not the same horizontally as it is vertically. To make things worser, it appeared that screen space in Destiny was different depending on if the game was being rendered in Windowed or Fullscreen mode even if they were set to the same resolution. This subtle effect ended up being responsible for most of the tinkering and bug fixing I had thought came from my own code up to this point. I gave myself some time to let the abject horror of my discovery wash over me.
|
Once I sat back down, things got a lot better. The strange window resolution reporting comes from the way windows report their own resolution in Windows. The extra screen space comes from the navigation bar at the top of the window. Simple enough fix.
The parallax effect in the vertical direction is so subtle that I could basically ignore it. The mouse's position would vary by 3-4 pixels at the most, not nearly enough to put the mouse outside of an item frame. The parallax effect also seemed to scale along with screen size. The higher the resolution of the display, the more pixels the mouse would have to move before the UI shifted.
This left me with one issue to tackle: horizontal parallax. To measure the parallax effect, I created another script that moved the mouse cursor horizontally across the screen, measured how much item frames moved along the way, and dumped the results to a text file. Turns out, the parallax effect is (thankfully) linear. To compensate for this, I made a function that took in an x-coordinate in screen space and returned how much to offset the mouse cursor given its intended destination on screen.
With that beast conquered and my new parallax compensation function in tow, all I had left to do was describe the position of each item frame in item sub menus (the nine boxes that expand out from the currently equipped item in your inventory) relative to the equipped item frame. Lastly, I came up with a method of offsetting the cursor from the center of an item frame to reach the corners where I would be sampling pixels from. And with that, I could now place the cursor on any item icon in the player inventory screen and offset it to any corner of that box.
Script Customization
I now had a functional item classifier and dismantler, but I wasn't satisfied just yet. There were multiple in game settings a user could have that could throw my script out of whack. As mentioned before, Windowed and Fullscreen modes had a strange effect on the application's reported screen space. There were also colorblind modes that I had to account for, character classes that affected the safe zones for where I could sample pixels for armor from, and script controls that users could not change.
To address this, I included a config file with the script that you could edit to change these behaviors to suit your needs. On startup, the script reads this config file and adjusts its behavior accordingly. I also created a README that described what these config options could be configured to and how they affected the script behavior. |
Plans for the Future and Known Issues
The script as it stands today is up on my GitHub page for download. AutoHotkey also has the ability to compile any script into an .exe alongside any supporting files like my config.ini and README.md.
Currently, the Blue Dismantler works entirely via shortcut commands and has no GUI at all. Since AHK has the ability to draw windows, I plan on creating a GUI mode that the script will launch in by default that allows users to change their config settings, restart the script, or initiate/cancel dismantling manually. I also plan on adding support for dismantling items in different menus like the Postmaster and Vault. Lastly, if enough people show interest in the tool, I'll likely rebuild it correctly so that it uses Bungie.net API calls to fetch item rarities instead of sampling pixels from the screen.
The script also has some bugs that come from abnormal screen resolutions and aspect ratios. Currently, the script makes cursor movements in screen space which is to say everything is offset from the top left corner of the window. For people using ultra-wide monitors, however, it is easier to offset the cursor from the center of the screen since Destiny's UI is centered in the screen at every resolution. Padding the horizontal resolution of the window only adds dead space to either side of the character menu. If I change this behavior in the future, I'll be looking for pixel density instead of window resolution to determine my offsets. Finally, Destiny has another UI/UX feature that highlights newly acquired items in your inventory periodically until you mouse over them for the first time. If this highlighting effect happens to coincide with a dismantling routine, my script sometimes misclassifies items and fails to dismantle them. This is another thing that the Bungie.net API workflow would resolve.
All in all, I'm happy with my little tool. I have added a few functions here and there such as the ability to only search specific parts of your inventory to avoid sweeping the full inventory unnecessarily, but the bulk of it remains unchanged. This little project taught me a lot about AHK and its potential, and I feel much better equipped to create quick and dirty automation tools for repetitive tasks anywhere on my computer. While I don't think I go about this project the same way I did the first time around, I'm content to have made something that works rather quickly, learned some new tricks along the way, and solved my vendor trash problem. A fun little project.
Currently, the Blue Dismantler works entirely via shortcut commands and has no GUI at all. Since AHK has the ability to draw windows, I plan on creating a GUI mode that the script will launch in by default that allows users to change their config settings, restart the script, or initiate/cancel dismantling manually. I also plan on adding support for dismantling items in different menus like the Postmaster and Vault. Lastly, if enough people show interest in the tool, I'll likely rebuild it correctly so that it uses Bungie.net API calls to fetch item rarities instead of sampling pixels from the screen.
The script also has some bugs that come from abnormal screen resolutions and aspect ratios. Currently, the script makes cursor movements in screen space which is to say everything is offset from the top left corner of the window. For people using ultra-wide monitors, however, it is easier to offset the cursor from the center of the screen since Destiny's UI is centered in the screen at every resolution. Padding the horizontal resolution of the window only adds dead space to either side of the character menu. If I change this behavior in the future, I'll be looking for pixel density instead of window resolution to determine my offsets. Finally, Destiny has another UI/UX feature that highlights newly acquired items in your inventory periodically until you mouse over them for the first time. If this highlighting effect happens to coincide with a dismantling routine, my script sometimes misclassifies items and fails to dismantle them. This is another thing that the Bungie.net API workflow would resolve.
All in all, I'm happy with my little tool. I have added a few functions here and there such as the ability to only search specific parts of your inventory to avoid sweeping the full inventory unnecessarily, but the bulk of it remains unchanged. This little project taught me a lot about AHK and its potential, and I feel much better equipped to create quick and dirty automation tools for repetitive tasks anywhere on my computer. While I don't think I go about this project the same way I did the first time around, I'm content to have made something that works rather quickly, learned some new tricks along the way, and solved my vendor trash problem. A fun little project.