Skip to content

Twin Emperors: rebuild encounter state machine and stable ownership #2

Description

@RovxBot

Objective

Rebuild the Twin Emperors encounter-local state so it provides deterministic, instance-scoped phase control and stable boss ownership instead of reopening the fight from transient aggro.

Why this exists

The current strategy collapses immediately after swap windows because state is too loose.

Observed locally from the supplied logs:

  • tmp/Playerbots.log produced 493 split_risk, 27 movement_failure, 3 pickup_failed, and 40 unsupported_setup events.
  • The first collapse sequence is immediate:
AQ40 event=movement_failure bot=iledori role=healer ... reason=outside_leash path=none
AQ40 event=pickup_failed bot=jihthu role=ranged ... target=emperor_vek_lor:153
AQ40 event=split_risk bot=danderanor role=melee ... separation=61
  • The encounter later degrades after tank deaths:
17:00:13.970 UNIT_DIED Roveral
17:00:58.312 UNIT_DIED Standeric
17:01:01.997 UNIT_DIED Kohi
AQ40 event=unsupported_setup ... reason=missing_warlocks_and_melee_tanks mode=degraded warlocks=1 melee_tanks=0
  • split_risk never recovers once the collapse starts. Logged separation drops from 61 to a minimum of 17.

Current code hotspots

  • src/Ai/Raid/Aq40/Util/RaidAq40Helpers.cpp
    • BuildTwinEncounterSnapshot
    • ResolveTwinCurrentBossOwnerGuid
    • ResolveTwinBotExecutorGuid
    • IsTwinPostSwapThreatHoldActive
  • src/Ai/Raid/Aq40/Util/RaidAq40TwinEmperors.cpp
    • NoteTwinTeleportCast
    • GetActiveThreatHold
    • NoteTwinPickupEstablished
    • hold-window / pickup memory maps
  • src/Ai/Raid/Aq40/Action/RaidAq40Actions_TwinEmperors.cpp
    • GetTwinSnapshot
    • PrepareTwinRecoveryHold
  • src/Ai/Raid/Aq40/Util/RaidAq40Scripts.cpp
    • currently only hooks TwinTeleport

Required implementation

  • Introduce an explicit Twin encounter phase enum and state model. Minimum phases:
    • PrePull
    • Stable
    • TeleportWindow
    • PickupRecovery
    • EmergencySplitRecovery
    • Degraded
  • Track ownership separately for each boss:
    • expectedOwnerGuid
    • reserveOwnerGuid
    • candidateOwnerGuid
    • stableOwnerGuid
    • stableSinceMs
    • lastValidAtMs
  • Separate transient aggro from stable ownership. Stable ownership must require all of the following:
    • target has aggro on the correct emperor
    • target is alive and encounter-valid
    • range window is correct for the emperor
    • LOS is valid
    • target is on the correct side / anchor family
  • Do not clear threat holds just because Vek’lor briefly has a valid owner. Hold release must require:
    • both emperors have stable owners
    • current split is above the urgent band
    • no active Heal Brother emergency condition
  • Define reserve takeover behavior explicitly. If the primary tank dies or becomes invalid, reserve promotion must happen once and become visible in the encounter state instead of relying on ad hoc executor selection.
  • Keep all new state instance-scoped. Do not introduce global non-instance maps.
  • Preserve current public AQ40 action and trigger names. This is an internal Twin rebuild.

Reference patterns

Validation

  • Supported comp test: 2 warlock tanks, 2 melee tanks, dedicated side healers, hunters with pets, run through at least 3 teleports.
  • Success criteria:
    • no pickup_failed
    • no ownership thrash after teleport
    • no executor dead-end where both emperors become effectively unowned
    • no premature hold release while the split is still unsafe
  • Degraded test:
    • kill the primary melee tank
    • kill the primary warlock tank
    • confirm reserve takeover or deterministic Degraded behavior instead of repeated state flapping

Related

  • Foundation for #3, #4, #5, and #6.
  • #7 should only be finalized after this is in place.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions