Skip to content

Custom Equipment and Room Cards

Brandon edited this page Jun 5, 2026 · 7 revisions

Welcome! In this tutorial, we will create both an Equipment and a Room card and explain how both works.

Equipment and Room cards both are very similar in setup. Before starting this tutorial, make sure you understand how Card Upgrades work by reading:

Heavy Spiked Shield

Overview

The equipment card we will create is Heavy Spiked Shield.

This shield demonstrates the basic setup for an equipment card. When attached to a unit, it:

  • Increases the unit's capacity by 1.
  • Gives the unit 20 Spikes.
  • Gives the unit 50 Armor.
  • Gives the unit 30 additional Spikes while it is in the front of the room.

Download the card art here, then download the equipment icon here.

Full JSON Definition

Equipment cards are set up like other cards, but with two important differences:

  1. The card's card_type is set to equipment.
  2. The card uses CardEffectAttachEquipment as its main effect.

The equipment itself is defined as a CardUpgrade.

{
  "$schema": "https://github.com/Monster-Train-2-Modding-Group/Trainworks-Reloaded/releases/latest/download/schema.json",
  "cards": [
    {
      "id": "SpikedShieldCard",
      "cost": 1,
      "card_type": "equipment",
      "names": {
        "english": "Heavy Spiked Shield"
      },
      "descriptions": {
        "english": "+[effect0.upgrade.bonussize][capacity]."
      },
      "rarity": "uncommon",
      "targets_room": true,
      "targetless": false,
      "card_art": "@SpikedShieldCardArt",
      "effects": [
        "@SpikedShieldEquip"
      ],
      "pools": [
        "EquipmentPool",
        "RoomAndEquipmentDraftPool",
        "RoomAndEquipmentMerchant_EquipmentPool",
        "RoomAndEquipmentMerchant_RoomAndEquipmentPool",
        "EquipmentPoolNonEnemy",
        "FreeEquipmentMutatorPool",
        "RedCrownEquipmentPool",
        "RandomGraftedEquipmentForEvent_NoVoidArms_EquipmentPool"
      ]
    }
  ],
  "effects": [
    {
      "id": "SpikedShieldEquip",
      "name": "CardEffectAttachEquipment",
      "target_mode": "drop_target_character",
      "target_team": "monsters",
      "param_upgrade": "@SpikedShieldUpgrade"
    },
    {
      "id": "SpikedShieldMoreSpiky",
      "name": "CardEffectAddTempCardUpgradeToUnits",
      "target_mode": "self",
      "param_upgrade": "@Spikes30",
      "param_int_3": 1
    },
    {
      "id": "SpikedShieldLessSpiky",
      "name": "CardEffectRemoveTempUpgradeFromUnit",
      "target_mode": "self",
      "param_upgrade": "@Spikes30",
      "param_bool": true
    }
  ],
  "upgrades": [
    {
      "id": "SpikedShieldUpgrade",
      "bonus_size": 1,
      "status_effect_upgrades": [
        {
          "status": "spikes",
          "count": 20
        },
        {
          "status": "armor",
          "count": 50
        }
      ],
      "trigger_upgrades": [
        "@SpikedShieldVanguardMoreSpiky",
        "@SpikedShieldVanguardLostLessSpiky"
      ],
      "icon": "@SpikedShieldIcon"
    },
    {
      "id": "Spikes30",
      "status_effect_upgrades": [
        {
          "status": "spikes",
          "count": 30
        }
      ]
    }
  ],
  "character_triggers": [
    {
      "id": "SpikedShieldVanguardMoreSpiky",
      "trigger": "on_deathwish",
      "descriptions": {
        "english": "Gain [spikes] [effect0.upgrade.status0.power]."
      },
      "effects": [
        "@SpikedShieldMoreSpiky"
      ]
    },
    {
      "id": "SpikedShieldVanguardLostLessSpiky",
      "trigger": "on_deathwish_lost",
      "effects": [
        "@SpikedShieldLessSpiky"
      ]
    }
  ],
  "game_objects": [
    {
      "id": "SpikedShieldCardArt",
      "type": "card_art",
      "extensions": {
        "card_art": {
          "sprite": "@SpikedShieldCardSprite"
        }
      }
    }
  ],
  "sprites": [
    {
      "id": "SpikedShieldCardSprite",
      "path": "textures/card_art/SpikedShield.png"
    },
    {
      "id": "SpikedShieldIcon",
      "path": "textures/icons/SpikedShieldIcon.png"
    }
  ]
}

Breaking Down the Card Fields

{
  "id": "SpikedShieldCard",
  "cost": 1,
  "card_type": "equipment",
  "names": {
    "english": "Heavy Spiked Shield"
  },
  "descriptions": {
    "english": "+[effect0.upgrade.bonussize][capacity]."
  },
  "rarity": "uncommon",
  "targets_room": true,
  "targetless": false,
  "card_art": "@SpikedShieldCardArt",
  "effects": [
    "@SpikedShieldEquip"
  ],
  "pools": [
    "EquipmentPool",
    "RoomAndEquipmentDraftPool",
    "RoomAndEquipmentMerchant_EquipmentPool",
    "RoomAndEquipmentMerchant_RoomAndEquipmentPool",
    "EquipmentPoolNonEnemy",
    "FreeEquipmentMutatorPool",
    "RedCrownEquipmentPool",
    "RandomGraftedEquipmentForEvent_NoVoidArms_EquipmentPool"
  ]
}

A few things to note.

  • card_type - This tells the game that this card is an equipment card. Be sure to set this correctly, because the game uses it to determine the card's behavior and presentation.
  • descriptions - We set the base description. Equipment cards automatically show many common stat changes, such as Attack and Health modifications. However, size changes are not shown automatically, so we include the capacity increase in the description.
  • pools - Equipment should be added to several pools so it can appear in the correct places.Since this card is clanless, we do not add it to MegaPool or any clan-specific pools.
    • EquipmentPool - Mandatory. This card pool contains ALL equipment cards. Cards in this pool are preloaded at the start of the run. Failure to include the card in this pool may result in a Game Data files are corrupted error, so don't forget to include it in this pool.
    • RoomAndEquipmentMerchant_EquipmentPool - Recommended. Equipment should be added to this pool, regardless of rarity. This pool is used by the Merchant of Arms for the first shop item, which is an uncommon or rare Equipment. Event specific equipment or non draftable equipment should not be added.
    • RoomAndEquipmentMerchant_RoomAndEquipmentPool - Recommended. All equipment and rooms should also be added to this pool, regardless of rarity. It is also used by the Merchant of arms for the third shop item, which is a rare Equipment or Room.
    • RoomAndEquipmentDraftPool - Recommended. This is the pool used by the Armory map node. Event specific equipment or non draftable equipment should not be added.
    • EquipmentPoolNonEnemy - Recommended. This is the pool used by Swordmaiden's effect. If the equipment is intended for friendly units, add it here. Note: If it is instead an equipment intended to be played on enemies, then add it to EquipmentPoolEnemy instead. Note: If the equipment is not added to either of these two pools, Then Swordmaiden won't be able to draw the equipment at all.
    • FreeEquipmentMutatorPool - Optional. Used by Truffles' ability and the Enchanted Armory mutator. Add the equipment here if it is clanless or, if its a equipment card from a clan, it is usable even when that clan is not primary or allied.
    • RedCrownEquipmentPool - Optional. Used by the Red Crown effect from the Cult of the Lamb crossover event. Add the equipment here if it is clanless or, if its a equipment card from a clan, it is usable even when that clan is not primary or allied.
    • RandomGraftedEquipmentForEvent_NoVoidArms_EquipmentPool - Optional. Allows this equipment to appear as a random graft option from the Plague Doctor event. Add the equipment here if it is clanless or, if its a equipment card from a clan, it is usable even when that clan is not primary or allied.

Equipment Effects

The main effect used by equipment cards is CardEffectAttachEquipment.

    {
      "id": "SpikedShieldEquip",
      "name": "CardEffectAttachEquipment",
      "target_mode": "drop_target_character",
      "target_team": "monsters",
      "param_upgrade": "@SpikedShieldUpgrade"
    },

This effect lets the player select a friendly unit and attach the equipment to it.

The required field for this effect is:

"param_upgrade": "@SpikedShieldUpgrade"

This points to the upgrade that represents the equipment.

The Equipment upgrade

The equipment itself is defined as an upgrade.

    {
      "id": "SpikedShieldUpgrade",
      "bonus_size": 1,
      "status_effect_upgrades": [
        {
          "status": "spikes",
          "count": 20
        },
        {
          "status": "armor",
          "count": 50
        }
      ],
      "trigger_upgrades": [
        "@SpikedShieldVanguardMoreSpiky",
        "@SpikedShieldVanguardLostLessSpiky"
      ],
      "icon": "@SpikedShieldIcon"
    },

When the equipment is attached, this upgrade is applied to the unit.

