Skip to content
Thin Creator 3483 edited this page Jun 8, 2024 · 32 revisions

Jsonloader Wiki

Generators

Heres a List of Generators for JSONLoader and a bunch of good stuff to go along with it:

Generator File Extension Link Extra Stuff
Animated Portraits .json https://tinyurl.com/Animjsons Requires: https://inscryption.thunderstore.io/package/KellyBetty/SpritesheetAPI/
Boss Cards _giant.json https://tinyurl.com/GiantCardsMaker Requires: https://inscryption.thunderstore.io/package/Cevin2006/GiantCardAPI/
Boss Dialogue _bd.json https://tinyurl.com/BDGenerator Requires: https://inscryption.thunderstore.io/package/KellyBetty/JSON_Boss_Dialogue/
Cards .jldr2 https://tinyurl.com/JsonCardMaker5
Custom Card Packs .jlpk https://tinyurl.com/jlpkgen2 Requires: https://inscryption.thunderstore.io/package/Infiniscryption/Pack_Management_API/
Encounters _encounter.jldr2 http://tinyurl.com/JsonEncountersV5
Gramophone Tracks _gram.jldr2 https://tinyurl.com/GramophoneJLDR2
Languages _language.jldr2 https://tinyurl.com/CustomLanguageJsonGenerator
Masks _mask.jldr2 https://tinyurl.com/MaskJsonGeneratorV2
Mod Manifests .json https://tinyurl.com/EasyuseManifestMakerTS Required for uploading your mod to Thunderstore
Sigils _sigil.jldr2 https://tinyurl.com/IKnowWhatImDoingConfigils4
Starter Decks _deck.jldr2 https://tinyurl.com/StarterDecksJsonV3
Talking Cards _talk.jldr2 https://tinyurl.com/TalkingCardJSON
Tribes _tribe.jldr2 https://tinyurl.com/TribeSchema2

Extra Stuff

All Enums (Including mods): https://github.com/SaxbyMod/SabyModEnums/wiki

Configils Wiki: https://docs.google.com/document/d/1QLAfomaTcatm-foU2P1ZoqGQFFvhCfmEnN4jIxAWceQ/edit?usp=sharing

For those using animated portraits I recommend making a Gif in https://www.pixilart.com/draw and downloading as sprite sheet!

Official JSONLoader Wiki: https://github.com/MADH95/JSONLoader/wiki

Animated Portraits

Animated Portraits is a Separated API that allows you to make Animated Card Portraits. For example You can make a Bee look like it's flying by making a sheet of frames each frame being a 114x94 and if you do it well enough it will look like it is Actually Moving. This file is stored in a .json and needs No suffix for Filtering.

Field Is Required? Field Type What does this do?
CardName String When a Card Name is entered what is stored within this file is applied to it a Card Name should be GUID_Name.
Spritesheet String This indicates which file the Spritesheet is stored within.
FrameRate Integer Determines the FPS The sheet displays with.
FrameCount Integer Determines the amount of flames that are in the sheet.
HasPause Boolean Determines whether the Playback has a Pause within it.
PauseTime Integer Determines how long the Playback will Pause for when HasPause is Enabled.

Example of Animated Portrait

{
  "CardName": "Goat", // Card applied to is Black Goat
  "Spritesheet": "MaidGoatAnim.png", // Sheet File Chosen
  "FrameRate": 20, // Runs at 20FPS
  "FrameCount": 10 // Sheet has 10 Frames.
}

Boss Dialogue

Boss Dialogue is a separated API that allows you to Change the Base Games Boss Dialogue for any Boss in KCM. The File's Extension is .json and Suffixed with _bd. The following are the Basic Fields.

Field Is Required? Field Type What does this do?
Filename String Determines what the screen will call the Dialogue
Description String This is a Basic Description of what the Dialogue Mode will do displays under the FileName in Game
Prospector Object Allows you to change any of the Prospectors Lines. See the Prospector Dialogue Section.
Angler Object Allows you to change any of the Angler's Lines. See the Angler Dialogue Section.
TrapperTrader Object Allows you to change any of the Trapper/Trader Lines. See the Trapper/Trader Dialogue Section.
Leshy Object Allows you to change any of Leshy's Lines. See the Leshy Dialogue Section.
Royal Object Allows you to change any of Royal's Lines. See the Royal Dialogue Section.

Prospector Dialogue

Field Is Required? Field Type What does this do?
PreIntro String Determines what Leshy says pre introduction to the Prospector.
Intro String Determines what The Prospector says when Introducing Himself.
BeforePickaxe String Determines what the Prospector says before hitting your cards with his pickaxe.
AfterPickaxe String Determines what the Prospector says after turning your cards into Gold.
IfNoGold String Determines what the Prospector says if there is no Gold on field after swinging the Pickaxe.
MuleKilled String Determines what the Prospector will say when his Trusty Mule Perishes.

Angler Dialogue

Field Is Required? Field Type What does this do?
PreIntro String Determines what Leshy says pre introduction to the Angler.
Intro String Determines what The Angler says when Introducing Himself.
GoFish String Determines what the Angler says before using the Hook Mechanic. (And when placing the Great Whites IIRC)
AimingHook String Determines what the Angler says when preparing to pull one of your cards to his side.
EasyChoose String Determines what the Angler says after choosing a card he wishes to pull to the other side.
HookPull String Determines what the Angler says Upon pulling one of your card's to his side.

TraperTrader Dialogue

Field Is Required? Field Type What does this do?
PreIntro String Determines what Leshy says pre introduction to the Trapper.
Intro String Determines what The Trapper says when Introducing Himself.
PrePhase2 String Determines what The Trapper says Pre switch to Phase 2.
Phase2 String Determines what the Trader says upon switch to Phase 2.
PreTrade String Determines what the Trader says Pre Pelt Trade.
Trade String Determines what the Trader says during the Trade.
PostTrade String Determines what the Trader says Post Trade.

Leshy Dialogue

Field Is Required? Field Type What does this do?
Intro String Determines what Leshy says when Introducing Himself.
AddCandle String Determines what Leshy says when he cheats himself a Third Candle.
Deathcards_Intro String Determines what Leshy says when Introducing the Deathcards at the beginning of Phase 2
Deathcards_Outro String Determines what Leshy says when Phase 2 Ends.
PreMoon String Determines what Leshy says Prior to Placing the Moon.
MoonPlaced String Determines what Leshy says Upon Placing the Moon.
StinkyMoon String Determines what Leshy says when a Stinky card is placed against the Moon.
MoonDestroyed String Determines what Leshy says when the Moon is Destroyed.

Royal Dialogue

Field Is Required? Field Type What does this do?
LeshyConfusion String Determines what Leshy says upon sighting Royals skull instead of his Normal Skull.
WakeUp String Determines what Royal's Skull says upon Awakening.
PreIntro String Determines What Leshy says pre Introduction to Royal.
Intro String Determines what Royal says when Introducing Himself.
Cannons String Determines what Royal says Upon placing the Cannons.
CannonFire String Determines what Royal says Upon Firing the Cannons.
Rodents String Determine what Royal says Upon giving you a Package of Vermin.
Limoncello_Charge String Determines what Royal says upon summoning his Ship.
LeshyStop String Determines What Leshy says upon stopping the movement of the Limoncello.
Limoncello_Intro String Determines what Royal says upon placing down the Limoncello.
Limoncello_Mutinee String Determines what Royal says when his crew jump off his ship.
Limoncello_NoCards String Determines what Royal says when all of his crew are gone.
Limoncello_Sunk String Determines what Royal says when his ship sinks into the Sea.
Defeated String Determines what Royal says upon his defeat.
Farewell String Determines what Royal says PreCredits Roll.

Dialogue Example

An Example Boss Dialogue file is as follows:

{
    "FileName": "KEVIN CLICK THIS!", // Defines the Dialogue Set
    "Description": "MAKES THE BOSSES KNOW KEVIN!", // Describes what the Dialogue Set is described with
    "Prospector": { // Starts Prospectors Dialogue
        "BeforePickaxe": "Why do you always forget, KEVIN!", // Replaces the Prior Pickaxe Swing Dialogue
        "AfterPickaxe": "TOO BAD, SO SAD, KEVIN!", // Replaces After Pickaxe Swing Dialogue
        "IfNoGold": "Damn, you remembered, I did not expect this!", // Replaces No Gold After Pickaxe Swing Dialogue
        "MuleKilled": "NOT MY MULE! WHY, KEVIN, WHY?" // Replaces Mule Death Dialogue
    },
    "Angler": { // Starts the Angler Set
        "GoFish": "FISH A NEW CARD!", // Replaces The Go Fish Dialogue
        "AimingHook": "THIS ONE SHALL DO!", // Replaces the Hook Aim Dialogue
        "EasyChoose": "I TAKE THIS LITTLE FISHIE", // Replaces Chosen Dialogue
        "HookPull": "DID YOU REALLY JUST DO THAT?" // Replaces Hook Pull Dialogue
    },
    "TrapperTrader": {
        "PrePhase2": "GOODBYE KEVIN *TRAP SHUTS*", // Replaces Prephase 2 Dialogue
        "Phase2": "HELLO KEVIN *BELL DINGS*", // Replaces Phase 2 Dialogue
        "PreTrade": "I SHALL TAKE THOSE FINE PELTS!", // Replaces PreTrade Dialogue
        "Trade": "CHOOSE THE BEST, KEVY BOY!", // Replaces Trade Dialogue
        "PostTrade": "I WOULD HAVE CHOSEN BETTER, KEVIN!" // Replaces Post Trade Dialogue
    }
}

Cards

Cards are a relatively simple thing to make in JsonLoader you just need to make a new .jldr2 file in your plugins folder and enter a json with the following fields:

Field Is Required? Field Type What does this do?
name String This is your in code name for the card Usually it won't be displayed on the card unless you don't have a DisplayedName Set. You are not allowed Spaces here.
modPrefix String This is basically how the game differentiates your card from the base game or another mods. You are not allowed spaces here.
displayedName String This is what your cards name is From the Players view such as on the card within the game.
description String This will be what leshy says upon introducing your card for the first time.
metaCategories String-Array This is how you set where your card appears if left empty your card wont show up in any pools. The Meta-Categories that can be entered are the Following: ChoiceNode, TraderOffer, Part3Random, Rare, GBCPack, and GBCPlayable.
cardComplexity String This is used during Act 1 to determine how Late in the game the card will be shown. The Options available: Advanced, Intermediate, Simple and Vanilla.
temple String Determines which scrybe this card belongs to Mainly for use in Act 2. The Options Available: Nature, Tech, Undead and Wizard.
baseAttack Integer Determines how much attack your card has lowest allowed is 0 Attack.
baseHealth Integer Determines how much health your card has lowest allowed is technically 1.
hideAttackAndHealth Boolean Determines whether cards Attack and Health should be shown.
bloodCost Integer Determines how much blood this card costs.
bonesCost Integer Determines how many bones this card costs.
energyCost Integer Determines how much Energy this card costs.
gemsCost String-Array Determines which Mox/Gems this card costs and how many. Options available: Blue, Green and Orange
specialStatIcon String Determines what stat icon is shown on the card can be vanilla or mod-added.
tribes String-Array Determines what tribes this card has applied can be vanilla or mod-added.
traits String-Array Determines what traits this card has applied can be vanilla or mod-added.
specialAbilities String-Array Determines what Special-Abilities this card has applied can be vanilla or mod-added.
abilities String-Array Determines what Abilities this card has applied can be vanilla or mod-added.
evolveIntoName String Determines what card this evolves into when it has/gains the Evolve Ability. Must be the Code name of the card can be from vanilla or a mod.
evolveTurns Integer Determines how many turns a card takes to Evolve.
defaultEvolutionName String Determines what this cards name becomes if it doesn't have a card to evolve into a vanilla example of this is how the Dam card becomes a God Dam when it Evolves.
tailName String Determines what card is placed when this card Loses its tail. Must be the cards In code name.
tailLostPortrait String Determines what this card's portrait becomes when it ends up Losing its tail. The image must be of this size: 114x94.
iceCubeName String Determines what this card turns into when it is broken out of the icecube. the name must be its in code name.
flipPortraitForStrafe Boolean Determines whether this card flips its portrait upon moving the direction it strafes in.
onePerDeck Boolean Determines whether or not this card may be obtained once in your deck.
appearanceBehavior String-Array Determines what Appearance Behavior this card has can be from a Mod or the base game.
texture String Determines what this card's portrait is in 3D based acts. Size of the image must be: 114x94.
emissionTexture String Determines what image gets overlayed when per example a card's abilities gets transferred onto it. Image size is 114x94
altTexture String Determines what this cards portrait is while the player has the Goat Eye on them. Image size must be: 114x94.
altEmissionTexture String Determines what this cards overlayed image is while the player has the Goat Eye on them. Image size must be: 114x94.
pixelTexture String Determines what the cards portrait is within 2D acts or the KCM screen. Image size should be: 41x28.
titleGraphic String Determines what image takes place of the cards name. Image size should be: 123x28.
decals String-Array Determines what image completely overlays the card. Image size is: 125x190.
extensionProperties Object Section where any mod added fields go such as the ones from the mod Custom Side Deck by TVF Labs.

Note: Non-Required Property's when not included Typically will default to not being enabled at all.

Example Card Json

{
  "name": "LFTD_Cicada", // Determines the In-Code Name of the card.
  "modPrefix": "LFTD", // Determines what Mod the card is from.
  "displayedName": "Cicada", // Determines what the card's name is shown as Within the game.
  "description": "The ever-bothersome cicada, with a buzzing so loud it can be heard far away.", // Determines what leshy tells you upon seeing it.
  "metaCategories": [ 
    "ChoiceNode",
    "TraderOffer"
  ], // Gives this card the Meta-Categorys of ChoiceNode and TraderOffer
  "cardComplexity": "Simple", // Sets the Act 1 Card Complexity.
  "temple": "Nature", // Tells the game this is Leshy's card.
  "baseAttack": 1, // Sets the cards attack value to 1.
  "baseHealth": 1, // Sets the cards health value to 1.
  "bloodCost": 2, // Sets the cost of this card to 2 blood.
  "tribes": [
    "Insect"
  ], // Gives this card the Insect Tribe.
  "abilities": [
    "BuffEnemy",
    "LFTD.Swarm"
  ], // Gives this card The Annoying sigil and a Mod added sigil from Legends_From_The_Darkness called Swarm.
    "tailName": "Tail_Insect", // If this card is given the Lose Tail sigil it will leave the Insect version of it in its place.
  "texture": "LFTD_Cicada.png", // Sets the Portrait of the card.
  "emissionTexture": "LFTD_Cicada_emission.png" // Tells the game what the Emissive layer of this card is.
}

Card Packs

This is a Seperated API that allows you to enable or disable Cardpacks via KCM. This file is a .jlpk and has no Suffix.

Field Is Required? Field Type What does this do?
Title String This determines what your Cardpack is called/What the cardpack is called.
Description String This determines what the Game displays as a Short discriptor of what the Cardpack Contains.
ModPrefix String This determines what GUID the cards within the Pack share for example with JSON it will contain all cards with the GUID of JSON.
PackArt String This determines what file the Package icon is stored in, The API automatically makes one if this is not included in the JLPK file. Image is a 46x74 File.
ValidFor String-Array Determines what Temples KCM Menus this pack applies to the following are the Pack Enums. MagnificusPack, GrimoraPack, P03Pack, and LeshyPack
SplitPackByCardTemple Boolean Determines whether your pack is split into multiple packs based on what Temple the cards within are a Part of. For Example if you have 5 Cards of Leshy, 20 Cards of P03, 10 Cards of Magnificus, and 3 Cards of Grimora it will Split them into 4 Packs for each Temple so One pack of 5, 20, 10, and 3.

Card Pack Example

{
  "Title": "Guild Of The Aztecs", // Sets the Title to `Guild Of The Aztecs`
  "Description": "This is the Guild of Cards created by the Aztec's for your playing Experience.", // Determines the Descriptor of your CardPack.
  "ModPrefix": "AZTEC", // Determines what GUID this applies towards.
  "PackArt": "AZTECIAN_Pack_Icon.png", // Determines the File the Pack Art is a Part of.
  "validFor": [ // Sets this pack to be Valid for all Temples.
    "LeshyPack",
    "P03Pack",
    "GrimoraPack",
    "MagnificusPack"
  ],
  "SplitPackByCardTemple": true // Makes it so the Pack is split into 4 Packs based on Temple.
}

Encounters

How do they work? this guide is aimed to help!

things you need to know:

  • when saving an encounter file it must end in "_encounter.jldr2"
  • remember to check if the json is valid (jsonlint is a good website to check)
  • when making encounters with custom cards, the internal name is used (including prefixes, ex: IGCC_Boar)

How every piece works individually:

Part Description Example
name Internal name, utilized by debugmenu to test your encounter name: "Example.JungleTheme"
minDifficulty How far into a level you should be in for the encounter to show up, determined by map nodes and KCM challenge skulls. (REDUNDANT: currently broken, use 1) minDifficulty: 6
maxDifficulty How far into a level you should be for the encounter to stop appearing. (REDUNDANT: currently broken, use 99) maxDifficulty: 32
regions What maps should the encounter appear in, multiple can be selected regions: [ "Wetlands", "Alpine", "Forest"]
dominantTribes What tribe should be selected when the encounter is a totem battle "dominantTribes":["Feline"]
randomReplacementCards What cards should be chosen from a pool, when randomReplacementChance is defined in a slot "randomReplacementCards": [ "Stoat", "Sparrow", "Snapper" ]
redundantAbilities What abilities shouldn't appear when the encounter is a totem battle "redundantAbilities": ["TouchOfDeath"]
turns The entire blueprint of the encounter "turns": [{ }]
cardInfo the individual row blueprint, card placements are randomized "cardInfo":[{card:"Wolf"},{card:"Opposum"}]
card What the card should be. "card": RatKing
randomReplaceChance How much, in percentage, of a chance should a random card replace "card" from the randomReplaceCards pool. "randomReplaceChance":50
difficultyReq What level should the "difficultyReplacement" card replace the originally defined card (works on node level and challenge skulls). "difficultyReq": 16
difficultyReplacement What card should replace the originally defined card, when the player reaches the specified "difficultyReq" level.

Map Enums:

Internal In-game Boss' map
Alpine Snow line Trapper/Trader
Wetlands Wetlands Angler
Forest Woodlands Prospector
Midnight Leshy Final Boss
Midnight_Ascension Leshy (KCM) Final Boss in KCM
Pirateville Royal alt. Final Boss

Unless you have mods that allow battles before the final boss, Midnight, Midnight_Ascension and Pirateville are redundant.

