-
Notifications
You must be signed in to change notification settings - Fork 5
Custom Monster Cards
For many of you, this is probably the exciting part. In fact, it may be so exciting that you skipped right over the previous tutorial about spell cards. Don't do that. Monster cards are actually just spell cards that summon monsters, and I'm not going to repeat things that were already covered there, so go back and read it over.
Once you've done that, you can move on to the next section.
The first card we will create is a Banner unit. A true classic. Blue Eyes White Dragon. This will cover the basic skeleton of a Monster Card, and common things you must set for all monster cards as well as more on specific card pools for monster cards.
Download the card art here, then download the monster art here. They're both static images. Animated characters are much more complicated, so they're covered in their own dedicated tutorial.
Of course Blue Eyes will be placed in the Pyreborne clan and have the Dragon subtype.
For monster cards we make a card with a singular effect to spawn a character. Then we define the character to spawn. As shown below.
{
"$schema": "https://github.com/Monster-Train-2-Modding-Group/Trainworks-Reloaded/releases/latest/download/schema.json",
"cards": [
{
"id": "BlueEyesCard",
"cost": 3,
"card_type": "monster",
"rarity": "rare",
"class": "ClassPyreborne",
"pools": [
"UnitsAllBanner",
"UnitsPyreborneBanner"
],
"card_art": "@BlueEyesCardArt",
"effects": [
"@SpawnBlueEyes"
]
}
],
"characters": [
{
"id": "BlueEyesCharacter",
"names": {
"english": "Blue Eyes White Dragon"
},
"character_art": "@BlueEyesCharacterArt",
"size": 5,
"attack_damage": 3000,
"health": 2500,
"subtypes": [
"SubtypesData_Dragon",
"SubtypesData_BannerUnit"
]
}
],
"effects": [
{
"id": "SpawnBlueEyes",
"name": "CardEffectSpawnMonster",
"param_character": "@BlueEyesCharacter"
}
],
"game_objects": [
{
"id": "BlueEyesCardArt",
"type": "card_art",
"extensions": {
"card_art": {
"sprite": "@BlueEyesCardSprite"
}
}
},
{
"id": "BlueEyesCharacterArt",
"type": "character_art",
"extensions": {
"character_art": {
"sprite": "@BlueEyesCharacterSprite"
}
}
}
],
"sprites": [
{
"id": "BlueEyesCardSprite",
"path": "textures/card_art/blueeyes.png"
},
{
"id": "BlueEyesCharacterSprite",
"path": "textures/character_art/blueeyes_character.png"
}
]
}A few things to note.
-
card_type- We set this tomonster, be sure to set this properly. The game uses this to define the look and feel of the card. If it were set to spell it would still work; however, the card would not have the attack, health, and capacity icons present on the bottom and top of the card. -
names- Notice we don't setnamesin the card's definition. The name of a monster card will be fetched from the character spawned by the card so no need to set that here it will be ignored. -
pools- We add this to two card pools:-
UnitsAllBanneris the main pool containing ALL banner units. You should put your banner units in this pool, otherwise it will not be picked for the Unit Banner reward after the ring 3 major boss battle. -
UnitsPyreborneBanneris the pool containing just Pyreborne's banner units. This pool is used for Pyreborne Banner map rewards.
-
A new top level section. characters specifies a list of characters we will define. Characters are any units you see in battle, your units, enemy units, even Flying Bosses, and the Titans all can be defined here, they are all the same type of data.
"characters": [
{
"id": "BlueEyesCharacter",
"names": {
"english": "Blue Eyes White Dragon"
},
"character_art": "@BlueEyesCharacterArt",
"size": 5,
"attack_damage": 3000,
"health": 2500,
"subtypes": [
"SubtypesData_Dragon",
"SubtypesData_BannerUnit"
]
}
],We define one character with id BlueEyesCharacter we will use this in the effects section coming up shortly. We give this character a name which in english is Blue Eyes White Dragon, like with card names you can specify translations in the other langauges supported by Monster Train 2.
-
character_art- Just like with cards, characters also need a sprite, we define this later. -
size- This is how much space the unit takes, this can be a number from 1 to 6, here this unit will take 5 capacity on the floor. -
attack_damage- This is how much attack the character has, staying true to his homage its 3000. -
health- The units HP. 2500. -
subtypes- Important field this determines what subtypes the character has. To make a unit a banner unit the special hidden subtypeSubtypesData_BannerUnitis used. We also want to make it the Dragon subtype so the subtype corresponding to that isSubtypesData_Dragon. The full list of subtypes is in the schema and will be present in autocomplete they are fairly intuitive what they are given the name.
"effects": [
{
"id": "SpawnBlueEyes",
"name": "CardEffectSpawnMonster",
"param_character": "@BlueEyesCharacter"
}
],Here we show a new CardEffect type - CardEffectSpawnMonster. This card effect, you guessed it. Spawns a monster. All you need to tell it is which character to spawn, we specify the BlueEyesCharacter we just defined. Remember to reference it we need to prepend an '@' to its id. All monster cards will have an effect that spawns the character in.
These sections will be simple since we are defining an non-animated sprite with just a static image.
Here is the game object definition. Just like with cards we specify we want a character art gameobject created for us. Be sure to set the type as character_art you can't reuse the card art GameObjects for character art as they have a different structure. You can reuse the card sprite for the character_art by setting sprite below to be the same sprite reference for the card art.
{
"id": "BlueEyesCharacterArt",
"type": "character_art",
"extensions": {
"character_art": {
"sprite": "@BlueEyesCharacterSprite"
}
}
} {
"id": "BlueEyesCharacterSprite",
"path": "textures/character_art/blueeyes_character.png"
}Once your JSON is saved, rebuild your project and copy to the Bepinex/plugins folder.
If you check the logbook and search in Pyreborne you will see that the new card is in the logbook but hasn't been discovered yet. If you don't then check the following
- All
@references match defined IDs - There are no trailing commas in your JSON
- The sprite path is correct
Make sure that the BepinEx logs don't produce any warning or error text, If you have the console enabled simply checking for red/yellow text.
You can give yourself the card by using one of the console mods if you are using Patty's DevConsole mod you can use the command card BlueEyesCard during a run to get the card for testing.
This character is a dragon costume. When it takes a hit, it puts on a new costume (graphical effect not included), gaining damage shield. If you remember from the last tutorial, Cards can have triggers; now we show that Characters can have triggers too!
Download the card art here and the character art here.
You'll find that it is very similar to Blue Eyes White Dragon, but note the addition of triggers.
{
"$schema": "https://github.com/Monster-Train-2-Modding-Group/Trainworks-Reloaded/releases/latest/download/schema.json",
"cards": [
{
"id": "DragonCostumeCard",
"cost": 2,
"card_type": "monster",
"rarity": "uncommon",
"class": "ClassPyreborne",
"pools": [
"MegaPool"
],
"card_art": "@DragonCostumeCardArt",
"effects": [
"@SpawnDragonCostume"
]
}
],
"characters": [
{
"id": "DragonCostumeCharacter",
"names": {
"english": "Dragon Costume"
},
"character_art": "@DragonCostumeCharacterArt",
"size": 2,
"attack_damage": 20,
"health": 5,
"subtypes": [
"SubtypesData_Dragon"
],
"triggers": ["@DragonCostumeHarvest"]
}
],
"character_triggers": [
{
"id": "DragonCostumeHarvest",
"trigger": "on_any_unit_death_on_floor",
"descriptions": {
"english": "Gain <nobr>[damageshield] [effect0.status0.power]</nobr>"
},
"effects": ["@DragonCostumeGainDamageShield"]
}
],
"effects": [
{
"id": "SpawnDragonCostume",
"name": "CardEffectSpawnMonster",
"param_character": "@DragonCostumeCharacter"
},
{
"id": "@DragonCostumeGainDamageShield",
"name": "CardEffectAddStatusEffect",
"target_mode": "self",
"param_status_effects": [
{
"status":"damage shield",
"count": 1
}
]
}
],
"game_objects": [
{
"id": "DragonCostumeCardArt",
"type": "card_art",
"extensions": {
"card_art": {
"sprite": "@DragonCostumeCardSprite"
}
}
},
{
"id": "DragonCostumeCharacterArt",
"type": "character_art",
"extensions": {
"character_art": {
"sprite": "@DragonCostumeCharacterSprite"
}
}
}
],
"sprites": [
{
"id": "DragonCostumeCardSprite",
"path": "textures/card_art/DragonCostume.png"
},
{
"id": "DragonCostumeCharacterSprite",
"path": "textures/character_art/DragonCostume.png"
}
]
}We'll only go over differences.
"triggers": ["@DragonCostumeHarvest"] - Here we set the triggers on the character to be the one we define below. DragonCostumeHarvest
A new top level section, character_triggers defines all of the CharacterTriggers we will use on characters we define.
"character_triggers": [
{
"id": "DragonCostumeHarvest",
"trigger": "on_any_unit_death_on_floor",
"descriptions": {
"english": "Gain <nobr>[damageshield] [effect0.status0.power]</nobr>"
},
"effects": ["@DragonCostumeGainDamageShield"]
}
],-
*id*- As with other things we assign an id to our CharacterTrigger which is referenced in the character. -
*trigger*- This determines the trigger type, the internal trigger name for Harvest is on_any_unit_death_on_floor. For a full list of internal -> in game name see Character Trigger Reference -
*descriptions*- Triggers also have descriptions, they add themselves to the card's text. The tags prevent the text from being split onto a new line. -
*effects*- Much like Card Triggers triggers also have a list of effects to play when the trigger fires.
Testing this is the same as Blue Eyes just give yourself the card during battle and play it. Notice that it has the purple Harvest trigger, test it out by playing a card that kills a unit and watch it gain Damage Shield.
This character introduces Room Modifiers — effects that apply to the room a character occupies for as long as that character remains there.
A good example from the base game is Deranged Brute (rage damage modification). Any unit with the yellow star icon has a Room Modifier.
Download the card art here and the character art here.
This definition is very similar to the earlier Blue Eyes White Dragon example. The main difference is the addition of a room_modifiers section and the reference to that modifier on the character itself.
{
"$schema": "https://github.com/Monster-Train-2-Modding-Group/Trainworks-Reloaded/releases/latest/download/schema.json",
"cards": [
{
"id": "FrostFuryCard",
"cost": 2,
"card_type": "monster",
"rarity": "uncommon",
"class": "ClassStygian",
"pools": [
"UnitsStygianBanner",
"UnitsAllBanner"
],
"card_art": "@FrostFuryCardArt",
"effects": [
"@SpawnFrostFury"
]
}
],
"characters": [
{
"id": "FrostFuryCharacter",
"names": {
"english": "Frost Fury"
},
"character_art": "@FrostFuryCharacterArt",
"size": 2,
"attack_damage": 20,
"health": 20,
"subtypes": ["SubtypesData_BannerUnit"],
"room_modifiers": ["@FrostFuryBonusFrostbite"]
}
],
"room_modifiers": [
{
"id": "FrostFuryBonusFrostbite",
"name": "RoomStateAddStatusEffectOnStatusApplied",
"titles": {
"english": "Frosty"
},
"descriptions": {
"english": "Apply +[power] stack of [frostbite] each time it is applied."
},
"param_int": 1,
"param_status_effects": [
{
"status": "poison",
"count": 0
}
]
}
],
"effects": [
{
"id": "SpawnFrostFury",
"name": "CardEffectSpawnMonster",
"param_character": "@FrostFuryCharacter"
}
],
"game_objects": [
{
"id": "FrostFuryCardArt",
"type": "card_art",
"extensions": {
"card_art": {
"sprite": "@FrostFuryCardSprite"
}
}
},
{
"id": "FrostFuryCharacterArt",
"type": "character_art",
"extensions": {
"character_art": {
"sprite": "@FrostFuryCharacterSprite"
}
}
}
],
"sprites": [
{
"id": "FrostFuryCardSprite",
"path": "textures/card_art/FrostFury.png"
},
{
"id": "FrostFuryCharacterSprite",
"path": "textures/character_art/FrostFury.png"
}
]
}The important addition is:
"room_modifiers": ["@FrostFuryBonusFrostbite"]This attaches the FrostFuryBonusFrostbite Room Modifier that we define in the file to the character. While this unit is in a room, the modifier becomes active and affects everything in that room according to its behavior.
The room_modifiers section defines all Room Modifiers used by your characters.
Unlike character_triggers, Room Modifiers are separate reusable objects with their own tooltip text, parameters, and behavior definitions.
"room_modifiers": [
{
"id": "FrostFuryBonusFrostbite",
"name": "RoomStateAddStatusEffectOnStatusApplied",
"titles": {
"english": "Frosty"
},
"descriptions": {
"english": "Apply +[power] stack of [frostbite] each time it is applied."
},
"param_int": 1,
"param_status_effects": [
{
"status": "poison",
"count": 0
}
]
}
]
-
*id*- As with other things we assign an id to our RoomModifier which is referenced in the character. -
*name*- Like the same parameter for card effects, this is an important parameter that specifies which Room Modifier class to use which defines the Room Modifier's behavior. -
*titles*- This sets the tooltip title for the Room Modifier. If you forget to set this each Room Modifier has a default title. -
*descriptions*- RoomModifiers also have descriptions, they add themselves to the card's text. Here, [power] is another special substitution text will resolve to the value inparam_intRemember not to hardcode it! -
*param_int*- This is a parameter used byRoomStateAddStatusEffectOnStatusAppliedIn this instance it specifies the amount of additional frostbite to apply when frostbite is applied. -
*param_status_effects*- Another parameter used byRoomStateAddStatusEffectOnStatusApplied. In this instance it specifies which status effects the room modifier looks for to apply additional stacks of said status effect.
Testing this card is the same process used in the Blue Eyes White Dragon example:
- Give yourself the card during a battle.
- Play the unit into a room.
- Notice the yellow star icon, which indicates an active Room Modifier.
- Apply Frostbite using a spell or another unit effect.
- Observe that additional Frostbite stacks are added automatically.