Skip to content

Conversation

@majochem
Copy link
Contributor

@majochem majochem commented Oct 7, 2025

Description of the problem being solved:

I was getting a bit annoyed by having to micro-manage attributes when planning out passive trees, so I added the option for some automation.

Until now assignment of attributes for travel nodes worked like this:

  1. You select attribute via pop-up
  2. You hold one of three hotkeys to force an attribute
  3. If you allocate more than one node, it allocates all attribute nodes in the path to your last selected attribute

I found that inconvenient because I would have to keep track of how many attributes I have vs. how many I needed. Especially on triple attribute builds, it felt pretty tedious.

Feature Description

Now there is a new menu button called "Auto Attribute Config" (I'm open to better naming suggestions) on the bottom of the tree tab and it looks like this:
image

image

Copied explanation from help.txt:

You can enable the automatic allocation of attributes via the "Auto Attribute Config" button at the bottom
of the "Tree" menu section. Each configuration is saved per tree. So if you have multiple trees, each will
have its configuration values.

Weights:
If enabled, attribute travel nodes will automatically be assigned to Strength / Dexterity / Intelligence
according to your configured "weight" values. E.g. values of Str: 1 / Dex: 1 / Int: 2, would result in
roughly 25% of the attribute nodes being assigned to Strength and Dexterity and 50% to Intelligence.
By default, attributes gained from items and other small passive nodes are taken into account when
calculating the actual vs. desired attribute ratios.

Max Value:
If a "Max Value" is entered and the "Limit to Max?" checkbox is ticked, no more nodes will be allocated
to that attribute, once the maximum value is reached

Attribute Requirements:
For ease of use, the "Use Attribute Requirements" checkbox can be ticked. This will result in weights
automatically being based on current attribute requirements from gems and gear.

Item Mods:
If you want your attribute allocation to be gear-agnostic, you can tick the "Ignore Attribute Requirements"
checkbox. Any attribute bonuses gained from equipment will then not be taken into account during allocation.
Note: This does not affect modifiers to attribute requirements found on gear.

Other Functionality:

  • Saved Auto Attribute Config values are written to and retrieved from the XML
  • Added hint about new automatic allocation to ModifyAttributePopup
image
  • Added hint about active automatic attribute allocation when hovering over attribute nodes (in case user is loading someone else's build and confused what's happening)
image
  • Added information about Auto Attribute Config to the help.txt
  • Added tab navigation to the Auto Attribute Config pop-up to easily switch between attributes

Steps taken to verify a working solution:

Test cases

  • Basic Popup
    • Opens and closes correctly
    • Works in different window ratios
    • option controls only enabled if main enabled box is checked
  • Item mods
    • Correctly accounted for (BASE, INC, and MORE)
    • Ignored if desired
  • Use Attribute Requirements
    • Calculated correctly
    • Updated when requirements change, both for calculation and in popup display
    • Modification of weight values disabled, if using requirements
  • Special Jewels
    • Timeless jewels
      • No mods affecting attributes afaik?
    • Time-lost jewels
      • %increased effect of notables/small passives is taken into account for attribute totals
    • Intuitive leap likes
      • From Nothing
      • Controlled Metamorphosis
      • Auto allocation works
      • Manual allocation (hotkey or right click swap works)
    • Against The Darkness
      • %attribute mods correctly accounted for
  • Alt Pathing (via holding shift)
    • auto allocation works
    • non-attribute-passive mods are correctly accounted for
  • Saving Config
    • One Tree
    • Multiple Trees
    • Enable "Save" on config change
  • Loading Config
    • One Tree
    • Multiple Trees
    • No existing config
    • Works if calcsTab.mainOutput doesn't exist yet
  • Weapon Swap passives (*)
    * "Works", but weapon swap passive functionality is still buggy in itself
  • Hotkeys
    • "1/2/3" & "S/D/I" still works
    • Right click attribute swap still works
  • Undo States work
  • Reset Tree Behavior
    • Result: Config does not get reset (intended)
  • Import Behavior
    • Importing from build code with config, correctly imports config
    • Importing via build code without config sets it to nothing (overwriting if one exists, but I think that's fine?)
    • Importing from account keeps current config unchanged

Limitations:

  • The automation only works for attribute nodes that are on the currently allocated path. So, if you allocate some small passives that e.g. provide "+x to all attributes" that will be taken into account when allocating the attribute travel nodes on the path there, however, if you allocate the travel nodes first, then the "+x to all attributes" nodes afterwards, it will not recalculate already allocated nodes, which can lead to slight deviations from the target ratio. I think it's a negligible edge case though, and I'd rather implement a manual "reallocate all attribute nodes" button in the future, than dealing with the performance impact of going over the entire tree, any time you allocate a node that affects attributes in any way.

Link to a build that showcases this PR:

Test Build with some relevant test items

Adds a new button and a new popup to the TreeTab that allow the
configuration of settings for automatic attribute allocation
- If an `autoAttributeConfig` exists and is enabled, any attribute pathing
  nodes will be allocated according to the configured weightings and
  options.

- Holding a hotkey will still have priority and right-clicking will also
  remain unchanged.

- Attributes that are gained from non-attribute nodes on the path are
  taken into account *before* deciding the allocation
`autoAttributeConfig` is saved on a per tree/spec basis to the xml, so
that different trees can have different configs.
`autoAttributeConfigSaved` wasn't updated when saving a build
- Didn't properly cache all attributes gained from all non-attribute
  nodes in path
- Also changes `maxValue` to use `<=` rather than just `<`
Even with a set config, attributes can be forced via hotkey or swapped
via right click
Disable/Enable the other buttons/fields, when automatic attribute
allocation checkbox is marked/unmarked
Automatic attribute allocation wasn't working with effects like
"From Nothing" or "Controlled Metamorphosis"
Previous fix led to right-click attribute switching taking into account
auto attribute ratios, which is not intended
@majochem majochem marked this pull request as ready for review October 8, 2025 10:26
@Blitz54
Copy link
Contributor

Blitz54 commented Oct 9, 2025

Couple issues I found, hopefully not user error here. This is on a fresh build with no weights set.

First one, the Limit to Max for strength doesn't seem to work. Intelligence and Dexterity properly cap.

Second one is related to first. If I set a max to Int (or Dex), once it hits that max, it seems to pick Strength much more than the other one. Almost like it defaults to Strength instead of using the weights on the other two. With all 3 set to 0 weight, I'd assume they should scale equally. This also happens with all three set to a weight of 1 instead of blank 0.
image
image

@majochem
Copy link
Contributor Author

majochem commented Oct 9, 2025

Thanks for testing. Can confirm, not user error.

I think it has something to do with "Strength" acting as a default fallback, if no attribute can be determined (I copied that behavior from the previous attribute logic). In equal weight scenarios it will therefore usually pick Strength first, but it should only happen on the first node and that's definitely not the case here.

I'll look into it

`maxDiff` was initialized at `0`, which led to problems when the
difference in attribute ratio was nominally negative.

There is secondary issue that needs to be fixed related to this, but
at least this ensures that maximum value always applies as a limit.

The other issue is that target ratios should be recalculated if a
maximum value is reached because it changes the relative weights of the
remaining attributes. Will be done in separate commit
@majochem majochem marked this pull request as draft October 9, 2025 11:57
@majochem
Copy link
Contributor Author

majochem commented Oct 9, 2025

Fixed the max value for Strength bug, but found another issue with ratios not being properly affected, once max values are reached, so I'm converting to draft again for the moment.

The weights and actual attribute values of attributes that had already
reached maximum values were still taken into account when calculating
current and target ratios, leading to wrong effective weights.

Now, if weights are `str: 10 / dex: 2 / int: 1` and strength reaches its
limit, it will be treated as `str: 0 / dex: 2 / int: 1`
@majochem majochem force-pushed the autoAttributeRatio branch from 0526f77 to 8f490f1 Compare October 9, 2025 12:43
@majochem majochem marked this pull request as ready for review October 9, 2025 15:52
@Blitz54
Copy link
Contributor

Blitz54 commented Oct 9, 2025

Confirmed previous issues are fixed.

Out of scope for this PR, but in game every support gem requires 5 of the same colour attribute. So I actually need 25 Dex in game to use the 5 green support gems I have equipped.

image image

@majochem majochem marked this pull request as draft October 13, 2025 13:00
The `Load()` function called `UpdateAutoAttributeConfig()` before
`calcsTab.mainOutput` was initialized, which led to an error. I've added
an additional `nil` check now
@majochem
Copy link
Contributor Author

Actually found another bug while using it myself. It's fixed now, but I marked the PR as draft again and will give it a few more days of testing with real builds.

@majochem
Copy link
Contributor Author

majochem commented Oct 17, 2025

Tested a bit more with my own characters, as well as some imported poe2.ninja characters, and it seems to work fine.
Also added the behavior for imports to the PR description. Marking as ready for review again.

@majochem majochem marked this pull request as ready for review October 17, 2025 11:45
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

Successfully merging this pull request may close these issues.

2 participants