When the equipment is removed or replaced, the upgrade is removed as well. This reverts the changes made by the equipment.

  • bonus_size - Changes the unit's size.

    • Positive values increase size.
    • Negative values decrease size.
    • Unit size cannot go below 1 or above 6.
  • status_effect_upgrades - Adds status effects to the equipped unit.

    This respects modifiers such as Dualism. For example, if the unit has Dualism when the equipment is applied, it will gain 40 Spikes and 100 Armor instead.

  • trigger_upgrades - Adds character triggers to the equipped unit, which will be explained in the next section.

  • icon - Equipment requires an icon.

    This icon appears on the equipped character. It is also used in merged equipment card art. See this image for a template.

Character Triggers

Now we will use a new trigger: Vanguard.

Vanguard is one of the passive blue triggers. Its effect is active only while a condition is true.

For Vanguard, the condition is:

The unit is in the front of the room.

When the condition becomes true, the Vanguard trigger immediately runs. When the condition stops being true, a separate "lost" trigger runs to undo the effect.

Internally, these triggers are named:

  • on_deathwish — Vanguard
  • on_deathwish_lost — Lost Vanguard

Note that on_deathwish_lost does not have a player-facing name.

Vanguard Setup and Effects

Here is the main Vanguard trigger:

{
  "id": "SpikedShieldVanguardMoreSpiky",
  "trigger": "on_deathwish",
  "descriptions": {
    "english": "Gain [spikes] [effect0.upgrade.status0.power]."
  },
  "effects": [
    "@SpikedShieldMoreSpiky"
  ]
}

This trigger applies the following effect:

{
  "id": "SpikedShieldMoreSpiky",
  "name": "CardEffectAddTempCardUpgradeToUnits",
  "target_mode": "self",
  "param_upgrade": "@Spikes30"
  "param_int_3": 1
}

That effect applies this temporary upgrade:

{
  "id": "Spikes30",
  "status_effect_upgrades": [
    {
      "status": "spikes",
      "count": 30
    }
  ]
}

Together, these make the unit gain 30 Spikes while it is in the front of the room.

The description uses replacement text to display the number of Spikes granted:

[effect0.upgrade.status0.power]

This references the first effect's upgrade, then the first status effect inside that upgrade, and gets its count.

Removing the Vanguard Bonus

Because Vanguard is conditional, we also need to remove the bonus when the unit is no longer in front.

If we do not do this, the unit will gain another 30 Spikes every time it moves to the front without losing the previous bonus.

{
  "id": "SpikedShieldVanguardLostLessSpiky",
  "trigger": "on_deathwish_lost",
  "effects": [
    "@SpikedShieldLessSpiky"
  ]
}

This trigger uses the following effect:

{
  "id": "SpikedShieldLessSpiky",
  "name": "CardEffectRemoveTempUpgradeFromUnit",
  "target_mode": "self",
  "param_upgrade": "@Spikes30",
  "param_bool": true
}

This is an effect that removes a previously applied upgrade from a unit. "param_bool": true is the flag that makes the effect respect dualism.

We also do not give on_deathwish_lost a description, because it does not have a player-facing name or icon. Addi### Why Use Temporary Upgrades Instead of Adding Spikes Directly?

You may wonder why we use:

CardEffectAddTempCardUpgradeToUnitsand CardEffectRemoveTempUpgradeFromUnit

instead of directly adding and removing Spikes with CardEffectAddStatusEffect and CardEffectRemoveStatusEffect.

The reason is subtle but important.

CardEffectRemoveStatusEffect removes the exact amount specified by the effect. It does not account for modifiers like Dualism.

For example:

  1. A unit has Dualism.
  2. It moves to the front of the room.
  3. The Vanguard effect grants 30 Spikes, but Dualism doubles that to 60 Spikes.
  4. The unit later moves out of the front position.
  5. If we used CardEffectRemoveStatusEffect, only 30 Spikes would be removed.

That would leave the unit with 30 extra Spikes it should not have.

By applying the Spikes through a temporary upgrade instead, both the application and removal respect the same modifiers. This keeps the unit's stats correct.

Testing Your Card

You can verify that everything is working correctly with the following test:

  1. Get a copy of the equipment and play it on an active monster.

Expected Result:

  • The unit should immediately gain 20 Spikes and 50 Armor.
  • The unit's size should increase by 1.
  • If the unit is in the front of the room, it should also gain 30 additional Spikes.
  1. Spawn another unit in front of the equipped unit.

