Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Proposal: Sims, Specs and Builds - How we can reduce the complexity of classes and specs with multiple playstyles #2397

Closed
kayla-glick opened this issue Jan 13, 2023 · 4 comments

Comments

@kayla-glick
Copy link
Contributor

kayla-glick commented Jan 13, 2023

*** !This is a work in progress so please be mindful of that before reading, thank you! ***

Background

At the most basic level, our WoW characters are most defined by our class and spec (aka the talent tree with a majority of points invested). But during the course of Classic WoW and even during the original runs of expansions like Wrath of the Lich King, the community has found alternative ways to play characters; alternative "builds" that redefine how you play whether by changing gear, rotation, talents, etc. We can already see many of these builds represented in WoWSims and Warcraftlogs:

  • Fire vs Frostfire Mages
  • Smite Priest
  • 2H vs DW Unholy, Lichborne, and other DK builds
  • Feral vs Guardian vs Warden Druids
  • Gladiator warriors
  • Justicar vs Protection Paladin

Builds have existed as a concept for almost as long as WoW has been around, and arguably even more so in Classic than Retail because of the classic talent tree system. For many players, builds are as much a part of player identity as class and spec.

What's the problem we're trying to solve?

There's a lot of inconsistencies with how we've been handling builds up to this point. Many specs have just one major build that's played, but clearly many other don't. This creates complexity for tools like WoWSims and Warcraftlogs because we have to find ways to represent these builds within our code. Up to this point, we haven't really handled this consistently in WoWSims. Our Spec Proto is really a representation of the various unique "Sims" the site offers.

  • Some entries do represent a single spec - Balance Druid, Restoration Druid, Shadow Priest, all 3 Shaman specs all 3 Paladin specs, Protection Warrior
  • Some represent a whole class (Hunter, Mage, Rogue, Warlock)
  • Some represent a particular role within a class - DPS and Tank Death Knights, DPS Warrior (though labeled "Warrior"), Healing Priest
  • And some represent variant builds - Feral DPS and Tank, Smite Priest

These inconsistencies not only create complex and often confusing code within the code-base by misrepresenting the traditional idea of "specs", but also create inconsistent experiences for our users as they navigate between our various sims.

Code Complexity

Because of our inconsistent application of "specs" (aka sims), we often can't rely on just the "spec" to make determine information in the code. Often times we end up having to provide additional context (like talent strings, class, or other identifiers) or create mappings to point to the right thing.

As an example, the SimTitleDropdown that builds the list of sims has to do extra checks to determine how it should build the various components of the dropdown. It checks if the "spec" is for a class, or if it's for a spec or build within a class.

Another example, the Raid Sim Importer has to map several specs and builds to a single WoWSims "spec" while others are mapped 1-to-1. The Death Knight sim is particularly
difficult because even Warcraftlogs doesn't distinguish between some of the hybrid DK builds.

This has also lead to a lack of structure in many cases. Spec/Build icons, or example, can be accessed several different ways - all of which are just functions coming from the proto utils module. Lack of structure can make any code base harder to maintain in the long term, as people create new solutions to new problems, throwing more and more code into various new files without much order.

The site's UI is built with TypeScript - which itself exists because of the lack of structure of old vanilla JavaScript. It excels at dealing with object-oriented code and dealing with intentionally strict types. But in many cases we're not taking full advantages of these benefits.

What should we do about it?

Rethinking the relationship between Classses, Specs, and Builds

I've been trying to think about what the relationship between Classes, Specs, Builds, and Sims really looks like in Classic WoW and put together the small diagram below. What I've come to realize is that - unlike Retail WoW - "Specs" aren't necessarily a rigid entity in Classic WoW. Specs are a label for a talent tree and a label we give to a Build that has a majority of talent points allocated to a single talent tree. For classes that don't really have any prominent variation builds, you can model their "Specs" as "Builds" all the same way. By dividing things into Builds, we gain more flexibility to represent major variations like some of the ones above. This isn't to say that everything needs to be its own build. In fact, I'd argue that things like Fire vs Frostfire Mage and Unholy 2H vs DW Death Knight should be represented by single builds with variations to rotation, gearing, talents, etc. The other part of this is that Sims are not the same thing as Builds (though realistically they are very close). Each build should have 1 sim powering it, but sims can also live independently from a single build as seen with the Raid Sim.

Class, Spec, Build, Sim relationship

Restructuring our code around these ideas

I imagine there would probably need to be quite a few changes to both the Go and UI sides of the app to actually accommodate these changes. On the Go side, we might want to break up some sims to correspond with different builds (such as mage being slit into 3 sims - 1 for each spec), with a new proto enum to represent them.

// STILL WIP
enum Build {
  BuildUnknown = 0;
  // Deep blood dps
  BuildBloodDPSDeathKnight = 1;
  // Deep Frost dps
  BuildFrostDPSDeathKnight = 2;
  // Deep Unholy dps
  BuildUnholyDPSDeathKnight = 3;
  // Other DK variants as well
  ...
  BuildBalanceDruid = ...;
  BuildFeralDPSDruid = ...;
  BuildGuardianDruid = ...;
  ...
  BuildArcaneMage = ...
  // Fire and Frostfire represented by a single sim as they're variants of deep Fire
  BuildFireMage = ...
  BuildFrostMage = ...
  ...
}

// STILL WIP
message Sim {
  Class class = 0;
  Build build = 1;
}

On the UI side I see us having wrapper classes for each Class and each Build/Sim containing all of the information needed to use and identify the build, including names, icons, talent and gear presets, rotations, etc. very similarly to what we do now with the individual sim UIs, but not coupled to the UI specifically.

@avidal
Copy link

avidal commented Jan 31, 2023

I like the idea here, especially after looking into some of the complexity in some of the existing sims. As a user, the options presented to me are really complex and some of them can completely crash a simulator (select Demonology rotation but remove your pet). There's a balance to be found between ergonomics and flexibility.

In your example, how do you envisage the actual sim selection process going? If a player chooses to sim the Demonology build but changes the talent tree to remove Metamorphosis, should that still run the Demonology sim? And does that mean the Demonology sim needs to have guards around Metamorphosis not being selected?

If you assume that the demo sim needs to support not having a demo tree, does that actually make the demo sim less complicated? Or can a demo sim, in this scenario, be simplified to say: If you don't have a demo tree, none of the demo talents are going to apply....but none of the affliction or destruction talents will apply either.

Of course, in that scenario players that want to try something completely new are left with no options (other than building their own sim or just playing around with it in-game)...which might very well be an acceptable tradeoff.

@kayla-glick
Copy link
Contributor Author

Hey @avidal thanks for checking in! I actually never got around to finishing this because I've been pretty busy lately 😅 but to answer your question, I'm not 100% sure what restrictions we might put on a spec-by-spec basis, but the same is already true of the many single-spec sims we already have (all Druid, Shaman, Paladin, and sort of Priest sims). I would think one way to handle it would be to prevent users (or show an error) from saving a talent setup that has less than a majority of points in the correct talent tree for the sim. The sims would still need to consider that some spells might not be selected and check for it (APL-like sims would be even better for that).

@NuptupTDOW
Copy link

If a player chooses to sim the Demonology build but changes the talent tree to remove Metamorphosis, should that still run the Demonology sim? And does that mean the Demonology sim needs to have guards around Metamorphosis not being selected?

This is EXACTLY the issue I came across over in #2560.

@jimmyt857
Copy link
Contributor

With #4077 this is less of an issue, seems safe to close this now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants