CombatEvent.SpecChanged record
The value GetSubProfession returns for an entity changed (spec-from-talent-buffs, 2026-09-26). Raised exactly once per REAL change of that value, whether it came from a talent root buff or from cast inference — never for a no-op re-resolution. Holding the previous spec across a same-class swap gap (the root buff removed before the new one arrives) is not a change, so Smite → gap → Lifebind raises ONE event, Smite → Lifebind; a gap that outlives 10 s drops the talent spec and raises one if the reported value changes. A class change (attr 220) with no root buff of the new class yet DOES raise one (old spec → the new class’s cast-derived spec, or 0). Changes are evaluated on the main-thread drain, never while a wire packet is mid-ingest, so the whole-packet net change is reported (a class swap delivering attr 220 and the new talent set together raises one event, not an intermediate old→0→new pair). Not raised when a scene change resets every spec to 0; specs re-announce (0 → spec) as entities reappear. Rides the existing ICombatEvents stream so no combat service interface gains a member.
public record SpecChanged : IEquatable<CombatEvent>Public Members
Section titled “Public Members”| name | description |
|---|---|
| SpecChanged(…) | The value GetSubProfession returns for an entity changed (spec-from-talent-buffs, 2026-09-26). Raised exactly once per REAL change of that value, whether it came from a talent root buff or from cast inference — never for a no-op re-resolution. Holding the previous spec across a same-class swap gap (the root buff removed before the new one arrives) is not a change, so Smite → gap → Lifebind raises ONE event, Smite → Lifebind; a gap that outlives 10 s drops the talent spec and raises one if the reported value changes. A class change (attr 220) with no root buff of the new class yet DOES raise one (old spec → the new class’s cast-derived spec, or 0). Changes are evaluated on the main-thread drain, never while a wire packet is mid-ingest, so the whole-packet net change is reported (a class swap delivering attr 220 and the new talent set together raises one event, not an intermediate old→0→new pair). Not raised when a scene change resets every spec to 0; specs re-announce (0 → spec) as entities reappear. Rides the existing ICombatEvents stream so no combat service interface gains a member. |
| FromTalent { get; set; } | true when the new value is talent-derived — the same meaning as TryGetTalentSpec returning true. |
| NewSubProfessionId { get; set; } | The sub-profession id now returned by GetSubProfession (0 = none). |
| OldSubProfessionId { get; set; } | The previously reported sub-profession id (0 = none). |
| TargetId { get; set; } | The entity whose spec changed (named to match the TargetId convention of its siblings). |
See Also
Section titled “See Also”- record CombatEvent
- namespace Stellar.Abstractions.Domain