Re-introducing Public TSM Groups

Since the launch of the new TSM website, we’ve had a lot of feedback about the missing directory of publicly shared group imports.

While it’s easier than ever to make your own groups in-game by searching the Base Group, or using Wowhead to leverage more powerful filters – we wanted to improve the way you find and use community-made groups on the web. It wasn’t quite ready for the recent relaunch of the overall website but we’re excited to announce that it’s back and the first iteration is ready to use!

As was the case with the old TSM website, the ability to search for and use these groups will remain free and does not require a TSM Premium plan.

You can access groups by using the global search bar or via the Groups menu option in the navigation bar. When opening the page you’ll see a list of popular groups, groups you have looked at recently, and a link to view all of the groups shared for the game version selected. The page is always pre-filtered based on the game version you have selected in the top right of the page, so you won’t see Classic Era groups mixed in with Retail groups for example.

If you search for a particular item in the global search bar or on the Groups main Browse page, you’ll see published groups in the results along side the item itself. This is very handy to find groups you might be interested in using based on the item you want to group.

The first major evolution to the system is that they can also include operations associated with the group. This is possible because the way groups are published is based on what a TSM user uses in-game, rather than collecting some item IDs from Wowhead which was the only option on the old website.

If you’d like to use a group you can click on the Add to Addon button to generate an import string to be copy and pasted in-game.

Publishing Groups

There are two ways to publish a group on the TSM website.

Clicking on the My Published Groups sub-menu item will show a list of currently published groups. From here you can click on Import From String and copy and paste the import string that can be manually exported from any group in-game. Learn how to export a group from the TSM knowledgebase.

Alternatively, if you are a TSM Premium (Gold) subscriber, all of your groups are synced to the website automatically so you can publish them from directly from the My Addon Groups tab after selecting the appropriate WoW Account and TSM Profile.

Once published, you’ll get a shareable link you can provide your friends or community and the group will appear in the public directory. You can however opt to make the group ‘private’ so only those with a link can access the group if you’d prefer not to have the group included in the public directory.

Future Improvements

We have a lot of other ideas to improve the process of finding and managing groups on the TSM website including showcasing published groups that contain a particular item when you view that item page and introducing a rating system to share feedback.

Additionally, with a TSM Premium plan, we’re exploring options to synchronise a group to the game directly via the TSM desktop app to skip the manual importing process. This could also enable some cool mechanisms such as ‘subscribing’ to a particular published group so you would be able to keep up to date with any changes or updates without having to think about it.

We’d love to hear your feedback on how you used the old version of the public TSM groups feature, what you like or dislike about the newly revamped version, and what you want to see out of it in the future!

Announcing the new TSM Website and Premium Plans!

We’re super excited to announce the launch of a brand new TradeSkillMaster website to elevate your gold making in The War Within and Classic World of Warcraft!

Along side a new website, rebuilt from the ground up – our TSM Premium offering has evolved in to multiple plans which are stuffed with brand new features and quality of life improvements to take your gold making even further.

If you’re an existing TSM Premium subscriber and are mostly interested in what happens to your current subscription, please check out this supplemantal support article that covers the possible scenarios, including keeping your existing subscription.

Let’s get started with what’s in store on the brand new TSM website.

The homepage now features a few important tools that will help you get an understanding of what’s going on with the Auction House – and what’s going on with your gold making activity, if you’re logged in.

You’ll first notice a heatmap of items and item categories that show trends in market value (red for declining trends, green for increasing trends) and volume of auctions (the bigger the square, the higher the volume) on your realm or your region – for the the version of the game you have selected on the homepage.

From here you can drill down in to a category, and then an item, to see current trends in price data at a glance. For example let’s look at Cooking Reagents.


Here we can see that cooking reagents are overall down in price trending when comparing the market value and historical value by -24.2%, then selecting the Reagents category the Cooking category shows individual items including Basically Beef trending down in price by -12.7% (perhaps oversupplied?) and Leyblood trending up by 505% (perhaps new demand?) – there’s also a tally of current volume of auctions for these item categories and individual items.

Let’s drill down further into Basically Beef as an item and check out the item page to see what’s going on in more detail.

At the top of the page we can see a summary of the item’s TSM Market Value, a confirmation of the current trend of the Market Value compared to the Historical Value, the current quantity on the Auction House – and if you’re logged in with TSM Premium (Platinum) an overview of your current inventory data across characters and the Auction House.

We also see an Auction House Quantity trend chart, showing volume of auctions for this item over time – coupled with your recent gold making actions pulled from your Ledger automatically, with TSM Premium (Platinum). In this example I might see I have a bunch of stock not listed and decide to log in and post them to the Auction House before the trend continues to fall, or realise I don’t have any stock on hand and decide to scoop any deals before the trend reverses.

Moving down the page, with a TSM Premium (Platinum) subscription, we see more visualisations representing the Region Sale Average and Region Sold Per Day values – information you’d usually only see in-game in the item tooltip. All of the tooltip information is also surfaced in the Item Statistics section to the right – including your personal Ledger and Accounting data for sales, purchases, sales, and sale rates. This data is available if you’re logged in with an active TSM Premium subsription.