Example:

{
  
  "name": "Example.BirdEncounter",
  //internal name
  
  "minDifficulty":  1,
  //how far into the map you need to go before you stumble into this. (unused, best to leave it at 1)
  
  "maxDifficulty":  32,
  //how far until this encounter stops appearing (unused, best leave it at a high level)
  
  "regions": [
    
    "Alpine",
    
    "Forest"
    
  ],
  //what maps should this encounter appear in (alpine and forest is specified, will only show up in prospector and trapper/trader's map [Woodlands and Snow line respectively])
  
  "dominantTribes": 
   [
  
    "Bird"
    
   ],
   //the tribes that will be used as heads in totem battles
  
  "randomReplacementCards": 
  
  [
    "Sparrow",
  
    "RavenEgg",
  
    "Porcupine",
  
    "AntFlying",
  
    "Cuckoo",
  
    "Adder",
  
    "Bee"
],
//pool of cards that will be drawn at random when a random chance card is specified
  
  "redundantAbilities": 
  [
  
    "Flying"
  ],
  //what abilities won't appear during totem battles
  
  
  "turns": [
    
    {
      "cardInfo": [
      //wave 1
        {
        // 1st card
          "card": "Sparrow",
          //"sparrow is specified"
          
          "randomReplaceChance": 50,
          //"50% chance of a random card from the randomReplacementCards pool"
          
          "difficultyReq": 15,
          //"what level of difficulty (how many nodes you've passed + challenge tweaks in KCM) should be passed until the sparrow/random card is replaced by the difficultyReplacement"
          
          "difficultyReplacement": "Vulture"
          //"the card that replaces the original card in the battle when a level requirement is met 
        },
        {
          //"2nd card"
          "card": "RavenEgg",
          "randomReplaceChance": 25,
          "difficultyReq": 10,
          "difficultyReplacement": "Raven"
        }
		]
    },
    {
    //wave 2
         "cardInfo": [
        {
          "card": "Sparrow",
          "randomReplaceChance": 50,
          "difficultyReq": 15,
          "difficultyReplacement": "Vulture"
        },
        {
          "card": " ",
          //card is blank, no card shall be placed, useful for hiding cards until a specific level requirement or random chance cards (Not required for purposefully empty slots)
          "randomReplaceChance": 25,
          "difficultyReq": 10,
          "difficultyReplacement": "Raven"
        }
		]
    }
]

}

Gramophone Tracks

Gramophone Tracks are the Second Easiest thing to make within JSONLoader, Only seconded to Starter Decks due to needing to make or obtain a Music Track. This file should end with .json and have the suffix of _gram.

Field Is Required? Field Type What does this do?
Prefix String Determines what mod/id the track should be labled as Coming from.
Tracks String Array Determines What tracks should be loaded in from this file.
Track String Determines what the name of the Audio file to be loaded in (Goes in the Tracks String Array). File must be a .mp3, .wav, .ogg, .aiff, .aif
Volume Integer Determines what the volume of the track should be, Any Integer between 0 and 1 works such as 0.5 which makes the track play at half volume.

Gramophone Example

{
  "Prefix": "Saxby", // Defines what mod the track comes from.
  "Tracks": [ // Loads Tracks within the Brackets
    { // Loads in a `.wav` track at half Volume
      "Track": "TestTrackA.wav",
      "Volume": 0.5
    },
    { // Loads in a `.mp3` track at full Volume
      "Track": "TestTrack2.mp3",
      "Volume": 1
    }
  ]
}

Starter Decks

Starter Decks are Practically one of the Easiest things you can make In Jsonloader. They can have any amount of cards within them but a Strict Minimum of 3 Cards. To Setup make a new .jldr2 File with the Suffix of _deck and then make the json using the following Fields:

Field Is Required? Field Type What does this do?
decks Object This is what your starter deck is stored in, Essentially the Field's parent.
name String This is what the starter deck will be called.
iconTexture String This is the Image that will be displayed upon the deck. It is a 35x44 Texture.
cards String-Array This Array will determine what cards are in the deck. You can find a List of all options from the base game here: https://github.com/SaxbyMod/SabyModEnums/wiki/Card-Names-Wiki

Example Deck

To go more in depth Here's how an example deck file would look like.

{
  "decks": [ // Manages All decks within the file
    { // Registers Test Deck A
      "name": "TestDeckA", // Names Test Deck A
      "iconTexture": "TestDeckA.png", // Gives Test Deck A an Texture
      "cards": [ // Manages Deck A's Cards
        "AboveCurve", // Places Curve Hopper into the Deck
        "AnnoyTower", // Places Annoy FM into the Deck
        "DUMMY_5-5" // Places the Dummy from Act 2 Into the Deck
      ]
    },
    { // Registers Test Deck B
      "name": "TestDeckB", // Names Test Deck B
      "iconTexture": "TestDeckB.png", // Gives Test Deck B an Icon
      "cards": [ // Manages Deck B's Cards
        "Goat", // Adds the Black Goat to the Deck
        "Moose", // Adds the Moose Buck to the Deck
        "Grizzly" // Adds the Grizzly to the Deck.
      ]
    }
  ]
}

Talking Cards

Here you'll find instructions on how to make your own talking card with JSONCardLoader.

JSONCardLoader supports the following features for talking cards:

  • Custom animated portrait
  • Custom talking card dialogue, responding to many game events
  • Custom voice sound for your talking card, added through a short audio file
  • Support for facial expressions that you can change in your dialogue

All of this is done through JSON. You don't need to load any Unity prefabs or anything of the sort for your portrait either: All you need are some image files, which you'll referencing in your JSON file.

Preparation

You're going to need an existing card for this. You can create your own card with JSONLoader! The instructions for it should be in JSONCardLoader's Thunderstore page.

You're also going to need to make another JLDR2 file for this. This new file will contain all of the necessary information for the generation of your talking card.

This new JSON file must have a name that ends in "_talk.jldr2". If your file's name does not end in "_talk.jldr2", you will run into quite a few issues, so please make sure of that!

I'm gonna explain the structure of "_talk.jldr2" files below.

Structure

Alright, for starters you're using this mod, I heavily encourage you to use this JSON Generator for making your JSON file. I wrote the JSON schema for this generator myself, making sure to add as many descriptions and as much pattern-matching as I could to make the process easier for you.

Again, I heavily encourage you to use this JSON Generator: link.

Anyhow; the documentation.

Your JSON file should look like this:

{
  "cardName": "",
  "faceSprite": "",
  "eyeSprites": {
    "open": "",
    "closed": ""
  },
  "mouthSprites": {
    "open": "",
    "closed": ""
  },
  "emissionSprites": {
    "open": "",
    "closed": ""
  },
  "faceInfo": {
    "blinkRate": 1.5,
    "voiceId": "female1_voice",
    "voiceSoundPitch": 1,
    "customVoice": ""
  },
  "emotions": [
  ],
  "dialogueEvents": [
    {
      "eventName": "OnDrawn",
      "mainLines": [ "" ],
      "repeatLines": [
        [ "" ],
        [ "" ]
      ]
    }
  ]
}

I'm going to explain each field in detail below.

If you want to see an example of a _talk.jldr2 file completed filled out, you can look at my Talking Possum card. It has an animated portrait, dialogue codes and a custom voice.

Note: Backwards Compatibility

I have included backwards compatibility for all cards created with my TalkingCardAPI mod before it was merged with JSONLoader. Most fields are the same, except for "emissionSprites", which didn't exist back then: Instead, JSON files back then had a "emissionSprite" field, which accepted only one image (for an 'open eye' emission only). Thus, you can still use that field, though I'd encourage you to transition to the new structure instead!

Overview

An overview of every field in your JSON file, each of which will be explained in depth below:

Field Description
cardName The name of an existing card.
faceSprite An image for your card's face.
eyeSprites A pair of images for your card's eyes: open and closed, respectively.
mouthSprites A pair of images for your card's mouth: open and closed, respectively.
emissionSprites A pair of images for your card's eye emission: open and closed, respectively.
faceInfo A bunch of details about your card, which will be explained below.
emotions Your character's emotion sprites. Explained here.
dialogueEvents The dialogue for your card. Will be explained more in depth below.
Sprite Images

All of the images used for the character's face (including eyes, mouth and emission) should have the dimensions of a regular Inscryption Act 1 card portrait: That is, 114 x 94 pixels.

A good approach to making these face sprites is draw the face, eyes and mouth in different layers in your art program of choice and then exporting each layer separately!

You don't have to worry about any performance impact when putting the same image on multiple fields, as explained in this section below.

This mod also includes shorthand for an 'empty' texture, which you can use when you want a part of your character's face to not be displayed. The shorthand for that is a "_" in the field for the given image. This is explained more in depth in this section below.

FaceInfo

A set of details about your character's face: blink speed and voice.

Field Description
blinkRate How often your character blinks. The higher, the more often they'll blink.
voiceId Your character's "voice". Will explain more below.
voiceSoundPitch Your character's voice's pitch. The higher the number, the higher the pitch.
customVoice A custom voice for your character. Will be explained below.

"voiceId" can only be one of these three strings:

  1. female1_voice
  2. cat_voice
  3. kobold_voice

Most talking cards in the game use the first and simply change the pitch.

Custom Voices

You can add a custom voice to your character instead of using one of the default voices. For that, all you need to is put the path to your audio file in the "customVoice" field.

The supported audio formats are MP3, WAV, OGG and AIFF!