Expected Result:

  • The equipped unit should immediately lose the 30 bonus Spikes from Vanguard.
  1. Give yourself Just Cause and swap the unit's position.

Expected Result:

  • The unit should gain or lose the 30 bonus Spikes depending on whether it is in the front of the room.
  1. Replace the equipment on the unit.

Expected Result:

  • The unit should lose 20 Spikes.
  • The unit should lose 50 Armor.
  • The unit's size should decrease by 1.
  • If the unit was in front of the room, it should also lose the 30 bonus Spikes from Vanguard.

Dance Room

Overview

The room card we will create is Dance Room.

Dance Room is a perfect venue for Banished and demonstrates several common room card features:

  • Room Ability — The room has an active ability, Shuffle!, which shuffles friendly units 3 times.
  • Room Modifier — The room shuffles friendly units again at the end of combat.
  • Room-Applied Trigger — Friendly units in the room gain Valor 1 on Shift.

Download the card art here, then download the equipment icon here.

Full JSON Definition

Room cards are set up like other cards, but with two important differences:

  1. The card's card_type is set to room.
  2. The card uses CardEffectAttachTrainRoomAttachment as its main effect.

Like equipment, the room itself is defined as a CardUpgrade.

{
  "$schema": "https://github.com/Monster-Train-2-Modding-Group/Trainworks-Reloaded/releases/latest/download/schema.json",
  "cards": [
    {
      "id": "DanceRoomCard",
      "cost": 2,
      "card_type": "room",
      "names": {
        "english": "Dance Room"
      },
      "descriptions": {
        "english": "Friendly units gain [valor] [effect0.upgrade.charactertrigger0.effect0.status0.power] on [shift].[halfbreak]Shuffle friendly units at the end of combat."
      },
      "rarity": "uncommon",
      "targets_room": true,
      "targetless": true,
      "card_art": "@DanceRoomCardArt",
      "effects": [
        "@DanceRoomAttach"
      ],
      "pools": [
        "TrainRoomPool",
        "MegaPool",
        "FreeRealEstatePool",
        "RoomAndEquipmentDraftPool",
        "RoomAndEquipmentMerchant_RoomPool",
        "RoomAndEquipmentMerchant_RoomAndEquipmentPool",
        "UnitsBanishedBannerReplacementMutator"
      ]
    },
    {
      "id": "DanceRoomShuffle",
      "card_type": "spell",
      "is_room_ability": true,
      "targets_room": true,
      "targetless": true,
      "cooldown": 3,
      "effects": [
        "@DanceRoomShuffleUnits",
        "@DanceRoomShuffleUnits",
        "@DanceRoomShuffleUnits"
      ]
    }
  ],
  "effects": [
    {
      "id": "DanceRoomAttach",
      "name": "CardEffectAttachTrainRoomAttachment",
      "target_mode": "room",
      "target_team": "monsters",
      "param_upgrade": "@DanceRoomUpgrade"
    },
    {
      "id": "DanceRoomShuffleUnits",
      "name": {
        "id": "@CardEffectShuffleUnits",
        "mod_reference": "Conductor"
      },
      "target_team": "monsters",
      "target_mode": "room"
    },
    {
      "id": "DanceRoomGainValor",
      "name": "CardEffectAddStatusEffect",
      "target_mode": "self",
      "param_status_effects": [
        {
          "status": "valor",
          "count": 1
        }
      ]
    }
  ],
  "upgrades": [
    {
      "id": "DanceRoomUpgrade",
      "room_ability_upgrade": "@DanceRoomShuffle",
      "trigger_upgrades": [
        "@DanceRoomValorOnShift"
      ],
      "room_modifier_upgrades": [
        "@DanceRoomPostCombatShuffle"
      ],
      "icon": "@DanceRoomIcon"
    }
  ],
  "character_triggers": [
    {
      "id": "DanceRoomValorOnShift",
      "trigger": "on_shift",
      "effects": [
        "@DanceRoomGainValor"
      ],
      "hide_visual_and_ignore_silence": true
    }
  ],
  "room_modifiers": [
    {
      "id": "DanceRoomPostCombatShuffle",
      "name": "RoomStateAddEffectPostCombatModifier",
      "param_effects": [
        "@DanceRoomShuffleUnits"
      ]
    }
  ],
  "game_objects": [
    {
      "id": "DanceRoomCardArt",
      "type": "card_art",
      "extensions": {
        "card_art": {
          "sprite": "@DanceRoomCardSprite"
        }
      }
    }
  ],
  "sprites": [
    {
      "id": "DanceRoomCardSprite",
      "path": "textures/card_art/DanceRoom.png"
    },
    {
      "id": "DanceRoomIcon",
      "path": "textures/icons/DanceRoomIcon.png"
    }
  ]
}

