Skip to content

AbilityFactory

github-actions[bot] edited this page Jan 4, 2026 · 1 revision

AbilityFactory parses differently from the Keyword parser. Your Ability line will look more like a collection of name-value pairs:

A:<AB/SP/DB/ST>$ <AFSubclass> | <Necessary$ Parameters> | (<Separated$ By> | <Pipes$ Here>) | [Optional$ {Values} [Nested$ Dependency]]

The ability types are:

  • AB for Activated Abilities
  • SP for Spell
  • DB for Drawback and many abilities that are subsidiary to other things, like replacements. They are only used to chain AFs together, and will never be the root AF
  • ST for Static, this gets used in case the API should resolve without using the stack
    (e.g. the unique Circling Vultures special action is directly implemented in the script this way)

Syntax definitions like the above will use different symbols to separate the variable parts from the plaintext:

  • angle brackets for mandatory parts
  • square brackets for optional parts
  • round brackets for grouping parts that are exclusive to each other
  • curly brackets to denote the type of a parameter

NOTE:

  • these factories are refactored from time to time (often to adapt to new mechanics), so while some entries could be slightly outdated, the base information should still be correct
  • when in doubt you can always cross-check with the available APIs code
  • a few factories also have *All variants, these are slowly being phased out
  • some parameters are only added for very exotic cards, these won't be included here to keep the focus on understanding the general concepts of scripting
  • a good knowledge of the game rules is often helpful for some of the more complex cases covered

Common Parameters

Tip: the convention is to put most of these before AF-specific params for readability (with the exception of Descriptions better suited at the very end)

Cost / UnlessCost

Cost$ {AbilityCost} is the appropriate way to set the cost of the ability. Currently for spells, any additional costs including the original Mana cost need to appear in the Cost param in the AbilityFactory. For each card that uses it, the order in which the cost is paid will always be the same.

Secondary abilities such as those executed by triggers or replacements (usually) don't need costs. (This is one reason to use DB over AB in these cases.)

Read more about it in Costs

Defined / ValidTgts

Most effects need to know (at least implicitly) which players or objects they're trying to affect. There are two different ways for that:

  • Defined$ {Defined} if the ability describes on what it's applied
  • ValidTgts$ {Valid} for abilities that target

Read more about it in Affected / Targets

Restrictions / Conditions

Restrictions limit when abilities can be put on the stack and Conditions apply during resolving. Typical examples are "Activate only once each turn" or "If this spell’s additional cost was paid, [...]".

Read more about it in Restriction

SpellDescription

SpellDescription$ {String} is how the text of the ability will display on the card and in the option dialog for cards with multiple abilities.

The SpellDescription for secondary abilities is displayed when (and if) the ability prompts for user input in the prompt pane so it is useful to put some text there or rather split the text into the different effect parts.

StackDescription

StackDescription$ {String} is the description the ability will have on the stack. This is automatically generated by the effect, but may be overridden using this parameter. This is sometimes needed with complex effects, when the generated text can't handle some details. Properties of the spell can be accessed like this: {c:Targeted}. You can reuse the spell text by just putting SpellDescription or None to leave it empty.

Remember*

Remembering is often needed when a card becomes a new object, which is then further affected by the ability. Typical example: Flicker
Because cards keep their remembered parts when changing zones manual cleanup is usually required.

Duration

611.2a. A continuous effect generated by the resolution of a spell or ability lasts as long as stated by the spell or ability creating it (such as "until end of turn"). If no duration is stated, it lasts until the end of the game.

Values:

  • EndOfTurn (Default)
    Note: since more often an effect only lasts until end of turn this was chosen as default instead of following how the rule defines it
  • Permanent
  • AsLongAsControl
  • AsLongAsInPlay - it really depends on each card's wording if this or the below one is correct, since here CR 702.26f defines phasing out as an extra way of ending the effect
  • UntilHostLeavesPlay - if the effect should last while the host is still in play
  • UntilEndOfCombat
  • UntilYourNextTurn

AI params

  • IsCurse$ True - for effects that are normally treated positive e.g. Pump

  • AICheckSVar$ {Count}

  • AILogic$ {String}

  • AITgts$ BetterThanEvalRating.130 Normally the AI will only prefer targeting cards that satisfy the constraint. However, you can add AITgtsStrict$ True if playing it should only happen when enough of these cards are available, e.g. Rootwater Matriarch.