Please use a very short audio file for your voice. Typically, you want only a very short 'vowel' sound for this, since it's going to be played in rapid repetition.

If you put anything in "customVoice", then the contents of the "voiceId" field will not matter.

DialogueEvents

The "dialogueEvents" field is an array of dialogue event objects. If you're confused by this, you should use the generator I mentioned above: it makes this step much easier.

A dialogue event object has the following fields for you to fill:

Field Description
eventName The "trigger" for this dialogue event.
mainLines A set of lines that plays in the very first time this event runs.
repeatLines Multiple sets of lines that are played after the first time this event has run.

Each of these fields will be explained way more in depth below!

EventName

The "eventName" field can have the following strings for triggers:

Trigger Description
OnDrawn Plays when your card is drawn.
OnPlayFromHand Plays when your card is played.
OnAttacked Plays when your card is attacked.
OnBecomeSelectablePositive Plays when your card becomes selectable for a positive effect.
OnBecomeSelectableNegative Plays when your card becomes selectable for a negative effect.
OnSacrificed Plays when your card is sacrificed.
OnSelectedForDeckTrial Plays when your card is selected in the deck trial node.
OnSelectedForCardMerge Plays before your card receives the sigil in the sigil node.
OnSelectedForCardRemove Plays when your card is selected for removal.
ProspectorBoss Plays at the beginning of the Prospector fight.
AnglerBoss Plays at the beginning of the Angler fight.
TrapperTraderBoss Plays at the beginning of the Trapper/Trader fight.
LeshyBoss Plays at the beginning of Leshy's boss fight.
RoyalBoss Plays at the beginning of Royal's boss fight.
Main Lines

A set of lines that will be played in very first time that trigger runs for your card. The game remembers this. After the first time it plays, these lines will not play again for that same save file.

If you want these lines to ever play again, you can put them inside of the "repeatLines" array, which I'll explain below.

Repeat Lines

All the sets of lines that will be played in alternation each time this trigger runs for your card.

This field is a little funny, because it's an array of arrays! If you don't know what means, don't worry. This means you can have multiple sets of lines inside of repeatLines, like this:

"repeatLines": [
  [
     "This is a perfectly valid set of lines.",
     "It ends here."
  ],
  [
     "This is another perfectly valid set of lines.",
     "This one ends here."
  ]
]

If you're still confused about how these work, I heavily encourage you to use the JSON Generator I linked above. The schema I wrote for it includes full support for adding repeat lines.

Dialogue Codes

A really neat feature of Inscryption's dialogue events are dialogue codes, they add a lot of life to dialogue!

The dialogue codes most relevant to talking cards will be explained below. All of these work with talking cards.

Wait ([w:])

This is by far the dialogue code you'll wanna use the most. It's also the one the game itself uses the most in all of its dialogue.

The "[w:x]" dialogue code adds a pause of x seconds before the rest of a sentence plays.

You can use it like this:

"Hello.[w:1] How are you?"

In this example, after saying "Hello.", the character waits 1 second before saying "How are you?".

The number of seconds does not have to be an integer. Using "[w:0.2]" to wait only 0.2 seconds is valid, for example, and used often throughout the base game's dialogue.

This being said, I'd advise you not to go below [w:0.1], as I don't know how small the number can go before issues arise. (And there's no point in going below that, anyhow.)

Color ([c:])

The [c:] dialogue code changes the color of a portion of your text.

You can use it like this:

"[c:R]This text is red.[c:] This text is not."

In this example, the part after [c:R] is colored in the color that matches the code 'R', which is the color red, and the part after [c:] has the default text color. You can think of this as "switching on" the colorful text mode and then switching it off.

"But how do I know the codes for each color?" Fear not! Here's a comprehensive table of all available colors and their respective codes:

Code Color
B Blue
bB Bright Blue
bG Bright Gold
blGr Bright Lime Green
bR Bright Red
brnO Brown Orange
dB Dark Blue
dlGr Dark Lime Green
dSG Dark Seafoam
bSG Glow Seafoam
G Gold
gray Gray
lGr Lime Green
O Orange
R Red

(For the record: These are the colors the game has available, built-in. I did not choose them. Yes, it's a very odd selection of colors.)

Custom Colors

I have added a way to use custom colors with dialogue codes. In place of one of the color codes in the table above, you can instead use a hex color code, and this mod will parse the code into an usable Color for the text.

Here's an example:

"You must be... [w:0.4][c:#7f35e6]confused[c:][w:1].",

In this example, the word "confused" is colored in the color #7f35e6. Which, if you don't wanna look it up, is this color!

Please note that for compatibility reasons, your hex color code should include the '#'.

Leshy ([leshy:x])

The [leshy:x] dialogue code makes Leshy say x. This color code is very useful for making Leshy and your card talk a bit between each other!

You can use it like this:

"We're all doomed.[leshy:Quiet now.][w:2]",

In this example, the character says "We're all doomed." and then Leshy says "Quiet now." right after. The text remains on the screen for 2 seconds.

There are a few things to note from that example:

  1. You don't need to put quotation marks around the line Leshy is going to say.
  2. The "Wait" dialogue code is still usable with Leshy's lines.

Emotions

All of the base game's talking cards have more than one emotion. Emotions are exactly what they sound like: Different facial expressions for a character to convey different emotions.

For those who care about this: Emotions are a C### enum in the game's code. This means each item has a numeric value associated with them.

Your character's default emotion is "Neutral". This emotion is added by default.

Anyway, a comprehensive list of all emotions, and the numeric value associated with each:

Emotion Number
Neutral 0
Laughter 1
Anger 2
Quiet 3
Surprise 4
Curious 5

There's another item in the Emotion enum, "None", but you should probably not use it.

To learn how to add emotions, see this section. To learn how to use emotions, see this section.

Adding Emotions

You can include new Emotions for your card by adding them to the "emotions" array in your JSON file. This is what that should look like:

"emotions": [
  {
    "emotion": "Anger",
    "faceSprite": "Example_AngryFace.png",
    "eyeSprites": {
      "open": "Example_AngryEyes_Open.png",
      "closed": "Example_AngryEyes_Closed.png"
    },
    "mouthSprites": {
      "open": "Example_AngryMouth_Open.png",
      "closed": "Example_AngryMouth_Closed.png"
    },
    "emissionSprites": {
      "open": "Example_AngryEmission_Open.png",
      "closed": "Example_AngryEmission_Closed.png"
    }
  }
]

In the example above, a new emotion is added, "Anger", which changes the sprites for the character's face.

The "emotion" field should contain the name of a valid emotion. (See the table above!)

"Do I have to replace every sprite?"

You don't have to replace every single sprite when you make an emotion!

You can change only the fields you want to, and leave out the fields you don't want to change. The fields you leave out are ignored, and they "default" to the Neutral emotion's sprites for those fields.

See this example:

"emotions": [
  {
    "emotion": "Anger",
    "eyeSprites": {
      "open": "Example_AngryEyes_Open.png",
      "closed": "Example_AngryEyes_Closed.png"
    },
    "emissionSprites": {
      "open": "Example_AngryEmission_Open.png",
      "closed": "Example_AngryEmission_Closed.png"
    }
  }
]

In that example above, only the sprites for the eyes and eye emission are changed. The sprites for the face and mouth stay the same; that is, they default to the Neutral emotion's face and mouth sprites.

If you're still confused about how this works, I advise you use the JSON Generator I linked above. I wrote the schema for it myself, and it should help you with creating emotions (and everything else). You can even choose to toggle optional fields on and off, which is specially handy for emotions!

Side Note: Reusing Images

"I want to re-use the same image multiple times! Will that affect performance?"

This mod implements a little texture cache, so an image is always only loaded once regardless of how many times you use it in your JSON file. Because of this, you don't have to worry about using the same image multiple times.

This means if you really want to use the same image for a character's eyes across multiple emotions (and even across multiple characters), you can do so without fear of it affecting performance.

Side Note: Empty Texture

You can add an 'empty'/fully transparent texture to a field if you wish, 'hiding' that field. This mod adds shorthand for that: "_" (an underscore) in the image field.

Here's an example:

{
  "emotion": "Quiet",
  "eyeSprites": {
    "open": "Example_QuietEyes_Open.png",
    "closed": "Example_QuietEyes_Closed.png"
  },
  "emissionSprites": {
    "open": "Example_QuietEmission_Open.png",
    "closed": "_"
  }
}

In that example, the 'closed eyes' emission is replaced by an empty texture. This means the emission vanishes when the character blinks!

This is very useful for eye-centric emissions.

This has lot of other uses: Hiding the emission altogether, hiding a character's eyes or mouth for a given emotion, et cetera.

Using Emotions

You can change your character's emotion in their dialogue lines with the dialogue code [e:x], where 'x' is the name of an emotion. You can look at the table above for the names of all the available emotions.

This mod adds patches to make the emotion names not case-sensitive, which means the following lines are all equally valid:

"[e:Anger]I'm angry."
"[e:anger]I'm angry."
"[e:AnGeR]I'm angry and my keyboard is acting up."

If you prefer, you can use the numeric value associated with an emotion instead of its name! This is perfectly valid, for example:

"[e:2]I'm angry."

FAQ

Q: "I'm getting an error that says my _talk.jldr2 file couldn't be loaded! What does this mean?"

A: Please double check your file and make sure you didn't make any mistakes with the JSON syntax.

There are multiple JSON validator tools you can use online that catch syntax errors and things of the sort. A favorite of mine is JSONLint.