You are viewing a potentially older version of this package. View all versions.
MADH95Mods-JSONCardLoader-2.5.4 icon


A mod made for Incryption to create custom cards, sigils, starter decks, tribes, encounters and more using JSON files.

Date uploaded 5 months ago
Version 2.5.4
Download link
Downloads 17570
Dependency string MADH95Mods-JSONCardLoader-2.5.4

This mod requires the following mods to function

BepInEx-BepInExPack_Inscryption-5.4.1902 icon

BepInEx pack for Inscryption. Preconfigured and ready to use.

Preferred version: 5.4.1902
API_dev-API-2.18.7 icon

The de-facto standard core API for all Inscryption mods. This lets you create new cards, abilities, challenges, map nodes, starter decks, and more.

Preferred version: 2.18.7


JSON Loader V2

This is a mod made for Incryption to create custom cards, sigils, starter decks, tribes, encounters and more using JSON files.

Version 2.0 of this mod is designed to create full compatibility with Version 2.0+ of the API. JSON files compatible with this API will have an extension of .JLDR2


As a mod creator using JSONLoader you can press "shift + r" to apply the changes you've made to any jldr2 files without having to restart the game.

Validation and GUI editing

You can use this online JSON Schema validator to avoid syntax errors, and make sure the fields are correct in your jldr2 files. Just put the contents of the corresponding schema from the Schema folder located in the JSONLoader files or on the github page in the left hand panel, and the contents of the jldr2 file that you want to validate in the right hand panel. If the json appears to be invalid the website will tell you where the error is and what exactly is wrong.

There is also a GUI based version that is an option, just input a schema in the panel at the bottom of the page and copy the json from the right hand panel when done!

Where do my files go?

Files go anywhere in the plugins folder, along with the artwork required for said file.

Converting Existing Cards to JLDR2

In order to have compatability with mod manager, version 2.0.0 breaks backwards compatability by default. Don't worry though! This mod comes with a backwards compatibility mode that can optionally be turned on. When turned on, all existing .JLDR files will be read in, converted to .JLDR2 files, and dumped back into the folder where the original JLDR was found. However, I cannot guarantee that the version will be 100% correct, especially when it comes to assigning the appropriate prefix to the card (see the first heading below under 'Custom Cards').

If you are a card creator, the best course of action is to set the config option to convert all JLDR files, manually inspect the JLDR2 files generated to ensure they are correct, then publish your mod with a brand new set of JLDR2 files.

For the most part, JLDR2 and JLDR are the same. The key differences are outlined here:

Abilities and Special Abilities

Previously, base game abilities and mod-added abilities were handled differently; they were completely separate parts of the file. Now, base game abilities and mod-added abilities are kept in the same list. Base game abilities are referred to by their enumerated name, such as "Flying" or "Reach." Mod-added abilities are referred to by a combination of the Mod GUID and their name. For example, the "Deathburst" ability from Void's sigil pack (part of the popular "All the Sigils" mod) is referred by the string "ATS.Deathburst"; in this example, "Deathburst" is the name of the ability, and "ATS" is the GUID of the mod.

So to create a card with both Flying and Deathburst, you would do something like the following:

"abilities": [ "Flying", "ATS.Deathburst" ]

This holds true for all custom enumerations on a card. In the case of Abilities and Special Abilities, this is very different behaviour from previous versions of JSONLoader. However, all enumerations are treated this way. For example, mod added Traits, Metacategories, special stat icons, etc can all be handled exactly the same way.

Evolve, Ice Cube, and Tail