Factories (in Alphabetical Order)

Animate

Animate handles animation effects like "This card becomes a 5/5 green creature with flying until end of turn."

Parameters (all optional):

  • Power - the power to assign to the animated card
  • Toughness - the toughness to assign to the animated card
  • Types/RemoveTypes - the types to give to/remove from the animated card; comma delimited
  • RemoveSuperTypes/RemoveCardTypes/RemoveSubTypes$/RemoveCreatureTypes True - if the animated being should have these types instead as opposed to in addition to
  • Keywords/RemoveKeywords - a " & " delimited list of keywords to give to/remove from the animated being
  • Colors - a comma-delimited list of colors to give to the animated being (capitalized and spelled out)
    • ChosenColor accepted
  • Abilities/Replacements/Triggers/staticAbilities - a comma-delimited list of SVar names which contain abilities that should be granted to the animated being
  • RemoveAllAbilities - Remove all Abilities, Triggers, Statics and Replacement effects
  • sVars - a comma-delimited list of SVars that should be granted to the animated being

Attach

Attaches a permanent to an affected card or player.

Parameters:

  • Object$ {Defined} (Default: Self) - This is the Object that will be Attached
  • Choices$ {ValidCard} - can be used to choose the attachment instead
    can also be combined with Object so the choice is for what it should attach to
  • RememberAttached

Note that Forge's engine handles this automatically for Aura spells, so adding AILogic is a bit different but usually required:

SVar:AttachAILogic:{String}

  • Curse/Pump - A generic Curse/Pump for which the AI has a handful of checks to see if an appropriate target exists
  • GainControl - Gains control of the attached permanent
  • ChangeType - For attachments that change types, e.g. Evil Presence

BecomeMonarch

No own parameters.

Bond

Soulbonding two creatures. Only used internally by the engine.

Branch

Sometimes, an ability might do certain things when a specific condition is true, and others if not. This can be implemented by using Branch.

Parameters:

  • BranchConditionSVar$ {Count}
  • BranchConditionSVarCompare {comparator}
  • TrueSubAbility/FalseSubAbility$ {SubAbility} - executes the specified ability depending on how the condition evaluated

The example below is from Composer of Spring, which allows either a "land" or a "land or creature" to be put on the battlefield, depending on the number of enchantments you control:

SVar:TrigBranch:DB$ Branch | BranchConditionSVar$ X | BranchConditionSVarCompare$ GE6 | TrueSubAbility$ PutLandCreature | FalseSubAbility$ PutLand
SVar:PutLand:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Tapped$ True | ChangeType$ Land.YouOwn
SVar:PutLandCreature:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | Tapped$ True | ChangeType$ Creature.YouOwn,Land.YouOwn
SVar:X:Count$Valid Enchantment.YouCtrl

Note: sometimes you could also implement this via standard ability Conditions instead, but that requires careful consideration if the relevant property could be changed by one of the applicable effects.

Charm

This AF represents modal effects.

Parameters:

  • CharmNum$ {Integer} (Default: 1) - number of modes to choose
  • MinCharmNum$ {Integer} (Default: same as CharmNum) - if "up to" allows a variable number
  • Choices$ {SubAbilities} - a comma delimited list of SVars containing the modes

Choices

AF in this group let the player make choices from all kinds of categories and are often used to chain effects together. However, for common cases many effects already support this directly, e.g. PutCounter | Choices$.
Besides making the script more concise using such shortcuts usually also helps the AI making better use of the effect.

ChooseCard

NameCard

ChooseColor

ChooseGeneric

ChooseNumber

ChoosePlayer

ChooseType

This can be used when a player is asked to choose a card (sub)type.

Parameters:

  • Type - Typically "Card", "Creature" or a few special cases
  • ValidTypes {String} - alternative to above param to explicitly define the types
  • InvalidTypes$ {String} (Optional) - used to specify any type that can't be chosen

Clash

This AF handles clashing.

Parameters:

  • WinSubAbility$ (Optional)
  • OtherwiseSubAbility$ (Optional)

Cleanup

A non-functional, maintenance AF used for cleaning up certain variables before a spell finishes resolving.

