Spell03 Unit Upgrades - Monster-Train-2-Modding-Group/Trainworks-Reloaded GitHub Wiki

Part 3: Unit Stat Upgrades (Not Razorsharp Edge)

← Part 2: Status Effects & Rooms | Next: Part 4: Dynamic Scaling Spells →

In this tutorial, we will build a card that modifies a unit's core stats by applying a CardUpgrade.

We will recreate the Awoken clan's classic Razorsharp Edge by building Not Razorsharp Edge, a 1-Ember spell that grants a unit +10 Attack and -2 Max HP. You will learn how to define a CardUpgrade, applying that upgrade to a unit, and about upgrade lifetimes.


1. Asset Setup

Download the custom card art:

  • Download Art: Save your card art texture as NotRazorsharpEdge.png.
  • Save Location: Place the file in your project under textures/NotRazorsharpEdge.png.

2. Complete JSON Definition

In Plugin.cs, add "json/spells/NotRazorsharpEdge.json" to your AddMergedJsonFile call. Then create json/spells/NotRazorsharpEdge.json and add:

{
  "$schema": "https://github.com/Monster-Train-2-Modding-Group/Trainworks-Reloaded/releases/latest/download/schema.json",
  "cards": [
    {
      "id": "NotRazorsharpEdge",
      "cost": 1,
      "names": {
        "english": "Not Razorsharp Edge"
      },
      "descriptions": {
        "english": "Apply +[effect0.upgrade.bonusdamage] and [effect0.upgrade.bonushp] to a unit."
      },
      "rarity": "uncommon",
      "targets_room": true,
      "targetless": false,
      "class": "ClassBanished",
      "card_art": "@NotRazorsharpEdgeCardArt",
      "pools": [
        "MegaPool"
      ],
      "effects": [
        "@ApplyUpgrade"
      ]
    }
  ],
  "effects": [
    {
      "id": "ApplyUpgrade",
      "name": "CardEffectAddCardUpgradeToUnits",
      "target_mode": "drop_target_character",
      "target_team": "both",
      "param_upgrade": "@TenAttackMinusTwoHealth",
      "param_int_3": 0
    }
  ],
  "upgrades": [
    {
      "id": "TenAttackMinusTwoHealth",
      "bonus_damage": 10,
      "bonus_hp": -2
    }
  ],
  "game_objects": [
    {
      "id": "NotRazorsharpEdgeCardArt",
      "type": "card_art",
      "extensions": {
        "card_art": {
          "sprite": "@NotRazorsharpEdgeSprite"
        }
      }
    }
  ],
  "sprites": [
    {
      "id": "NotRazorsharpEdgeSprite",
      "path": "textures/NotRazorsharpEdge.png"
    }
  ]
}

3. What’s New in This Recipe

The upgrades Section

"upgrades": [
  {
    "id": "TenAttackMinusTwoHealth",
    "bonus_damage": 10,
    "bonus_hp": -2
  }
]

The top-level upgrades list defines reusable stat and ability modifications:

  • bonus_damage: Increases (or decreases) a spells damage or a unit's attack.
  • bonus_hp: Increases (or decreases) a unit's maximum hp.

In addition to base stats, CaredUpgrades can also ad new traits, triggers, or status effects to cards and units.


Card description

"descriptions": {
  "english": "Apply +[effect0.upgrade.bonusdamage] and [effect0.upgrade.bonushp] to a unit."
}
  • [effect0.upgrade.bonusdamage]: Reads bonus_damage (10) from the upgrade referenced by the first effect (effect0).
  • [effect0.upgrade.bonushp]: Reads bonus_hp (-2). Because the value is negative, it naturally renders with its minus sign.

Applying Upgrades via CardEffectAddCardUpgradeToUnits

"effects": [
  {
    "id": "ApplyUpgrade",
    "name": "CardEffectAddCardUpgradeToUnits",
    "target_mode": "drop_target_character",
    "target_team": "both",
    "param_upgrade": "@TenAttackMinusTwoHealth",
    "param_int_3": 0
  }
]
  • name: CardEffectAddCardUpgradeToUnits is the effect for applying upgrades to units.
  • param_upgrade: References the @TenAttackMinusTwoHealth CardUpgrade we defined.
  • param_int_3: Controls the upgrade lifetime:
    • 0 = Temporary (default): Lasts until the current battle ends.
    • 1 = Transient: Lasts only while the unit remains alive in the room; when the unit dies, the upgrade is lost.
    • 2 = Permanent: Persists on the unit card the entire run.

Upgrade Lifetimes

When an upgrade is applied:

  • Temporary (0) or Permanent (2): Applied to both the active unit on the train floor and its underlying card in your deck. If you open your deck during combat, the unit card displays the modified stats.
  • Transient (1): Applied only to the unit and not its card. It does not modify the card in your deck and is lost if the unit is reformed or re-summoned.

Tip

Stat-only buffs follow the game's convention of using Temporary (0). If you deviate from the convention then it should be noted in the card's description.

Tip

Stat-only upgrades applied permanently should also set "param_bool": true. Setting param_bool to true will scale the existing upgrade if it is already present on the unit, saving memory.


4. Testing Your Card

  1. Build and copy your files to BepInEx/plugins/<YourMod>/.
  2. Launch the game and ensure the console reports no parsing or schema errors.
  3. Enter a battle and play Not Razorsharp Edge onto a friendly unit:
    • Verify the unit gains +10 Attack and loses 2 Max HP.
    • Open your Deck view during combat to confirm the unit card reflects these altered stats.
  4. (Optional) Change "param_int_3": 1 in your JSON, reload, and verify that the stats update on the field but do not alter the card when viewed in the deck.

Next Steps

Now that you can apply upgrades to units, continue to Part 4: Dynamic Scaling Spells (Play Other Cards) to make a cards effect grow dynamically based on actions taken during battle.

⚠️ **GitHub.com Fallback** ⚠️