Previously, these parameters were set as individual objects on the card. In a JLDR2, they have been "flattened" into the main card definition. The best way to understand this is to see an example:


    "evolution": {
        "name": "Bear",
        "turnsToEvolve": 1
    "tail": {
        "name": "BearTail",
        "tailLostPortrait": "taillessbear.png"
    "iceCube": {
        "creatureWithin": "FrozenBear"


    "evolveIntoName": "Bear",
    "evolveTurns": 1,
    "tailName": "BearTail",
    "tailLostPortrait": "taillessbear.png",
    "iceCubeName": "FrozenBear"

As you can see, the JLDR2 file has fewer child objects that have to be defined; the evolve, tail, and ice cube parameters are now on the card itself, reducing the overall size of the card file.

Custom Cards

To create your own cards you just create a .jldr2 file (written in json) and fill in all the fields you want your card to have (fields you don't include will be defaulted). The name field is required, and the rest are optional with default values (though that would be a boring card). Those fields and their values are specified in the table below. For reference, an example custom card (8 more f*cking bears_example.jldr2) is included in the Cards folder in this repo.

New Cards and Card Prefixes

If you are creating a new card, you need to consider how to name your card so that it does not end up accidentally sharing a name with someone else's card in the future. The accepted way to prevent naming collisions in the community is to prefix the names of your cards with a simple name or code representing your card pack. For example, if you are adding a bunch of cards for Act 3 themed around the all-time classic action movie The Matrix, you might prefix all of your cards with "matrix_" - for example, "matrix_Neo" and "matrix_Trinity." Then, if someone comes along after you and creates a card pack based on mythology and religion, and they also want to create a card called Trinity, they will name their card "myth_Trinity," and we no longer have any issues with having two cards named "Trinity." Note that they can both still be called "Trinity" on the card, but the internal game name is different.

Cards that are loaded via JSONLoader should indicate what their specific prefix is using the modPrefix field. This helps the card loading process recognize that you have properly prefixed your card and aren't simply using snake_case naming for multi-word cards. More specifically, we can't tell if a card named "Snow_Man" represents a snowman card, or if it's a card named "Man" with a mod prefix of "Snow."

Note that if your card's name and prefix don't match, the game will force it to match. So if your card's name is "StrongBad" and your card prefix is "HSR", the internal name of your card will be "HSR_StrongBad".

Editing base game cards

To edit a card from the base game, you similarly create a .jldr2 file and fill in the fields you want to edit on the card. You must include the name to be able to identify the card; the mod prefix is not necessary. Any fields you fill out will be changed, and everything else will stay the same. Note that you can only edit cards from the base game this way: you cannot edit cards from other mods.

The fields

Cards have lots of fields that can be filled - this is a list of all field names and their purposes. The fields you wish to include in the .jldr2 file should be copied exactly from this table, and any fields that refer to or Card should have their strings be copied exactly from there.

Field Description
name [Required] A string for the name the game will use to identify the card - should contain no spaces. When editing, this field must match the card's name (See Card for a list of ingame card names)
displayedName [Optional] [Default: ""] A string for the name displayed on the card
description [Optional] [Default: ""] A string for the description Leshy gives when you find the card
metaCategories [Optional] A string array of meta catagories the card has. See for the list that the game ships with. These can also be fully qualified guid+ability strings if they were added by another mod.
cardComplexity [Optional] [Default: Vanilla] A string for the complexity of the card (See for a list of levels of complexity)
temple [Optional] [Default: Nature] A string for which Scrybe created the card
baseAttack [Optional] [Default: 0] An integer value for the attack of a card
baseHealth [Optional] [Default: 1] An integer value for the health of a card
hideAttackAndHealth [Default: false] A boolean value to toggle if the cards attack and health are visible
bloodCost [Optional] [Default: 0] An integer value for the blood cost of a card
bonesCost [Optional] An integer value for the bones cost of a card
energyCost [Optional] An integer value for the energy cost of a card
gemsCost [Optional] A string array for the gems cost of a card (See for a list of gems)
specialStatIcon [Optional] An string for which special stat icon the card has. See for the list that the game ships with. These can also be fully qualified guid+ability strings if they were added by another mod.
tribes [Optional] An string array for the tribes the card belongs to. See for the list that the game ships with. These can also be fully qualified guid+ability strings if they were added by another mod.
traits [Optional] An string array for the traits a card has. See for the list that the game ships with. These can also be fully qualified guid+ability strings if they were added by another mod.
specialAbilities [Optional] A string array for the special abilities a card has. See for the list that the game ships with. These can also be fully qualified guid+ability strings if they were added by another mod.
abilities [Optional] A string array for the sigils a card has. See for the list that the game ships with. These can also be fully qualified guid+ability strings if they were added by another mod.
evolveIntoName [Optional] The name of the card that this card will evolve into when it has the Evolve sigil
evolveTurns [Optional] The number of turns to evolve
defaultEvolutionName [Optional] The name the card will have when it evolves (when it doesn't have evolve_ fields set)
tailName [Optional] The name of the tail card produced when this card has TailOnHit
tailLostPortrait [Optional] The .png file to switch the card's art with when the tail is lost
iceCubeName [Optional] The name of the card generated when the card has the IceCube ability
flipPortraitForStrafe [Optional] A boolean to determine if the cards portrait should flip when it uses one of the strafe sigils
onePerDeck [Optional] A boolean value that toggles if there can be only one of the card per deck
appearanceBehaviour [Optional] A string array for the behaviours the cards appearance should have. See for the list that the game ships with. These can also be fully qualified guid+ability strings if they were added by another mod.
texture [Optional] A string for the name of the card's image (must be .png). If it is in a subfolder within Artwork the subfolder should preceed the file name seperated by a '/' (or your system equivelent)
altTexture [Optional] A string for the name of the card's alternate image (must be .png)
emissionTexture [Optional] A string for the name of the card's emission image (must be .png)
titleGraphic [Optional] A string for the name of the card's title image (must be .png)
pixelTexture [Optional] A string for the name of the card's act2 image (must be .png)
animatedPortrait [Unavailable]
decals [Optional] A string array for the texture names of a card decals (must be .png)


Besides cards JSONLoader also allows you to create sigils. To do this, your file needs to end in '_sigil.jldr2'.

Here is the documentation for making sigils.

Talking Cards

JSONLoader also allows you to create talking cards! To do this, your file needs to end in '_talk.jldr2'.

All of the documentation for that can be found here!

Starter Decks

JSONLoader also allows you to create starter decks. To do this, your file needs to end in '_deck.jldr2' and should look like this:

    "decks": [
            "name": "DeckName1",
            "iconTexture": "icon.png",
            "cards": [ "Card1", "Card2", "Card3" ]
            "name": "DeckName2",
            "iconTexture": "icon2.png",
            "cards": [ "Card4", "Card5", "Card6" ]

Note that you can define any number of starter decks in a single '_deck.jldr2' file, and that the expected format of a '_deck.jldr2' file looks very different than that of other jldr2 files.


JSONLoader also allows you to create tribes. To do this, your file needs to end in '_tribe.jldr2' or '_tribes.jldr2' and should look like this:

    "tribes": [
      "name": "TribeName1",
	  "guid": "YourModGuid",
	  "tribeIcon": "tribeicon_custom1.png",
	  "appearInTribeChoices": true,
	  "choiceCardBackTexture": "card_rewardback_custom1.png"
      "name": "TribeName2",
	  "guid": "YourModGuid",
	  "appearInTribeChoices": false

Note that much like starter decks, any number of tribes can be defined in a single '_tribe.jldr2' file. Also note that if a tribe doesn't have a choiceCardBackTexture, one will be auto-generated based on the tribe's icon.


JSONLoader also allows you to create encounters. To do this, your file needs to end in '_encounter.jldr2' and should look like this:

	"name": "",
	"minDifficulty": 0,
	"maxDifficulty": 0,
	"regions": [""],
	"dominantTribes": [""],
	"randomReplacementCards": [""],
	"redundantAbilities": [""],
	"turns": [{
		"cardInfo": [{
			"card": "",
			"randomReplaceChance": 0,
			"difficultyReq": 0,
			"difficultyReplacement": ""

These are all the vanilla regions that you can use for your encounters: Alpine, Forest, Midnight, Midnight_Ascension, Pirateville, Wetlands


JSONLoader also allows you to add music tracks to the Gramophone in Leshy's cabin. To do this, your file needs to end in '_gram.jldr2' and should look like this:

  "Prefix": "Example",
  "Tracks": [
      "Track": "MyTrack.mp3",
      "Volume": 1
      "Track": "AnotherTrack.wav",
      "Volume": 1

You should put your mod's prefix in the "Prefix" field. You can add as many tracks as you want inside of "Tracks", following the example above.

"Track" should be the name of your audio file. The audio file should be located inside of the BepInEx/plugins folder. The supported audio formats currently are MP3, OGG, WAV and AIFF.

"Volume" should be the volume of your track, from 0 to 1, where 0 is silence and 1 is full volume. If you want your track to be at half volume, for example, you can put 0.5 in the Volume field.


If you want to translate your cards into other languages, add the language suffix to the end of the field name.

For example, if you want to translate the displayedName field into French, you would add a displayedName_fr field to your card.

Card localisation

  "name": "JSON_SuperHypeMan", 
  "modPrefix": "ExampleMod", 
  "baseAttack": 6, 
  "baseHealth": 9, 
  "displayedName": "Super Hype Man", 
  "displayedName_fr": "Super Animateur", 
  "displayedName_it": "Super Uomo dell'Eccitazione", 
  "displayedName_de": "Super Stimmungsmacher", 
  "displayedName_es": "Super Animador", 
  "displayedName_pt": "Super Animador", 
  "description_tr": "Süper Coşku Adamı", 
  "description_ru": "Супер Человек-Аниматор", 
  "description_ja": "スーパーハイプマン", 
  "description_ko": "슈퍼 하이프 맨", 
  "description_zhcn": "超级炒作男", 
  "description_zhtw": "超級炒作男"

New Languages

    "languageName": "Polish",
    "languageCode": "nl",
    "resetButtonText": "Reset with Polish",
    "stringTablePath": "stringtable.csv"

New Language Fonts

    "fontReplacementPaths": [
        "Type": "Liberation",
        "AssetBundlePath": "en_mainfont.assetbundle",
        "FontAssetName": "en_mainfont",
        "TMPFontAssetName": "en_mainfont"


To replace a mask that a boss puts on their face you can do it in a few ways.

Replace a mask with a texture

This will replace the angler mask model with a flat surface and apply a texture to it. The image dimensions are 1000x1500

  "maskName": "JSON_TestMask",
  "type": "Override",
  "texturePath": "testmask.png",
  "maskType": "Angler"

If you want to keep the original model but replace the texture you can add a field specifying the model type as below.

  "modelType": "Angler"



Simply download with Thunderstore Mod Manager!


To install this plugin you first need to install BepInEx as a mod loader for Inscryption. A guide to do this can be found here

You will also need the newest version of the InscryptionAPI plugin.

Finally, you simply need to put the JSONLoader.dll folder in BepInEx/plugins.


The easiest way to check if the plugin is working properly or to debug an error is to enable the console. This can be done by changing

\## Enables showing a console for log output.
\# Setting type: Boolean
\# Default value: false
Enabled = false


\## Enables showing a console for log output.
\# Setting type: Boolean
\# Default value: false
Enabled = true

in Inscryption/BepInEx/Config/BepInEx.cfg

To add cards to your deck to test if your cards work, you can download the debug menu mod

If you want help debugging you can ask in the #jsonloader channel in the Inscryption modding discord server.



  • made it so JSONLoader now loads files that end in "_example.jldr2"
  • made it so JSONLoader now ignores the "Examples" folder instead of the whole JSONLoader folder


  • fixed abilityLearnedDialogue
  • rewrote buffCards (again) to make it cleaner and work faster
  • added the changeAppearance field which has this format:

"changeAppearance": [{ "changePortrait": "portrait.png", "changeName": "Elder ([BaseCard.Info.displayedName])", "addDecals": [ "decal1.png", "decal2.png" ], "removeDecals": [ "decal3.png", "decal4.png" ] }]

  • added the OnDamageDirectly trigger which triggers when a card deals direct damage to the opponent, it has two variables [HitSlot] and [DamageAmount]
  • added the [DeathSlot] variable to the OnPreKill and OnPreDeath triggers
  • added a field called isPermanent to buffCards
  • made buffCards and transformCards point the camera at the hand instead of the board if the card that they're modifying is in the hand
  • added a function called SetVar which has this format: SetVar('function_name', 5) (currently gets resets after all actions caused by the current trigger have happened, but i will try to fix that later though)
  • added support for comments in any jldr2 file, comments are to be used in this format:

//This changes the appearance of a card "changeAppearance": [{ "changePortrait": "portrait.png", //This changes the portrait of the card "changeName": "Elder ([BaseCard.Info.displayedName])", //This is just like evolve! "addDecals": [ "decal.png" ] //And last but not least i add a decal to the card here }]

  • fixed generated variables causing an error if one of their variables were null
  • updated NCalcExtensions to the latest version
  • made it so all fields in configils can be empty or only whitespace without it causing an error
  • cleaned up some code
  • rewrote the readme and some file names for better consistency
  • updated the card names file, changelog and the configils documentation

--changes made by James <3--

  • fields in JSONLoader are no longer case sensitive and can be upper or lower case to avoid errors.
  • Tribe file extensions now support tribe.jldr2 and tribes.jldr2 to avoid errors.
  • Fixed reload and export hotkeys inverted.
  • Fixed JSONLoader not loading cards with non-english characters.


  • Fixed Emissions not working
  • Fixed mods with a custom tribe failing to load
  • Fixed cards overriden with JSON missing fields that aren't specified
  • Fixed Configils breaking due to parameters not being parsed correctly
  • Exposed hotkeys as configs to fit individual needs. (See config for more info)
  • _example cards are ignored yet again (This wasn't meant to be removed)


  • Fixed Encounters throwing errors when importing cards form mods
  • Incorrectly named cards will now throw an error and suggest names of similarly named cards.
  • Errors in .jldr2 files now log more information when they occur.


  • Bumped API requirement to 2.18.2
  • Added custom mask support (With example .jldr2 and .schema!)
  • Added custom language support (With example .jldr2 and .schema!)
  • Added translation support for cards using displayName and description.
  • Added support for overriding existing encounters
  • Added hotkey to export all compatible content to .jldr2 (Left Control + Right Control + X)
  • Added config to enable verbose logging to help debugging
  • Added Tribe .jldr2 example
  • Reduced the amount of times JSONLoader looks for files when starting the game
  • Moved Change notes from Readme to
  • Updated 8 Fucking bears card example. Includes custom tribe example

2.4.5 (configil patchnotes)

  • rewrote and cleaned up a ton of code
  • added the triggers: OnPlayerStartOfTurn, OnOpponentStartOfTurn, OnPlayerEndOfTurn and OnOpponentEndOfTurn
  • fixed retainMods removing the evolve sigil from the card because of some left over code from evolve
  • added targetCard to the card object
  • fixed a bug where the game would softlock when infused was not set in addAbilities
  • fixed targetCard only working with singular variables and not with things like functions, this does mean that targetCard will now require variables to be encased in parentheses to enable NCalc
  • fixed a bug where if you set one sigil to be infused in addAbilities that it would make all infused
  • changed removeAbilities to now be a list in this format: "removeAbilities": [{ "list": "", "name": "", "all": "" }]
  • added a new field to removeAbilities called "all", when this field is set to true all instances of a sigil will be removed from a card instead of just one (this also means that the default for removing sigils isn't removing all instances of that sigil anymore, but now just one)
  • added a new field called "list" to both addAbilities and removeAbilities, this field can be set to any list and will add/remove any sigils from that list from the targeted card
  • added a "damageSource" field to damageCards which functions like targetCard but changes what card the game will think the damage came from, this field can be set to "null" to have there be no damage source
  • changed gemCost in activationCost to be gemsCost instead to be in line with the card jldr2's
  • added a function called ListContains() which can be used to see if a list contains a certain object
  • added a couple of general use functions to check if a card has a certain "modifier" called: HasAbility(card, ability), HasTribe(card, tribe), HasTrait(card, trait) and HasSpecialAbility(card, specialAbility)
  • added a couple of functions to get the object of a specific type from it's name: Ability('GuidPlusName'), Tribe('GuidPlusName'), Trait('GuidPlusName') and SpecialAbility('GuidPlusName'). Here's an example of how you could use the Ability() function: (HasAbility([BaseCard], Ability('Submerge')))

(an object is basically just a container with information about something, so for example the object of a sigil contains things like: the name, the guid, the description, the metacategories etc.)


  • Actually added the file now


  • Readded an important file that i deleted because i thought it wasn't important :P


  • Fixed the patchnotes

2.4.0 (configil patchnotes)

  • Added a maxEnergy field to gainCurrency (coded by UwUMacaroniTime)
  • Made configils run much faster and have better performance (coded by kelly betty)
  • Fixed any errors relating to a sigil trying to access the card that it is on after it has died or has been removed from the board
  • Fixed the passive trigger spamming the console and cards dying when their attack was set to 0 when using the passive trigger
  • Fixed gainCurrency foils only being visual and not actually increasing the foil amount
  • Added a [DamageAmount] variable to both OnStruck and OnDamage
  • Fixed runOnCondition not working for sendMessage
  • Added two new variables [card.TemporaryMods] and [card.AllAbilities]


  • Added talking card support!


  • Added talking card support!


  • Added gramophone support


  • Added encounter support
  • Removed the [PlayerSlot()] and [OpponentSlot()] variable and replaced it with the GetSlot() function with this format: GetSlot(index, isOpponentSlot, fields) (fields is everything that you would have after the first dot of the original variable in single quotation marks)
  • Fixed a ton more configil bugs


  • Added tribe support


  • Added card and sigil reloading and fixed a ton of bugs with configils


  • Added API for adding cards


  • Added configils (made by Lily#7394)


  • Added starter deck support with help from Lily


  • Fixed a defect with converting JLDR to JLDR2 as it relates to editing base game cards
  • Base game cards are now edited directly instead of using the event. This fixes issues where copies of those cards still existed in other places but wouldn't get properly edited (example: Pack Rat).


  • Rewritten to be compatible with API 2.0


  • Added check for "_example" on the end of file name to remove example files from loading


  • Fixed discrepancies in ancillary files


  • Fixed error when assigning temple on custom cards
  • Removed TestDeck to be released as an individual mods
  • Support for customSpecialAbilities in API v1.12
  • Support for mod manager with custom .jldr extension on card files
  • cost changed to bloodCost in accordance with API
  • Refactored JLUtils into clearer classes
  • Removed redundant variables (evolve_evolutionName, etc.)
  • Alphabetized Card Names.txt
  • Made more infomrative


  • Fixed error if abilities array is present but empty


  • Added support for adding custom abilities implemented by other mods


  • Changed default "metaCategories" to be an empty list
  • Added


  • Compatability patch for InscryptionAPI v1.11
  • Refactored Code:
    • Error checking no longer uses exception handling to funciton
    • Game will load default deck if the names in the config for testdeck don't exist
    • baseHealth and metaCategories are handled before the call to NewCard.Add to avoid bloat in the function call
    • Removed Evolve/Tail/IceCubeParams handling to utilise API's handling of those aspects instead
    • Added ErrorUtil to better help with error logging
    • Made use of new json parser to read in Evolve/Tail/IceCubeData from json objects


  • Changed json parser from Unity's JSONUtility to TinyJson


  • Fixed error with png check


  • Added check for textures being png files


  • Fixed bug where textures were being assigned wrong


  • Fixed bug where "altTexture", "pixelTexture" and "titleGraphic" were being set to "texture"


  • Fixed linking error from update v1.3.5 Refactored Code:
    • Seperated EvolveData, TailData, and IceCubeData into their own files and gave them functions to handle their own generation and conversion to Param varients
    • Added class CDUtils to seperate the data from card adding/editing funcitons
    • seperated ExtensionUtils into it's own file


  • Compatablity patch for InscryptionAPI v1.10
  • Refactored code:
    • CardData has it's own file
    • Dicts has it's own file
    • EvolveData, TailData, and IceCubeData are now in their own file together
    • JLUtils was created to host utility functions like assignment helpers and validity checks


  • updated error logging for user


  • Added ability to edit existing cards with the use of "fieldsToEdit" with example card OP-ossum.json
  • Added better error logging for user


  • Compatablity patch for InscryptionAPI v1.8


  • Added validity check for TestDeck cards
  • Added functionality for:
    • EvolveParams via "evolve_evolutionName" & "evolve_turnsToEvolve"
    • TailParams via "tail_cardName" & "tail_tailLostPortrait"
    • IceCubeParams via "iceCube_creatureWithin"
  • Patched LoadScreenManager.LoadGameData and ChapterSelectMenu_OnChapterConfirmed to facilitate above implementation
  • Minor refactor of NewCard call


  • Added ability to use strings for the enum values on a card
  • Added ability to add cards to starting deck using config file in order to test functionality


  • Fixed issue with hard coded file paths


  • Handles cards that don't use:
    • EvolveParams
    • TailParams
    • IceCubeParams