Skip to content

[Demonology] Let cast-time on-use buff trinkets fire around Summon Demonic Tyrant - #11807

Open
bclinnin wants to merge 1 commit into
simulationcraft:midnightfrom
bclinnin:warlock-stormbound-emblem
Open

[Demonology] Let cast-time on-use buff trinkets fire around Summon Demonic Tyrant#11807
bclinnin wants to merge 1 commit into
simulationcraft:midnightfrom
bclinnin:warlock-stormbound-emblem

Conversation

@bclinnin

@bclinnin bclinnin commented Aug 26, 2026

Copy link
Copy Markdown

Demonology's buff-trinket line is unsatisfiable for any on-use buff trinket that has a cast time. The second clause requires Tyrant to be inactive:

(!pet.demonic_tyrant.active&trinket.N.cast_time>0|!trinket.N.cast_time>0)

and the third requires it to be active, its remaining arms needing either no Tyrant talent or trinket_priority pointing at the other slot:

(pet.demonic_tyrant.active|!talent.summon_demonic_tyrant|variable.trinket_priority=...)

With Tyrant talented and trinket_priority on the trinket's own slot, the conjunction can never be true. The line only ever fires through its trailing |variable.trinket_N_buff_duration>=fight_remains — once, in the last few seconds of the fight.

Two measurements with Stormbound Emblem of Dazar equipped, on the unmodified APL:

Test Result
Uses per fight at max_time 300 / 600 / 900 1.0 / 1.0 / 1.0 — independent of fight length, on a 120s cooldown
Stock line with the fight_remains clause removed never fires

The change

Add the matching cast-time arm to the third clause, so such a trinket may fire while Tyrant is nearly ready. Instant trinkets are untouched — the new arm sits behind cast_time>0.

+ trinket.N.cast_time>0&cooldown.summon_demonic_tyrant.remains<=4|

Two lines, +2 −2. With Stormbound equipped:

Uses/fight Duration Uptime
Stock 1.0 4.2s 1.40%
This PR 3.0 19.3s 19.19%
Ceiling (use_item on cooldown, no rotation) 3.0 20.0s 20.00%

Worth +0.98% to +2.89% across hero trees, target counts, item levels and fight styles, and inert for instant trinkets and for players without a cast-time buff trinket. Details below.


Full resultstarget_error=0.05
Case Stock This PR Delta
Soul Harvester, 1 target 211,976 215,169 +1.51%
Soul Harvester, 2 targets 268,679 274,669 +2.23%
Soul Harvester, 5 targets 439,055 451,754 +2.89%
Diabolist, 1 target 207,529 209,818 +1.10%
Diabolist, 2 targets 351,589 356,446 +1.38%
Diabolist, 5 targets 628,809 643,636 +2.36%
ilvl 320 210,704 213,518 +1.34%
ilvl 350 213,654 217,373 +1.74%
DungeonSlice 214,930 217,032 +0.98%
Emblem in trinket2 212,052 215,313 +1.54%

Regressions — this edits a line every Demonology trinket flows through, so both cases are measured rather than argued:

Case Stock This PR Delta
No cast-time trinket equipped 218,255 218,307 +0.02%
Vile Vial of Volatile Venom (instant on-use buff) 218,319 218,373 +0.02%

Both are noise, confirming instant trinkets take the unchanged path.

Note on methodology: the shipped profile embeds its own APL snapshot, so simming it directly does not exercise warlock.cpp. All runs above use an APL-stripped copy, verified equivalent to the embedded APL within 0.09%.

Why remains<=4

Swept against .ready / <=2 / <=6 / <=8 / ungated on both hero trees, target_error=0.05:

Variant Soul Harvester Diabolist
<=4 215,338 (1st) 209,890 (2nd, −0.004%)
<=2 214,643 209,899 (1st)
<=6 215,170 209,477
<=8 214,867 209,480
ungated 214,581 208,827
.ready 213,786 208,849

The trees disagree on the optimum, and <=4 is the only value strong on both. Ungated and .ready are the two worst on each, so the gate is doing real work.