The entire Auction House is your oyster now, giving new insights in market vs historical trends outside of the in-game addon for you to browse and research at any time. Time to start exploring!

Before moving away from the item page – you may have also noticed the ‘Alerts’ button at the top of the page. We’re very excited to introduce a more robust item notification system which includes realm, region, BMAH alerts via email and now also via Discord with a TSM Premium (Platinum) subscription!

It’s quick and easy to enable an alert from the item page, simply select the realm or region and your notification option, along with the price threshold and you’re all set. You must connect your Discord Account through OAuth in the TSM Account Management page in order to receive Discord notifications.

Ledger

The Ledger has had a coat of paint and now shows better charts and statistics based on your in-game gold making activity. The Ledger will continue to evolve over time as it is fully integrated in to the TSM website and new data flows are established from the in-game addon.

Groups

We’re also now making it easier than ever to view your in-game groups outside of the game via the Groups tab on the new TSM website. As a starting point, with TSM Premium (Gold) subscription, you can view the groups and the operations assigned to them separated by profile and also by account.

From here you can also opt to Publish your group to create an easy-to-share link with a friend or the TSM community – which will allow an easy import of the group and operation in one go in-game

Website Future

The new TSM website is a foundation for a lot of things we want to do in future, including more Auction House analysis tools, and more ways to understand your own gold making activity and to help you make more informed decisions on what you should or could do to improve your strategies.

We have a dedicated team working on it full time so we’ll be introducing new features and pushing out updates frequently now that it has been introduced to the world.

For the launch we have opened a new channel in Discord where you can share your feedback or ideas, and report any bugs you might encounter as you’re exploring and discovering our new website.

TSM Premium

With the launch of the new website, we are also revamping the TSM Premium offering with many more features described in the post above, and many more to come.

As of today September 4th, 2024 TSM Premium will be offered at two tiers, each with their own price point and access to features. The Premium plan offered before September 4th, 2024 will no longer be available to new subscribers.

TSM will always be available for free, which gives access to the TSM Desktop Application with TSM Price data and basic Auction House analysis on the website.

TSM Premium will now be offered at a Gold tier and a Platinum tier.

TSM Gold subscriptionTSM Platinum subscription
Support TSMEverything in the Gold subscription tier
Basic analysis of recent sales and purchases in Ledger (your personal TSM data)Extensive analysis of sales and purchases in Ledger (your personal TSM data)
View BMAH auctions on the TSM websiteTrack gold making performance on the dashboard and item pages
TSM Addon setting backups synced to the cloudView sale price and quantity graphed over time on item pages
Email alerts for items on your realm, region, or BMAHUnlimited realms for price data in the TSM Desktop application
Up to 25 realms for price data in the TSM Desktop applicationDiscord alerts (in addition to email) for items on your realm, region, or BMAH
Great Deals synced to your in-game addonSpecial Discord Role with access to exclusive channels / TSM roadmap insights and input
TSM Premium Role in Discord
Priority TSM beta program access

Price Changes

TSM Gold will start at just $3.00 US per month, while TSM Platinum for all the extra benefits and features will start at just $7.50 US per month, each while billed annually. Monthly and bi-annual options are also now available for each plan.

Current Subscribers

To celebrate the launch of our new Premium offerings, all current TSM Premium subscribers will gain access to the Platinum TSM Premium tier for 6 months at no extra cost!

If you’re a current subscriber and want to know what to expect during and after those 6 months, we have prepared a supplemental support article that covers all of the scenarios – including keeping your existing subscription.


We’re thankful for you being part of the TradeSkillMaster community, and hope you enjoy the new website and can benefit from all of the new enhancements to the TSM Premium offering.

We are Hiring a Senior React Front-End Developer

EDIT: This position has been filled. Thanks for your interest.

The TradeSkillMaster team is a small group of gamers who love to learn new skills and constantly push the boundaries of what TradeSkillMaster can do for our users. What started as a small addon has grown into a comprehensive gold making addon, desktop application, and set of web-based tools and resources. We are driven by self-improvement and creating a great set of products and services for our users, while working in an efficient, but low-stress environment.

We are always exploring new ways to improve the experience we offer to our users. To that end, we are looking to add an experienced React Front-End Developer to the team in order to deliver a new web project to our hundreds of thousands of users.

The Role

As a part of this role, you will be expected to work closely with other members of the team to turn UI/UX designs into high-quality, responsive, and accessible front-end applications.

This position is short-term (2-3 months), full-time and paid. The work will be purely remote with EU time zones strongly preferred.

About You

Qualifications:

  • Strong technical background in JavaScript and TypeScript. Good code design sense with an emphasis on UI and data processing.
  • Expertise and experience in React and Remix, creating components for data-driven APIs.
  • A proven ability to work in established code bases as part of a team and self-motivation to constantly improve code quality and processes.
  • Experience with TradeSkillMaster and a passion for improving it