Parameters:

  • ClearRemembered$ True - clear this card's remembered list. Generally useful for abilities that remember an object, do something to it, then need to forget it once it's done
  • ClearImprinted$ True - clear the imprinted cards
  • ClearChosenCard$ True - clear the chosen cards

Control

GainControl

Parameters:

  • NewController$ {Defined} (Default: You)

ControlExchange

ControlPlayer

ControlSpell

Copies

Clone

CopyPermanent

Copies a permanent.

Parameters:

  • NumCopies (Default: 1) - the number of copies to put onto the battlefield.
  • Keywords (Optional) - a list of keywords to add to the copies

CopySpellAbility

Parameters:

  • Num$ {Integer} (Default: 1)

Counter

Countering Spells or Abilities.

Parameters:

  • Destination - send countered spell to: (only applies to Spells; ignored for Abilities)
    • TopDeck

Counters

Factories to handle counters on cards or players.

Poison

Poison gives a player the specified number of poison counters.

Parameters:

  • Num$ {Integer} - the number of poison counters to give

PutCounter

Put any type of counter on a game object.

Parameters:

  • CounterType - specifies the type of counter and should appear in all caps
  • CounterNum$ {Integer} (Default: 1) - how many counters will be put on the chosen card
  • Placer$ {Defined}
  • ETB$ True - for ETB counters

RemoveCounter

Remove any type of counter from a game object.

  • CounterType (required) specifies the type of counter and should appear in all caps. It should be one of the values in the Counters enum.
  • CounterNum (required) specifies how many counters will be removed from the chosen card.
  • UpTo is optional. If an effect states you may remove "up to X counters", set this to True.

Proliferate

MoveCounters

Used for effects that move counters.

Parameters:

  • Source - The Source of the counters
  • Defined - The Destination of the counters
  • CounterType - The type of counter to move
  • CounterNum - The number of counters to move

Damage

DealDamage

Deal damage to a specified player or permanent.

Parameters:

  • NumDmg$ {Integer} - amount of damage dealt

EachDamage

Debuff

Removing Keywords.

Parameters:

  • Keywords
  • Duration

Destroy

Handles destruction of permanents.

Parameters:

  • NoRegen$ True

Effect

Effect is an oddball of the AF family. Where usually AFs have similarities to each other to help with AI use, this one's used for all sorts of continuous effects.

A good example is High Tide. It doesn't matter if the Island was in play, if it turned into an Island after the spell resolved, any of that.

A:SP$ Effect | Triggers$ IslandTrigger | SpellDescription$ Until end of turn, whenever a player taps an Island for mana, that player adds an additional {U}.
SVar:IslandTrigger:Mode$ TapsForMana | ValidCard$ Island | Execute$ TrigMana | Static$ True | TriggerDescription$ Whenever a player taps an Island for mana, that player adds an additional {U}.
SVar:TrigMana:DB$ Mana | Produced$ U | Amount$ 1 | Defined$ TriggeredActivator

Effect is most similar to Token as it creates a pseudo-permanent, except Effect creates in the command zone rather than the battlefield.

Parameters:

  • Abilities,Triggers,ReplacementEffects,StaticAbilities,SVars - comma separated lists which contain SVars that point to the appropriate type that the Effect will gain. You don't need to put the zone-specific params like EffectZone$ onto these
  • Duration
  • EffectOwner$ {Defined}
  • ForgetOnMoved$ {ZoneType} - gets rid of the effect if all remembered cards have left the affected zone
  • RememberObjects$ {Defined}
  • Stackable$ False - most effects are assumed to be stackable. By using this flag, the AI will know having a second one active is (at least mostly) useless, so it will save its resources for something else
  • Name$ {String} (Optional) - usually auto-generated
  • Image$ filename\without\extension (Optional) - image needs to reside in the tokens directory

Explore

Fight

FlipACoin

Fog

This AF is based on the original Fog spell: "Prevent all combat damage that would be dealt this turn." While this could be done with an Effect, the specialized nature of the AI gives it its own AF.

GainLife / LoseLife / SetLife

Have a player gain or lose the specified amount of life.

Parameters:

  • LifeAmount$ {Integer} - the value to modify the life total(s)

Game outcome

GameDraw

GameLoss

GameWin

RestartGame

Used in the script of Karn Liberated.

Goad

Loops

Repeat the specified ability.

Repeat