Scope: which trinkets this actually affects

The bug needs both has_use_buff and cast_time>0. Across the MID2 trinket pool, exactly one item qualifies today:

Trinket has_use_buff cast_time>0 Affected
Stormbound Emblem of Dazar yes yes yes
Font of Venomous Rage no yes no — takes the damage branch
Vile Vial of Volatile Venom yes no no — instant satisfies clause 2
Voracious Heart of Ulatek yes no no
Gebbo's Bottomless Bag no no no
Vexhul's Everflowing Gland no no no
Zul'jin's Guillotine Technique no no no

So in practice this currently rescues one trinket. It is written as a logic fix rather than a named-item exception because the defect is in the condition, and any future cast-time on-use buff trinket would hit it the same way.

An earlier revision of this PR instead added a named use_item line for the emblem. That worked, but it routed around the broken condition rather than fixing it, and sat +9 −6 with a hard-coded item name; the repair here beats it in every test case above.

Note on has_use_buff

For the record, since it came up while investigating: trinket.X.has_use_buff resolves correctly for this trinket. item_buff_exists_expr_t falls back to a name lookup —

auto _list = e->buff_list;  // make a copy
if ( auto _buff = buff_t::find( &player, e->name() ); _buff && !range::contains( _list, _buff ) )
  _list.push_back( _buff );

— so the buff being created directly rather than through create_all_stat_buffs() (and therefore missing from special_effect_t::buff_list) does not affect the expression. There is no engine bug here; the problem is entirely in the APL condition.

…monic Tyrant

Demonology's buff-trinket line is unsatisfiable for any on-use buff trinket
with a cast time. For such a trinket the second clause requires Tyrant to be
inactive:

  (!pet.demonic_tyrant.active&trinket.N.cast_time>0|!trinket.N.cast_time>0)

while the third requires it to be active, the remaining arms needing either no
Tyrant talent or trinket_priority pointing at the other slot:

  (pet.demonic_tyrant.active|!talent.summon_demonic_tyrant|variable.trinket_priority=...)

With Tyrant talented and trinket_priority on the trinket's own slot the
conjunction can never be true, so the line only fires through its trailing
|variable.trinket_N_buff_duration>=fight_remains -- once, in the last few
seconds of the fight.

Measured with Stormbound Emblem of Dazar equipped: usage is 1.0 per fight at
300s, 600s and 900s max_time, i.e. independent of fight length despite a 120s
cooldown; and removing the fight_remains clause makes the trinket never fire
at all.

Add the matching cast-time arm to the third clause so such a trinket may fire
while Tyrant is nearly ready. Instant trinkets are unaffected -- the new arm is
gated behind cast_time>0.

  uptime  1.40% -> 19.19%   (1.0 -> 3.0 uses/fight, 4.2s -> 19.3s each)

  Soul Harvester  1/2/5 tgt  +1.51% / +2.23% / +2.89%
  Diabolist       1/2/5 tgt  +1.10% / +1.38% / +2.36%
  ilvl 320 / 350             +1.34% / +1.74%
  DungeonSlice               +0.98%
  emblem in trinket2         +1.54%

Regression, target_error=0.05: no emblem equipped +0.02%, and Vile Vial of
Volatile Venom (an instant on-use buff trinket) +0.02% -- both noise.

The <=4 threshold was swept against .ready / <=2 / <=6 / <=8 / ungated on both
hero trees; it is first on Soul Harvester and within 0.004% of first on
Diabolist. Ungated and .ready are the two worst on both.
@bclinnin
bclinnin force-pushed the warlock-stormbound-emblem branch from d87f6a9 to 9759a97 Compare August 26, 2026 19:52
@bclinnin bclinnin changed the title [Demonology] Sync Stormbound Emblem of Dazar to the Summon Demonic Tyrant ramp [Demonology] Let cast-time on-use buff trinkets fire around Summon Demonic Tyrant Aug 26, 2026
@bclinnin
bclinnin marked this pull request as ready for review August 26, 2026 21:04
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.

1 participant