Page 1 of 1

Card, Spell, Ability, and Stack basics

PostPosted: 12 Jan 2015, 17:19
by pfps
Is there a good description of how the innards of Forge work?

In particular, I'm wondering why resetTargets is called so often. Is there something that requires this, or is it just being done out of caution?

Re: Card, Spell, Ability, and Stack basics

PostPosted: 12 Jan 2015, 18:10
by friarsol
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?

Re: Card, Spell, Ability, and Stack basics

PostPosted: 12 Jan 2015, 19:29
by moomarc
I worked on this project for so long, but never quite needed to track that whole sequence. I feel like a few things I tried would have been more successful if I had understood how StackInstances fitted in properly... But then again, maybe not.

Howdee everyone!

Re: Card, Spell, Ability, and Stack basics

PostPosted: 12 Jan 2015, 23:32
by pfps
That helps, thanks.

I think that there are a couple of glitches in the code that may have happened because of the way that the split between SAs (which are really neither spells nor abilities) and SpellAbilityStackInstances (which are the real spells and abilities) are done. First, the resetting of SAs appears to affect copying of spells (and allows the AI to have Pacts of Negation with no targets). Second, counterspells don't check that their target is on the stack at resolution.

I think that copying a spell should copy a SpellAbilityStackInstance, including targets, etc., which is then modified as necessary. A "may choose new targets" would be an explicit action after the copy. Only if the new targets are valid would they replace the previous targets.

Fixing counterspell needs the ability to determine whether a SASI is still on the stack, and is thus really still a spell.

Ideally, I think that it should be SASIs that resolve, not SAs. This might require too much refactoring of code to be viable at the moment, however.

Comments? Is there a better way to make copies of spells? Is there a better way to check counterspell targeting on resolution?