Parameters:

  • MaxRepeat - optional - the maximum times to repeat, execute repeat ability at least once
  • RepeatSubAbility - setup subability to repeat
  • RepeatOptional$ True - you make the choice whether to repeat the process
  • RepeatPresent, RepeatCompare, RepeatDefined, RepeatCheckSVar, RepeatSVarCompare - optional - condition check

RepeatEach

A more complex variant that iterates over objects of some type instead. During each RepeatSubAbility execution the current object is remembered.

Parameters:

  • RepeatSubAbility - required - to set up repeat subability
  • RepeatCards - to repeat for each valid card (zone: present zone of the valid repeat cards, default: battlefield)
  • DefinedCards
  • RepeatPlayers - to repeat for each valid player
  • RepeatCounters - to repeat for each valid counters

Mana

Add mana to a player's mana pool.

Parameters:

  • Produced$ {String}

Manifest / Cloak

Permanent State

AF for effects that alter a permanent's state.

Phases

SetState

Changing a cards state. This is mostly for Flip Cards or the Transform mechanic.

Tap

TapOrUntap

Untap

Play

Playing cards as part of another ability. The player may have to make a choice about which card to play if there are more choices than the number of cards to play.

Parameters:

  • Amount$ {Integer/All} (Default: 1) - how many cards can be played
  • Valid - selection criteria for valid cards from the zone to cast
  • ValidSA - applied after Valid, this will filter based on all spells of the cards
  • ValidZone - the zone to look in to determine the valid cards
  • Optional$ True - playing is optional
  • RememberPlayed$ True - remember the card played
  • PlayCost$ {AbilityCost}
  • WithoutManaCost$ True - The card can be cast without its normal mana cost
  • Controller$ {Defined} (Default: You) - controller of the ability

PreventDamage

Protection

Grants protection from traits like colors or card types.

Parameters:

  • Gains - the thing to gain protection from (green, artifacts, Demons, etc.) or "Choice" if you can choose one of a comma-delimited list of Choices$

Pump

Handles pumping creatures power/toughness or granting keywords to cards or players.

Parameters (all optional):

  • NumAtt$ - pumps Power
  • NumDef$ - pumps Toughness
  • KW$ - gives keywords

Due to its generic nature Pump is also the conventional "helper AF" when an effect requires more than one target with different restrictions, e.g. Political Trickery:

A:SP$ Pump | ValidTgts$ Land.YouCtrl | TgtPrompt$ Choose target land you control | SubAbility$ DBExchange | SpellDescription$ Exchange control of target land you control and target land an opponent controls. (This effect lasts indefinitely.)
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Land.OppCtrl | TgtPrompt$ Choose target land an opponent controls

Regenerate

Creating regeneration shields.

Reveal

RevealHand

Look at a player's hand.

Reveal

Parameters:

  • RevealValid to limit the valid cards
  • AnyNumber
  • Random
  • RememberRevealed to remember the cards revealed

PeekAndReveal

This AF is very similar to things that Dig can do, but handle a much simpler form, with less complex coding underneath. Similar to how RearrangeTopOfLibrary could be handled with Dig.

Primarily used with cards that allow you to Peek at the top card of your library, and allow you to reveal it if it's of a certain type. The Kinship cards fit this bill perfectly, so they are used to simplify the complex popups that would be required if using multiple Dig SubAbilities.

Parameters:

  • RevealOptional - Whether or not the Reveal is optional.
  • RememberRevealed - Whether to remember the revealed cards (after filtering by Valid)
  • RememberPeeked - Whether to remember the peeked cards (only if they are not revealed!)
  • RevealValid - defaults to Card, but allows you to set a specific ValidType if you can only have certain things
  • PeekAmount - defaults to 1, but allows you to peek at multiple cards if possible

RollDice

Sacrifice

Forces a player to sacrifice something of their choice.

Parameters:

  • SacValid$ {ValidCard} (Default: Card.Self)

Scry

Surveil

StoreSVar

Tokens

Amass

Investigate

Token

Token lets you create tokens of any type. They get defined by creating scripts in the res/tokenscripts folder.

Parameters:

  • TokenScript$ {filename[,filename]} - list of tokens to create
  • TokenAmount$ {Integer} (Default: 1)
  • TokenOwner$ {DefinedPlayer} (Default: You)

