While it is the case for the existing official Skills, Skill implementations shouldn't be required to conform to a strain based approach.
There are other valid approaches to calculating skill difficulty that can be supported by abstracting the strain logic into its own StrainSkill class.
As strains are an implementation detail of the current Skill calculations, it makes sense that strain related logic should be encapsulated within the Skill class.
This was an insidious regression from a3dc1d5. Prior to that commit,
`DrawableHoldNoteHead` had `UpdateStateTransforms()` overridden, to set
the hold note head's lifetime. When that method was split into
`UpdateInitialStateTransforms()` and `UpdateHitStateTransforms()`, the
lifetime set was moved to the former.
Unfortunately, that override served two purposes: both to set the
lifetime, and to suppress hit animations which would normally be added
by the base `DrawableManiaHitObject`. That fact being missed led to
`UpdateHitStateTransforms()` hiding the hold note head immediately on
hit and with a slight delay on miss.
To resolve, explicitly override `UpdateHitStateTransforms()` and
suppress the base call, with an explanatory comment.
By moving this to a central location, we can avoid invoking the
EditorChangeHandler when there is no selection made. This helps
alleviate the issue pointed out in
https://github.com/ppy/osu/issues/11901, but not fix it completely.
Although this isn't necessary for existing official rulesets and calculators, custom calculators can have use cases for accessing mods in difficulty calculation.
For example, accounting for the effects of visual mods.
When starting a new section, the starting strain value was calculated using the unadjusted timing value, meaning decay curves were essentially being stretched or squashed according to the clockrate.
This caused incorrect strain peaks for any section where the peak occurs at the start of the section (none of the objects in the section added enough strain after decay to exceed the starting strain).
This bug caused star ratings with clockrates above 1 to be lower than they should and below 1 to be higher than they should.