Breaking Down the Card Fields

Here is the main room card definition:

    {
      "id": "DanceRoomCard",
      "cost": 2,
      "card_type": "room",
      "names": {
        "english": "Dance Room"
      },
      "descriptions": {
        "english": "Friendly units gain [valor] [effect0.upgrade.charactertrigger0.effect0.status0.power] on [shift].[halfbreak]Shuffle friendly units at the end of combat."
      },
      "rarity": "uncommon",
      "targets_room": true,
      "targetless": true,
      "card_art": "@DanceRoomCardArt",
      "effects": [
        "@DanceRoomAttach"
      ],
      "pools": [
        "TrainRoomPool",
        "MegaPool",
        "FreeRealEstatePool",
        "RoomAndEquipmentDraftPool",
        "RoomAndEquipmentMerchant_RoomPool",
        "RoomAndEquipmentMerchant_RoomAndEquipmentPool",
        "UnitsBanishedBannerReplacementMutator"
      ]
    }

There are a few important fields to understand.

  • card_type - This tells the game that this card is an room card. Be sure to set this correctly, because the game uses it to determine the card's behavior and presentation.

  • descriptions - We set the base description. Unlike equipment cards, room cards should usually describe their own effects directly. If your room modifies stats, grants statuses, adds triggers, or runs effects at certain timings, that text should be included in the room card description.

  • pools - Like equipment cards, Rooms should be added to several pools so it can appear in the correct places.

    • TrainRoomPool - Mandatory. All room cards must be added to this pool. The game preloads the assets for cards in this pool at the start of the run. If the room is missing from this pool, the game may show a "Game Data files are corrupted" error.

    • MegaPool - Required (if draftable). Since this room belongs to the Banished clan and should be draftable as a battle reward, we add it to MegaPool.

    • FreeRealEstatePool - Optional. Used by the Free Real Estate mutator. Add the room here if it is clanless or if its effects are useful even when its clan is not primary or allied.

    • RoomAndEquipmentDraftPool - Recommended. This is the pool used by the Armory map node.

    • RoomAndEquipmentMerchant_RoomPool - Recommended.

    • All rooms should be added to this pool, regardless of rarity. This pool is used by the Merchant of Arms for the second shop item, which is an uncommon or rare Room.

    • RoomAndEquipmentMerchant_RoomAndEquipmentPool - Recommended

      All equipment and rooms should also be added to this pool, regardless of rarity. It is also used by the Merchant of arms for the third shop item, which is a rare Equipment or Room.

    • UnitsBanishedBannerReplacementMutator - OptionalThis pool contains Banished clan cards except banner units. It is used by the "Banner-ed"" mutator to replace banner node options with other cards from the clan.You do not need to add cards to this pool manually. Trainworks manages this pool and will add cards automatically if they are in MegaPool and are not banner units. For custom clans, a pool for the custom clan is automatically created and populated with draftable non-banner cards for that clan.

Room Effects

The main effect used by room cards is CardEffectAttachTrainRoomAttachment.

    {
      "id": "DanceRoomAttach",
      "name": "CardEffectAttachTrainRoomAttachment",
      "target_mode": "room",
      "target_team": "monsters",
      "param_upgrade": "@DanceRoomUpgrade"
    },

This effect attaches the room upgrade to the floor where the card is played.

The most important fields are:

"target_team": "monsters",
"param_upgrade": "@DanceRoomUpgrade"
  • target_team determines which units are eligible for unit-facing parts of the room upgrade. In this example, we use monsters so the room applies its unit effects to friendly units.

  • param_upgrade points to the upgrade that represents the room.

The Room upgrade

The room itself is defined as an upgrade.

    {
      "id": "DanceRoomUpgrade",
      "room_ability_upgrade": "@DanceRoomShuffle",
      "trigger_upgrades": [
        "@DanceRoomValorOnShift"
      ],
      "room_modifier_upgrades": [
        "@DanceRoomPostCombatShuffle"
      ],
      "icon": "@DanceRoomIcon"
    }

When the room is attached, different parts of this upgrade are applied in different ways:

  • trigger_upgrades and stat upgrades are applied to eligible units in the room.
  • room_modifier_upgrades are associated with the room itself.
  • room_ability_upgrade adds an active ability to the room.
  • icon determines the icon shown on the floor.

Eligibility for room-applied upgrades is determined by the CardUpgradeMasks on the upgrade and the target_team specified by the attach effect.

When the room is removed or replaced, the upgrade is removed as well. This reverts the changes made by the room.

  • room_ability_upgrade - Adds an active room ability. This requires a card configured as a room ability card.

  • room_modifier_upgrades - Associates a RoomModifier with the room. This is attached to the room itself, not to individual units.

  • trigger_upgrades - Adds character triggers to eligible units in the room.

  • icon - Rooms require an icon.

    This icon appears on the center of the floor. See this image for a template.

Room abilities

Room abilities are similar to unit abilities, but they use a different flag.

Here we define the Shuffle! room ability, which shuffles friendly units 3 times.

    {
      "id": "DanceRoomShuffle",
      "names": {
        "english": "Shuffle!"
      },
      "descriptions": {
        "english": "Shuffle friendly units three times."
      },
      "card_type": "spell",
      "is_room_ability": true,
      "targets_room": true,
      "targetless": true,
      "cooldown": 2,
      "effects": [
        "@DanceRoomShuffleUnits",
        "@DanceRoomShuffleUnits",
        "@DanceRoomShuffleUnits"
      ]
    }

The important field is:

"is_room_ability": true

This tells the game that this card should be used as a room ability rather than a normal spell card.

The ability uses the same shuffle effect three times:

"effects": [
    "@DanceRoomShuffleUnits",
    "@DanceRoomShuffleUnits",
    "@DanceRoomShuffleUnits"
]

The base game does not include a card effect for shuffling units, so we use one from Conductor.

    {
      "id": "DanceRoomShuffleUnits",
      "name": {
        "id": "@CardEffectShuffleUnits",
        "mod_reference": "Conductor"
      },
      "target_team": "monsters",
      "target_mode": "room"
    },

Because this effect is defined by another mod, the name field includes both:

  • The name of the effect id: @CardEffectShuffleUnits
  • The mod's name that provides it mod_reference: Conductor

This is the same pattern used earlier for custom traits.

Room Modifiers

Next, we define the Room Modifier that shuffles friendly units at the end of combat.

    {
      "id": "DanceRoomPostCombatShuffle",
      "name": "RoomStateAddEffectPostCombatModifier",
      "param_effects": [
        "@DanceRoomShuffleUnits"
      ]
    }

This modifier reuses the same shuffle effect from the room ability.

RoomStateAddEffectPostCombatModifier lets us run simple card effects at the very end of combat, after fighting has completely concluded.

Character Triggers

Lastly, we handle this part of the room's effect:

'Friendly units in the room gain Valor 1 on shift'.

    {
      "id": "DanceRoomValorOnShift",
      "trigger": "on_shift",
      "effects": [
        "@DanceRoomGainValor"
      ],
      "hide_visual_and_ignore_silence": true
    }
  • hide_visual_and_ignore_silence This should usually be set to true for triggers granted by rooms and artifacts.

    It does two things:

    1. Hides the trigger from the unit, so the bonus appears to come from the room instead.
    2. Allows the effect to work even if the unit has been silenced.

The effect itself is pretty straightforward:

    {
      "id": "DanceRoomGainValor",
      "name": "CardEffectAddStatusEffect",
      "target_mode": "self",
      "param_status_effects": [
        {
          "status": "valor",
          "count": 1
        }
      ]
    }

When the room is applied, each eligible unit gets a copy of this trigger. Because of that, we use:

"target_mode": "self"

Whenever one of those units shifts, that unit gains Valor 1.

This makes room effects easy to express using the same character trigger and card effect tools we have already used.

Testing Your Card

You can verify that everything is working correctly with the following test:

  1. Get a copy of the room card and play it on a floor.

Expected Result:

  • The room's icon should appear on the floor.
  • The room should have an active ability.
  1. Activate the ability while at least two friendly units are in the room.

Expected Result:

  • The units should shuffle within the room 3 times.
  • The units should gain Valor as they shift.
  • Depending on the shuffle results, units may gain multiple stacks of Valor.
  1. Give yourself Just Cause and swap a unit's position.

Expected Result:

  • Any unit whose position changed should gain Valor 1.
  1. Let a round of combat play out.

Expected Result:

  • Friendly units in the room should shuffle again at the end of combat.
  • The shuffle happens after Valor's armor generation effect triggers, so the frontmost unit after the shuffle may not be the unit that received the Armor bonus.

Clone this wiki locally