Triggers

If possible split the SpellDescription of the effect so the part for the trigger can become the StackDescription directly.

DelayedTrigger

The trigger-specific params are defined in Triggers.

ImmediateTrigger

Parameters:

  • TriggerAmount$ {Integer} (Default: 1)

Turn structure

AddPhase

AddTurn

EndTurn

ReverseTurnOrder

No own parameters.

SkipPhase

SkipTurn

Vote

Zone Affecting

For effects that modify zones in a specific manner.

ChangeZone

ChangeZone is a united front of any card that changes zone. This does not include: drawing, destroying, etc. as these represent specific words on which triggers and replacements can react.

Two primary forms are available after setting these parameters, depending on how the effect is templated:

  • Origin$ {ZoneType} is where the card is coming from
  • Destination$ {ZoneType} is where the card is going to
  • LibraryPosition {Integer} (Default: 0) - ignored when not moving to library. 0 represents the top, -1 the bottom

Hidden syntax

Hidden is generally used for origin zones that are not known information, e.g. the Library. The choice of "What card is changing zones?" happens during resolution. If you need this for public zones Hidden$ True is required.

Example (Call the Gatewatch):
A:SP$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Planeswalker | SpellDescription$ Search your library for a planeswalker card, reveal it, put it into your hand, then shuffle.

Parameters:

  • ChangeType$ {ValidCard}
  • ChangeNum$ {Integer}
  • Chooser$ {DefinedPlayer} - which player decides which card changes zone
  • Mandatory$ True - most of these abilities aren't mandatory, but CR 701.23d. means cards like Demonic Tutor are different

Known syntax

The second is known, instead designed for origin zones that are known information, like the battlefield. The choice of "What card is changing zones?" happens when it's put on the stack (or is at least fixed some other way).

Example (Excommunicate):
A:SP$ ChangeZone | ValidTgts$ Creature | Origin$ Battlefield | Destination$ Library | LibraryPosition$ 0 | SpellDescription$ Put target creature on top of its owner's library.

ChangeZoneResolve

This is a helper AF, for chained effects that create multiple permanents which should enter the battlefield at the same time.

To use it, you need to set the param ChangeZoneTable$ True on the first effect and then call this at the end.

This is supported by the following effects:

  • Amass
  • CopyPermanent
  • RepeatEach (NOTE: if you wrap the creation, you don't need to call this AF on its own)
  • Token

Dig

Dig is for an ability that does basically this: "You look at the X cards of your Library, put Y of them somewhere, then put the rest somewhere."

Parameters:

  • DigNum$ {Integer} - look at the top X number of cards
  • Reveal$ True (Default: False)
  • ChangeNum$ {Integer/Any/All} (Default: 1)
    • the number of cards to move to the DestinationZone
    • "Any" if you can move any number of Cards to DestinationZone
    • "All" when it's for things like "put all lands revealed this way into your hand"
  • ChangeValid$ {ValidCard} (Default: Card) - use this to specify if only certain types can be moved to DestinationZone
  • Optional$ True (Default: False) - if you "may" move a card to DestinationZone
  • SourceZone$ {ZoneType} (Default: Library) - the zone to dig in
  • DestinationZone$ {ZoneType} (Default: Hand) - the zone to put the Y cards in
  • DestinationZone2$ {ZoneType} (Default: Library) - the zone to put the rest in
  • LibraryPosition/LibraryPosition2 {Integer} (Default: -1) - if DestinationZone is Library, use this to specify position

DigUntil

Discard

Parameters:

  • NumCards$ {Integer} (Default: 1) - the number of cards to discard
  • Mode$ {String} - the mode of discard
    • Random
    • TgtChoose
    • RevealYouChoose
    • Hand
  • DiscardValid$ {ValidCard} (Default: Card) - acceptable cards to discard
  • UnlessType$ {ValidCard} - expression for "discard X unless you discard valid"

Draw

Parameters:

  • NumCards$ {Integer} (Default: 1) - the number of cards to draw

Mill

Parameters:

  • NumCards$ {Integer} (Default: 1) - the number of cards to mill

RearrangeTopOfLibrary

Shuffle

Used for shuffling a player's library.

Parameters:

  • Optional$ True - if the activator gets to decide if each affected player shuffles

TwoPiles

Clone this wiki locally