I'm not at my codebase, so this might not be 100% accurate but it generally goes like this:
(I'm just going to use activate everywhere instead of both activate and cast for the appropriate word)
0. Select a card to activate any potential SpellAbilities from the Zone it's in. If multiple SpellAbilities are available (spells in your hand with cycling, or permanents with multiple abilities that pass their timing restrictions), popup an input for the user to select one.
1. Initiate activating of the SpellAbility. Place the SA on the Stack, determine
X values, select targets. All of this is happening on the reusable SpellAbility class.
2. Pay costs of the SA until completion.
3. Finalizing the activation, spawn off all relevant data points (target, costs paid, etc) and create a new SpellAbilityStackInstance. Resetting the initial SA so it's completely fresh the next time someone wants to try to activate it, or the next time a StackInstance is resolving and needs to use the SA.
4. Start resolving, take the StackInstance, and load it back into the SpellAbility. Then check if the SA has fizzled. If not, resolve the SA (as best as we can) by running through the appropriate Ability Effects
I don't know think too much of that has changed recently, but I know about 3-4 years ago that was implemented because certain cards that are often activated multiple times in the same Stack were either concatenating or overwriting their targets. (
Masticore and
Umezawa's Jitte are the two prime examples)
Does that count as good description?