Ready to join us? Send me (Sapu) a message on Discord (https://discord.gg/woweconomy). Come prepared with your resume and any questions about the role you may have.

Announcing TSM 4.14 Beta Test!

As the launch of The War Within expansion draws near, we’re very happy to announce the Beta test of the 4.14 addon update to TradeSkillMaster! If you’re a Premium member you will shortly be receiving an email inviting you to participate, along with instructions on how to get started.

Additional invites through our Beta sign-up page will be distributed on a First-In-First-Out system, so make sure you sign-up if you’d like to get involved!

Let’s take a look at some of the major features 4.14 brings!

New Sniper Mechanism

Patch 8.3 in Battle of Azeroth changed the way the Auction House works fundamentally. Blizzard removed the concept of ‘pages’ and since then all items are essentially part of the same pool of auctions for a given realm or region.

This caused some changes to the sniper behaviour for TSM in Retail which deviates from the original style of sniping that’s available in Classic WoW. So to try and close that gap and improve the efficiency and capabilities of TSM Sniper in Retail, we have introduced some changes to the way the Auction House is queried during a Sniper scan. If you’re familiar with other Sniper-focused addons, such as Point Blank Sniper (PBS), TSM 4.14 will function in a similar way.

Additionally, in Retail you’ll be able to apply a Sniper Operation to the Base Group just like you can in Classic (or in Retail prior to WoW patch 8.3), allowing for Sniping of items that are not otherwise grouped.

Secondary Realm Market Data

After region-wide trading was introduced in Dragonflight, we have been exploring how we might enable easier arbitrage between realms without overloading the addon with data and consuming all of our bandwidth quotas.

As a first step in this arena we have added the option to display some Price Sources such as Minimum Buyout and Market Value from one other realm that you have added to your TSM Desktop Application in your Tooltip Settings.

We hope this will enable some arbitrage opportunities with a specific realm that you may have gold-making activity on – we understand that discovering and identifying those opportunities is important and we’ll continue to explore supporting that type of analysis outside of the game with our new and improved website suite coming soon.

Scroll Table Improvements

Scrolling tables make up a lot of the UI of TSM, such as the interfaces for Mail, Vendoring, most of the Auction House, and your profession window.

It can take a lot of resources to create and update these tables as new data is loaded or you take actions in the addon, so we’ve spent a lot of time working to significantly improve the performance of these elements across the TSM addon suite.

As well as performance improvements, we’ve added a ton of new functionality to these tables:

Drag Columns to Reorder them

Now you can reorganize the columns in any scrolling data table, such as at the Auctioning House or in your profession window.

Note the ‘item name’ column position cannot be changed, and column positions can be reset in the traffic light menu in the top left of any table.

From this menu you can now also enable to lock the width of columns in the table so that you don’t accidentally resize a column too wide or too narrow. Enabling this option will maintain the current width of all columns in the table.

Create a Group from items showing in a Scrolling Table

Making Groups is often a challenge, over the years we have taken steps to make that easier including the concept of the Base Group which contains any item that you don’t already have inside a Group, even if you don’t currently own the item.

We’re taking that a step further and adding the option to create a Group containing the items that you currently see in the table – whether that is a category selected in your profession window to group items you can craft or a search on the Auction House.

In this example the Auction House Browse tab is filtered by using the Advanced Item Search to look for the category of Tailoring Recipes. I can select ‘Create Groups from Table’ to add all of the items in the table to a new Group. Note that items that are already grouped are not added to the newly created Group.

Adding Prices or Sources as Custom Columns

A very common line of feedback when using TSM is to add more information to the UI in order to be better informed and make it easier to make decisions. We have to strike a balance between what is usable or understandable to someone who may be new to TSM and creating the flexibility to enter ‘data overload’ territory if it’s desired.

With TSM 4.14 we’re pleased to add the option to include any standard price or value source as a new column in any scrolling table, such as your Auctioning and Shopping Scan results, or Sniper Scan results. This is also extended to include any custom sources you have defined as a custom column. Simply select the traffic light menu in the top left of any scrolling table to manage which columns appear in the table.

In this example the number of the item currently owned (NumInventory) is included in the Browse results so I can decide whether I want to purchase more at-a-glance.

Learn more about the available Price Sources and Value Sources out-of-the-box in TSM, and find the perfect combination of information to support your gold-making strategy.

Post From Bags Improvements

The Post From Bags section in the Auctioning tab of the Auction House receives all of the previously mentioned upgrades, including adding Price Sources, and in addition has the new option to add which Group the item is in to the table. It’s easy to see at a glance what might be worth posting if you have limited time or are learning new markets as part of your gold-making strategy!

In this example the DB Recent value and the minimum price from the assigned Auctioning Operation are shown in-context before selecting and posting the items, along with the Group that the items are in.

Scrolling Table settings persistence

All aspects of the scrolling table configuration are now persisted across sessions, including Column Sort Order, Price/Value/Custom Source Columns, and Column Display Order

Import Item IDs from Wowhead

Continuing the theme of creating Groups – historically the Group Maker was a primary middle-man between searching and filtering Wowhead for items you want to import into the addon in-game.

To make this process even more efficient we have added support for copying the IDs of any Item search on Wowhead directly into the addon in-game.

Once you’ve applied your filter, select the Copy button, and then click IDs. In this example the filter is for Bind on Equip drops added in Dragonflight, copying the IDs will include up to 1,000 items returned by Wowhead, and not just the first 50 shown on the page which was a historical limitation of our Group Maker web page.

Once copied, you can import them in-game. Learn more about creating Groups by importing.

Custom Strings in More Operations

Custom Strings are extremely powerful for the main Operation types in TSM such as Auctioning and Crafting – allowing fine-tuning and ultimate control on what you do and why at any time.

We’re empowering more Operations in TSM 4.14 to support Custom Strings including Mailing, Vendoring, and Warehousing.

Previously these operations generally only accepted integers such as sending 20 potions to an alt character without much flexibility. Now you can create a custom string to only send 20 potions if the market value is where you would consider selling them using price sources, or restock a particular vendor item if your personal sale rate is high enough using a logic function.

Learn more about the available Price Sources and Value Sources out-of-the-box in TSM.

Custom Source Formatting

Prior to TSM 4.14 all Custom Sources would be calculated and displayed as a currency. Now there’s an option to show a Custom Source as an integer, a percentage, or as a currency as before.

When creating a new Custom Source you can specify the format and you can modify this setting for each Custom Source at any time. Any Custom Source can be displayed in your tooltips via the Tooltip Settings.

In the following examples these Custom Sources use one of each format, the first being a percentage representing an average of personal and regional sale rate. The second shows a number representing the max stack size for an item (a new value source added to 4.14!), and finally the third is a currency averaging various price sources to provide a general price point.

Lots of Other Minor Changes

Addon Optimizations

Further to the Scrolling Table optimizations mentioned earlier, additional work has been completed to further improve the performance of the addon in general – particularly in the Profession UI and Auction House UI.

You’ll notice that the addon is generally more responsive and snappier as you engage with these pages, and searches or Shopping scans in the Browse tab are also much quicker due to scan time optimizations.

Mail Contact Management

It’s now possible to delete names from the recent contacts list in the Mail UI, get rid of those pesky alts that have been deleted or transferred!

Rescanning

There’s a new button in the Auction House UI to ‘Rescan’ to immediately repeat an Auctioning Post or Cancel Scan.

Help Tooltips

A large number of tooltips have been added across the addon to explain functionality for a particular setting, input, or button. Mousing over the section will display the tooltip with contextual information or a definition.

More documentation for the Addon suite can be found in our Knowledgebase.

Getting Help

Please join our Discord server as per the Get Started instructions, to share your feedback on the 4.14 Beta or report any bugs and issues you encounter.

We are Hiring a Product Marketing Consultant

UPDATE: This role has been filled so we are no longer accepting applicants. Thanks for your interest!

The TradeSkillMaster team is a small group of gamers who love to learn new skills and constantly push the boundaries of what TradeSkillMaster can do for our users. What started as a small addon has grown into a comprehensive gold making addon, desktop application, and set of web-based tools and resources. We are driven by self-improvement and creating a great set of products and services for our users, while working in an efficient, but low-stress environment.

We are always exploring new ways to improve the experience we offer to our users. To that end, we are looking for help in improving the various ways in which we communicate the value of our suite of tools to our users and potential users in the form of written content on our website and distribution platforms (Curseforge, Wago, etc), transactional emails, and more.

The Role

As a part of this role, you will be expected to work closely with other members of the team to create marketing content including copy and assets, ideate and manage marketing campaigns, and measure performance.

This position is short-term (3-6 months), part-time and paid. The work will be purely remote with NA/EU time zones strongly preferred.

About You

Qualifications:

  • At least 3 years in roles with a significant focus on written digital marketing
  • Strong written communication skills
  • Experience with TradeSkillMaster and a passion for improving it

Ready to join us? Send me (Sapu) a message on Discord (https://discord.gg/woweconomy. Come prepared with your resume, some examples of your past work, and any questions about the role you may have.

TSM Premium Survey

We are reviewing our Premium offering and considering where to take it in the future, with potential new features and benefits to enhance your gold-making experience inside and outside of the game.

Your feedback is important in shaping the future of TSM Premium and the direction we take will be guided by your input, so please take a few moments to share your thoughts and suggestions in the following survey – it is open to all TSM users whether you are currently a Premium member or not.

Please note you will need to be signed into a Google account to complete the survey, this account information is not shared with TSM. If the embedded survey does not load correctly, it can be accessed through the direct link:

https://docs.google.com/forms/d/e/1FAIpQLSc8_ftqHJqsejepvs6Lck7oyZuiO8l7q_r4ewWXRlGKdFwHAA/viewform

New Custom String Parsing

Introduction

Custom strings have long been at the heart of what makes TradeSkillMaster such a versatile and powerful tool for gold making. They allow the user to focus on their gold making strategy, and allow the addon to worry about doing all the complex math for them. For example, the default Auctioning operation settings ensure that items will be posted above their vendor sell price and a percentage of an average of the crafting cost, realm market value, and region market value, while transparently accommodating items that can’t be either vendored or crafted, all without requiring the user to ever need to manually calculate or input those values. In v4.13, we completely rewrote how the addon parses and evaluates custom strings to allow for much greater optimization and user debuggability. This blog post will dive deep into the changes that were made and the performance improvements they’ve enabled.

Background

TSM’s custom strings are defined by a set of functions and sources that can be used together in a single expression. As an example, let’s dissect the default Auctioning Operation minimum price setting:

check(
	first(crafting,dbmarket,dbregionmarketavg),
	max(
		0.25*avg(crafting,dbmarket,dbregionmarketavg),
		1.5*vendorsell
	)
)

There are a few things going on here. First of all, the outer check() function ensures that the first parameter is valid (and greater than 0); making the entire thing invalid if not. This is used here to ensure that the item has either a crafting cost, realm market value, or region market value. If all of these are missing for the item, we don’t have enough information available to properly post the item, so the custom string is made invalid to prevent posting the item at a potentially erroneous price. Assuming that check passes, we’re left with:

max(
	0.25*avg(crafting,dbmarket,dbregionmarketavg),
	1.5*vendorsell
)

The max() function here takes the higher of its two parameters. The first parameter is the average of the crafting cost, realm market value, and region market value multiplied by 0.25. The second parameter is 1.5 times the vendor sell price. This ensures that this custom string always evaluates to at least 1.5 times the vendor sell price, even if the market values / crafting cost is very low. Both avg() and max() also have a side-effect of silently ignoring any invalid parameters, meaning if the item doesn’t have a crafting cost or a vendor sell price, the custom string can still be evaluated based on the other parameters.

Let’s plug some values into this custom string and see how it gets evaluated. Let’s assume we’re trying to post “Spice Bread” which has the following prices:

  • Crafting Cost: 35c
  • Vendor Sell Price: 5c
  • Market Value: 12s 70c
  • Region Market Value: 11s 57c

If we simply plug these into our custom string, we get the following:

check(
	first(35c, 12s70c, 11s57c),
	max(
		0.25 * avg(35c, 12s70c, 11s57c),
		1.5 * 5c
	)
)

After evaluating the first() and avg() functions:

check(
	35c,
	max(0.25 * 8s21c, 1.5 * 5c)
)

The first parameter of check() is valid (greater than 0) so it simply evaluates to its second parameter, the max(), which calculated out results in 2s5c.

This is the same math that TSM is doing under the hood, but obviously TSM needs to do it in a well-defined and programmatic manner. It has traditionally accomplished this by relying on the fact that the custom string syntax (that is, the format used to write custom strings) is very similar to valid Lua code (the programming language addons are written in), and Lua allows for dynamically loading and executing code. In other words, we can treat the custom string as Lua code and execute it directly as if it were programmed directly into the addon. However, we don’t simply want to directly execute what gets entered into a custom string setting for multiple reasons:

  1. We need to be able to plug in the correct value for the sources depending on the item which the custom string is being evaluated for.
  2. The set of functions which are valid in custom strings are specific to TSM, and not necessarily part of the Lua language itself.
  3. We need a way to ensure that what the user enters is a valid TSM custom string, and not just some arbitrary snippet of Lua code.

This was previously accomplished by doing a very rough tokenization of the string followed by applying some rules and string replacements to the tokens to ensure the input was valid and create a valid, loadable snippet of Lua code to present the custom string. Tokenization is the process of turning an arbitrary string (i.e. the entire custom string the user enters into a setting input) into a series of known words (a.k.a. tokens). For example, the custom string “max(crafting, vendorsell)” gets turned into the tokens:

  • max
  • (
  • crafting
  • ,
  • vendorsell
  • )

In this tokenized form, we can then easily perform a series of validation checks, such as requiring that there is an equal number of left and right parentheses, and replace sources and functions as appropriate to turn this into a valid snippet of Lua code we can execute:

function(helpers, _item)
	local result = helpers._max(
		helpers._priceHelper(_item, “crafting”),
		helpers._priceHelper(_item, “vendorsell”)
	)
	if not result or helpers.IsInvalid(result) or result <= 0 then return end
	return result
end

Above is a simplified version of what the code generated by the original custom string implementation would look like. It looks very similar to the custom string we started with, but the sources have been replaced with function calls to look up the specified price for the item being evaluated, and the max() function call has been replaced with a call to a max() function TSM defines and provides.

This implementation has suited TSM well for a very long time, but has a few key limitations. First of all, the amount of validation that can be performed on a list of tokens is fairly limited and isn’t robust enough to catch all possible syntax errors. Having more robust processes in place for how custom strings are parsed will also enable better user-facing error messages and debugging functionality. Also, there’s no chance to perform any optimization on the generated code with this implementation. For example, if a custom string references the same source multiple times, the generated Lua code will look up the value of that source each and every time, with these lookups accounting for the majority of the computation time needed to evaluate custom strings in general.

New Implementation

The new implementation works much more like a traditional compiler and consists of 4 high-level steps: tokenization, abstract syntax tree generation, optimization, and code generation. We’ll use the following (somewhat contrived) custom string to demonstrate this process:
ifgt(crafting, 50g, crafting + 150% crafting, 10g + 5g)

For reference, here’s what that custom string would be converted to using the old system:

function(helpers, _item)
	local result = helpers._ifgt(
		helpers._priceHelper(_item, “crafting”),
		500000,
		helpers._priceHelper(_item, “crafting”) +
			1.5 * helpers._priceHelper(_item, “crafting”),
		100000 + 50000,
	)
	if not result or helpers.IsInvalid(result) or result <= 0 then return end
	return result
end

Tokenization

The tokenization step is similar to the prior implementation, but much more in-depth. It is responsible for taking the input string and converting it into a series of well-defined tokens which can then be more easily processed further. A token can be thought of similar to a word in an English sentence. It’s the smallest discrete unit which is meaningful by itself. The tokenizer works by methodically going through each character of the input string and separating out distinct tokens which are often separated by whitespace or formatting characters (i.e. parentheses or commas). In the case of our example (ignoring whitespace tokens), the tokenizer splits up our custom string into the following tokens:

ifgt ( crafting , 50g , crafting + 150 % crafting , 10g + 5g )

In addition to just splitting up the string into tokens, the tokenizer also classifies each token based on their type:

  • FUNCTION – ifgt
  • LEFT_PAREN – (
  • IDENTIFIER – crafting
  • COMMA – ,
  • MONEY – 50g
  • COMMA – ,
  • IDENTIFIER – crafting
  • MATH_OPERATOR – +
  • NUMBER – 150
  • MATH_OPERATOR – %
  • IDENTIFIER – crafting
  • COMMA – ,
  • MONEY – 10g
  • MATH_OPERATOR – +
  • MONEY – 5g
  • RIGHT_PAREN – )

The tokenization step takes care of a lot of the ambiguity of string parsing, and we now have a well-defined representation of the custom string which can more easily be worked with programmatically. The next step is to take this series of tokens and convert it into an abstract syntax tree, or AST for short.

AST Generation

An abstract syntax tree (AST) is a tree-based (per the name) form which better represents the structure of the custom string and the discrete operations (i.e. mathematical operations and / or function calls) which it consists of. A description of the algorithm for transforming the list of tokens into an AST is beyond the scope of this blog post, but we’ll visualize it with our example string, starting with a slightly more formatted version of the original string:

ifgt(
	crafting,
	50g,
	crafting + 150 % crafting,
	10g + 5g
)

In this form, we can visually see that this example has an outer “ifgt” function which has 4 parameters. Its 3rd parameter consists of 2 separate math operations (“+” and “%”). The 4th parameter of the outer “ifgt” also consists of a “+” math operation. Each of these distinct functions and operations is turned into a node in the tree, with its arguments becoming its children:

This AST form is helpful for doing a few things:

  1. It abstracts away all the original syntax of the custom string with the order of operations entirely determined by the location of a node within the tree. For example, we can look at the tree and see that we must calculate the “%” operation of “150” and “crafting” before we can calculate the “+” operation, as the result of the former is a dependency of the latter.
  2. We can easily validate that functions are being used properly. The “ifgt” function can only take either 3 or 4 parameters. We can easily see from this tree form that the “ifgt” node in the tree has 4 direct children, and therefore the “ifgt” function has a valid number of arguments. One thing worth noting here is that TSM stores enough information in both this tree form and the token list in order to reverse the process back to the original string form. This allows TSM to point the user at exactly where their custom string is invalid, which is one of the main benefits of this new custom string implementation as a whole.
  3. Lastly, we can perform very well-informed optimizations based on this AST form, which we’ll dive into next.

Optimizer

Now that we have the custom string represented as an AST, we can methodically go through it and look for opportunities where we can optimize it without changing the result. There are dozens of different optimizations which are attempted at this stage, but for this example there are just a few which apply.

The first optimization we can perform here is to realize that taking “150%” of something is the same as multiplying it by 1.5. Multiplication is generally a lot easier to reason about than a “%” operator, so we’ll update that part of the tree accordingly:

If we zoom out one level from that new multiplication, we can see that we now have the expression “crafting + (1.5 * crafting)” which, using some simple rules of algebra, we can rewrite as “2.5 * crafting”, or in AST form as:

Lastly, we can see that the 4th argument of our “ifgt” function is simply adding two constant values together, which can be precomputed to just “15g” with our optimized AST looking like this:

Although this was a relatively contrived example, we were able to reduce the number of nodes in the AST from 11 down to just 7 just through some simple optimizations. Most importantly, we were able to get rid of one out of three of the “crafting” source nodes. These optimizations mean that TSM users can format their custom strings in a way which makes managing them as easy as possible rather than worrying about trying to write them in an optimal way. The addon itself will take care of all the optimization.

Code Generation

The last step is to turn our optimized AST into Lua code that can be executed by the addon. Compared to the previous custom string implementation, having the AST allows us to do this in a much more controlled and optimized way. For example, we can cache intermediate values so we only need to compute them a single time, even if they are used multiple times within the custom string. The generated code for our example custom string (edited for readability) is as follows:

return function(itemString, helpers)
	-- Locals
	local res_ifgt_1901082 = nil

	-- Code
	local var_crafting = helpers.GetPrice(itemString, "crafting")
	if var_crafting == helpers.INVALID then
		return nil
	end

	if var_crafting > 500000 then
		res_ifgt_1901082 = (2.5 * var_crafting)
	else
		res_ifgt_1901082 = 150000
	end

	return helpers.ValidateResult(res_ifgt_1901082)
end

This code very closely matches our optimized AST, and has many optimizations when compared to our original custom string and the previous implementation. Most importantly, we only need to look up the “crafting” source for the item a single time, and then are able to reuse that multiple times within the generated code. One important optimization that’s not shown here is that we only evaluate sources as they are needed, and at most a single time. For example, if “crafting” was referenced in the “else” part of the “ifgt”, it would reference the same “var_crafting” variable rather than re-computing the crafting cost for the item.

Conclusion

Custom strings are one of the most powerful aspects of TSM, and we continue to dedicate significant time to improving their functionality and efficiency. With these under-the-hood improvements we made in 4.13, we are able to make the process of writing and debugging custom strings much better for all TSM users, while also improving their performance.

TradeSkillMaster 4.13 – Supporting Dragonflight 10.1.5

Following on from our last update with a recap of what was done and was to come in TSM in support of Dragonflight professions and systems – we’re pleased to share further improvements as well as the release of TSM 4.13!

Recent Dragonflight Profession Updates

Rounding out the last releases in TSM 4.12, let’s recap what has been introduced since the start of the year and our last blog update.

  • Updated milling / prospecting / disenchanting rates for Dragonflight reagents.
    • Given the significant variations of profession knowledge and equipment we gathered a lot of data to represent averages across the board as best as possible.
  • New quality selector to easily switch between different target qualities for a given crafted item, as well as easy access to add finishing reagents.
    • Selecting a different quality will automatically adjust the reagents selected to meet the selected quality, and is further enhanced in 4.13!
  • Quality reagents can now easily be changed by clicking on the material row in the material list
    • Seeing each quality of the reagent for at-a-glance pricing info and inventory quantity helps you decide what to use

New improvements in 4.13

With the launch of patch 10.15 we are introducing version 4.13 of TSM with a number of improvements to Dragonflight profession support and other additions we think you’ll love.

4.13 Profession Updates

Iterating on the things introduced in 4.12, we have continued to improve profession support including:

  • Adding support for Dragonflight salvaging for milling and prospecting
  • Adding support for crafting inspiration to show potential cost and profit of a crafted item that is not guaranteed
  • Improving the Optional Reagent flow further from the modal introduced in 4.12 to an in-line editor when a recipe is selected, allowing quicker access to add embellishments and finishing reagents

Region-wide support in 10.1.5

With the introduction of direct trading between any characters for gold and items on any realm in a given region, we are also very excited to expand on TSM cross-faction support added in 4.12 to cover region-wide tracking and reporting.

In 4.13, and if the option is enabled in the TSM General Settings, addon information such as inventory and accounting data will be available on any realm in your region. That way you can reference what you paid for an item and see how many you have on any realm from any other realm.

This will also include gold quantity and gold history, so your TSM Dashboard will cover all realms in your region if you’re actively using the addon on multiple realms!

To manage Accounting Data, the option to remove old sales and purchases has been modified to support an input instead of a predefined list in the Accounting Settings. If you’re making use of this feature and experience some performance issues it’s recommended to purge older data (which won’t affect your gold charts).

Custom String Performance Enhancements

Some TSM users have created some monster Custom Strings for all kinds of Operations and material prices. We’ve spent some time optimizing how Custom Strings are calculated to improve performance for very large or complex Custom Strings in very large profiles. This should also reduce the number of errors encountered when using TSM with some content creator profiles.

Grouping pets by level

We are also introducing ‘item level’ grouping for Pets in 4.13, where the pet item level translates to the level of the pet. When you’re grouping items by ‘item level’ they will be treated differently when shopping and posting through operations vs pets of other levels that are not grouped for example.

Dragonflight Update

In this post, we’re going to dive into where we’re at, what’s coming soon, and where we’re going with regards to supporting gold making in Dragonflight. I’ll start things off here by apologizing for not being as active as I would have liked with communicating this information sooner. TSM was definitely not as ready as I would have hoped for the changes in Dragonflight. There are a variety of reasons for this, which mainly boil down to not having enough development hours to spend and underestimating just how much of TSM would need to change to support the new profession changes. I understand people’s frustration with the state of TSM in Dragonflight so far, and am committed to improving things going forward. However, this will take some time.

Current State of Things

With that said, let’s talk about what changes we’ve made so far, and where things are at as of the time of writing (v4.12.20). The following things are working today:

  • For crafted commodity items, the crafting cost and profit will accurately display in the tooltip, and be available for use in custom strings (i.e. in Auctioning operation prices).
  • Quality, optional, and finishing materials can all be added manually to a recipe within the Crafting UI and then either crafted directly or added to the queue. Gathering then supports collecting all the materials as normal.
  • Restocking your groups based on Crafting operations is fully supported for crafted commodity items.

Coming Next

Here’s a list of things that are actively being worked on and can be expected to be released in the very near future:

  • Crafting cost and restocking support for quality crafts which produce gear of varying item levels.
  • Updated Destroying data for DF Milling, Prospecting, and Disenchanting.
  • Crafting UI support for selecting materials for and crafting recipes that don’t have fixed materials. This includes things like Mass Milling, Mass Prospecting, Recrafting, etc.
  • Improved UI for manually selected the target item for a quality craft, and having TSM automatically populate the cheapest set of quality materials needed.
  • Improved UI for selecting optional materials (including quality mats and finishing mats).
  • Display of crafting stats for quality crafts such as expected quality, inspiration, multicraft.
  • Support for taking inspiration into account when calculating the crafting cost.

Longer-Term Roadmap

There are a few other areas of TSM which definitely need some love and will be revisited in the not-too-distant future, which I thought I’d also call out here:

  • Improvements to how TSM handles buying commodities from the AH.
  • Item cache rebuilding performance improvements.
  • Account syncing performance improvements.

Crafting Cost

I thought it would be helpful to give some details on how we’re approaching crafting costs in Dragonflight. As we all know, Dragonflight greatly expanded the complexity of crafting things with professions. At its core, each recipe has a difficulty which gets matched up against your skill level to determine the result. That skill can then be modified with higher quality materials and various optional materials, as well as by proc’ing inspiration. In order to calculate how much it costs to craft something, TSM currently considers all the potential qualities of materials which result in the desired item being crafted.

As a hypothetical example, let’s assume there’s a potion which takes 1 herb and 1 vial to craft, with each of the materials being 1 of 3 qualities, and the recipe producing up to quality 3 of the potion. Let’s assume that using quality 3 of both materials results in quality 2 of the potion being crafted, and any other combination of materials results in quality 1 of the potion being crafted. To determine the crafting cost of the quality 1 potion, TSM will determine that there are 4 possible ways you could craft this item, from the 4 possible combinations of quality 1/2 of the herb, and quality 1/2 of the vial. TSM will then pick the cheapest of these options and use that as your crafting cost. Going further, it’s impossible to craft quality 3 of the potion, so TSM will treat that as an item you don’t yet know how to craft, and not display a crafting cost. Similarly, if you weren’t able to get your skill low enough to craft quality 1 of the potion anymore, TSM would treat that as something you can no longer craft and not show a crafting cost.

Currently, inspiration is not taken into account. From the above example, it’s possible that you could craft quality 3 of the potion if you were inspired. It seems like this will be important for some recipes where it won’t be feasible to get your skill high enough to craft at the highest quality without an inspiration proc for some crafts. This is something that’s not yet taken into account, but is something that we will plan to support in a future update as mentioned above.

Also, the game allows you to mix and max different qualities of the same material to hyper-optimize your crafting cost. For example, a recipe may require 5 of an herb, but you may only need to supply 1 at quality 3 with the remaining 4 being quality 1 in order to craft the desired quality of the crafted item. This isn’t something TSM takes into account, and is not something we have plans to support, due to the exponential increase in computing resource it would require to consider all possible permutations. Calculating crafting costs is already an order of magnitude slower than any other price source in TSM, so we felt that requiring all of a given material to be at the same quality struck the right balance between maximizing profits and keeping things performant and manageable for the user (i.e. when listing materials needed to craft something and/or gathering them).

Wrapping Up

In conclusion, there is a lot of work to do to get TSM where we want it to be for Dragonflight gold-making. This work is ongoing and we’re committed to aggressively work through the list of outstanding features and push out new functionality and bug fixes as they are ready. We’ll check in again with an update as things progress. If you have any feedback on the current state of things or the upcoming features, let us know in Discord.

TSM Addon 4.12 released!

Following the brief beta test, TSM Addon version 4.12 is now fully released for Dragonflight!

Check out our previous blog post for a full recap of the changes you can look forward to:

If you are running the TSM Desktop Application, you will be automatically updated.

NOTE: It may take up to 12 hours for you to receive this new version due to expected increased server load with the Dragonflight launch.

If you encounter any issues, please join us on Discord for support and help.