Skip to main content

Card Abilities

You can find a list of card abilities your version supports by finding the file cardabilites.md in the persistent directory described in the getting started guide.

Using card abilities

Creating a new card ability

You can use Lua scripts to add new card abilities.

To do so, you must create a new mod folder and add the following folder: GameData/CardAbilities/

For example, let's make a new ability called DestroyCardAbility:

First, create a file called DestroyCardAbility.lua, then write the following contents:

export = {
name = "Destroy card", --The name of the ability

parameters = { -- The parameters the ability uses

CardParameter.MakeStringParameter("TAGS", ""), -- Card tags (used to filter targets)
CardParameter.MakeBoolParameter("SELF", false), -- Whether to allow us to target ourselves
CardParameter.MakeBoolParameter("ALLY", false), -- Whether to allow us to target our allies
CardParameter.MakeBoolParameter("ENEMY", false), -- Whether to allow us to target our enemies
},

activeGameZones = { "ZONE_HAND" }, -- Which game zones this ability does something in

availableTargets = function(game, self, selectedTargets) --Get a list of all available targets

return HelperScripts.SearchTagInZones(game, -- Search for all zones
self.GetParameter("TAGS").stringValue, -- With the tags we want
self.card.playerID, -- Our player ID
self.GetParameter("SELF").boolValue, -- Ourselves
self.GetParameter("ALLY").boolValue, -- Allies
self.GetParameter("ENEMY").boolValue, -- Enemies
true, -- Whether to check for protection (Untargetable)
{ "ZONE_FIELD", "ZONE_SET" }); -- In the field and set zones
end,

hasAvailableTargets = function(game, self, selectedTargets) --Checks if we have any available targets

return HelperScripts.IsTagInZones(game, -- Search for all zones
self.GetParameter("TAGS").stringValue, -- With the tags we want
self.card.playerID, -- Our player ID
self.GetParameter("SELF").boolValue, -- Ourselves
self.GetParameter("ALLY").boolValue, -- Allies
self.GetParameter("ENEMY").boolValue, -- Enemies
true, -- Whether to check for protection (Untargetable)
{ "ZONE_FIELD", "ZONE_SET" }); -- In the field and set zones
end,

canPlay = function(game, self) -- Checks if we can play

return HelperScripts.CanPlayCard(game, self.card) and self.HasAvailableTargets(game, nil) -- We check if we can play the card and if we have targets
end,

onPlay = function(game, self, gameEvent) -- Called when we're playing the card

return HelperScripts.SpellOnPlay(game, self, gameEvent) -- We let the spell logic do its thing
end,

onPerformPlay = function(game, self, parameters)

local target = game.GetCard(parameters.GetParameter("TARGET").cardValue) -- Get our target

if target == nil then -- If it's invalid, stop

return
end

HelperScripts.EmitDeaths(game, -- Emit a death event to destroy the card
self.card, -- The source card (ourselves)
{ target } -- The target
)
end
}

Then, copy one of the cards you want to modify by copying the game data sources (for example, the Fireball card)

Make sure to make the copy in a similar path to the other cards (for example, GameData/Sets/AOF/CARD_DESTROY_CARD.json).

You can then modify the card data to suit your needs, and finally add the ability to it.

You want to find the field abilities and replace with your own:

    {
"name": "Destroy target",
"abilityName": "DestroyCardAbility",
"description": "",
"parameters": [
{
"n": "TAGS",
"t": null,
"dt": 3,
"sv": "FOLLOWER HERO"
},
{
"n": "SELF",
"t": null,
"dt": 0,
"bv": true
},
{
"n": "ALLY",
"t": null,
"dt": 0,
"bv": true
},
{
"n": "ENEMY",
"t": null,
"dt": 0,
"bv": true
}
]
}

Then you can enable the mod and test if your card works!

Card ability structure reference

Fields

name (String)

The name of the ability (required)

Example:

...
name = "My ability name",
...

parameters (Table)

List of parameters the ability uses. The default values of each parameter are ignored.

Example:

...
parameters = {
CardParameter.MakeBoolParameter("My bool parameter", -- parameter name
false), -- default value
CardParameter.MakeIntParameter("My int parameter", 0),
CardParameter.MakeStringParameter("My string parameter", ""),
},
...

flags (Table)

List of state flags the ability uses.

Example:

...
flags = {
CardParameter.MakeBoolParameter("My bool parameter", -- parameter name
false), -- default value
CardParameter.MakeIntParameter("My int parameter", 0),
CardParameter.MakeStringParameter("My string parameter", ""),
},
...

handledCharacteristics (Table)

List of characteristics the ability modifies. Please note that you must implement onGetCharacteristic if you use this!

Example:

...
handledCharacteristics = {
{
name = "ATTACK", -- Characteristic name
priority = GameCharacteristicLayer.Modifier, -- Type of change (Normal, Set, Modifier)
selfOnly = true, -- Whether it applies to the ability's card only
}
},
...

handledPlayerCharacteristics (Table)

List of player characteristics the ability modifies. Please note that you must implement onGetPlayerCharacteristic if you use this!

Example:

...
handledPlayerCharacteristics = {
{
name = "MAXIMUM_MANA", -- Characteristic name
priority = GameCharacteristicLayer.Modifier, -- Type of change (Normal, Set, Modifier)
selfOnly = true, -- Whether it applies to the ability's card only
}
},
...

handledEvents (Table)

List of events the ability handles. Please note you must implement handlesEvent and onEvent if you use this, and optionally expectedResultForEvent!

Example:

...
handledEvents = {
name = "EVENT_PARTY", -- Event name
phase = EventPhase.After -- Phase of the event (CheckReplacements, Before, During, After)
},
...

activeGameZones (Table)

List of game zones the ability is active.

NameDescription
ZONE_HEROHero Zone
ZONE_DECKDeck Zone
ZONE_SETSupport Zone
ZONE_FIELDField Zone
ZONE_DISCARDDiscard zone
ZONE_EXILEExile Zone

Example:

...
activeGameZones = { "ZONE_FIELD" },
...

activeWhenAttached (Bool)

Whether this ability is active while attached to something.

Example:

...
activeWhenAttached = true,
...

canActivate (function(game, self) -> Bool)

Returns whether this ability can be activated.

Example:

...
canActivate = function(game, self)

return HelperScripts.CanRest(game, self)
end,
...

onActivate (function(game, self) -> CardAbilityActivationPhase)

Called when this ability is activated.

Example:

...
onActivate = function(game, self)

if game.GetPlayer(self.card.playerID).GetState("MANA").intValue < 3 then

return CardAbilityActivationPhase.Cancelled -- Tells the system to cancel the activation
end

return CardAbilityActivationPhase.Continue -- Tells the system to continue (Cancelled, Continue, Finished). You may Finish instead of Continue.
end,
...

onPerformActivation (function(game, self))

Called to perform this ability's activation. This only gets called if onActivate returns Continue.

Example:

...
onPerformActivation = function(game, self)

game.MoveCard(self.card.playerID, self.card.GameZoneName, self.card.playerID, "ZONE_DECK", self.card.IndexInZone, -1)
end,
...