Modding Custom Skills

Video Guide


Timestamps:

  • 0:29 Adding a new skill .json & pasting in information
  • 1:17 "id"
  • 1:49 "skillTier"
  • 2:07 "skillTargetType"
  • 2:30 "canTeamKill"
  • 2:45 "canDuel"
  • 2:58 "canChangeTarget"
  • 3:09 "attributeType"
  • 3:32 "atkType"
  • 3:49 "defType"
  • 4:16 "skillMotion"
  • 4:48 "viewType"
  • 5:13 "targetNum"
  • 5:23 "range"
  • 5:37 "defaultValue"
  • 5:54 "skillLevelCorrection"
  • 6:20 "abilityScriptList"
  • 7:03 "coinList" -> "operatorType"
  • 7:25 "coinList" -> "scale"
  • 7:37 "coinList" -> "abilityScriptList"
  • 7:52 Adding scripts to skills | find scripts here
  • 11:42 Adding multiple skills to one skill .json
  • 12:16 Adding the skills to an identity

Text Guide

Making custom skills is a true rabbit hole of madness, so while I'll be doing my best to try and simplify it all. Feel free to DM froggo on discord regarding any of the myriad of stupid problems you've encountered.

Finding The Right Data

While with personalities I recommend simply grabbing the json and erasing everything, this isn't really applicable for skills as their jsons are much larger. Thus, I would recommend simply making a template json file with the right format for your skills. I've attached a template file to this message.

Skill Formatting

Skills are located in limbus_data/skill/ and custom_limbus_data/skill/. A skill json file is essentially another large list with multiple entries, with each skill having further entries.

As you can see in the code below, we have here a list with 1 skill in it. This serves as an example Skill 1 for you to learn the basics.

{
    "list": [
        {
            "id": 1125001,
            "skillTier": 1,
            "skillData": [
                {
                    "skillTargetType": "FRONT",
                    "canTeamKill": false,
                    "canDuel": true,
                    "canChangeTarget": true,
                    "attributeType": "SHAMROCK",
                    "atkType": "SLASH",
                    "defType": "ATTACK",
                    "skillMotion": "S1",
                    "viewType": "BATTLE",
                    "targetNum": 1,
                    "range": 6.5,
                    "defaultValue": 8,
                    "skillLevelCorrection": 1,
                    "abilityScriptList": [
                        {
                            "scriptName": "GiveBuffOnUse",
                            "buffData": {
                                "buffKeyword": "Breath",
                                "target": "Self",
                                "stack": 1,
                                "turn": 0,
                                "activeRound": 1
                            }
                        }
                    ],
                    "coinList": [
                        {
                            "operatorType": "ADD",
                            "scale": 3,
                            "abilityScriptList": [
                                {
                                    "scriptName": "GiveBuffOnSucceedAttack",
                                    "buffData": {
                                        "buffKeyword": "Breath",
                                        "target": "Self",
                                        "stack": 0,
                                        "turn": 2,
                                        "activeRound": 1
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

So What Am I Looking At???

There is, simply put, a lot of information here, so I'll explain in order.

  • "id" this is the skills ID number. Self-explanatory. Unlike personalities these don't follow any strict rules and can be whatever you want them to be.

  • Using the ID number of a vanilla skill will overwrite it. This is a VERY BAD IDEA. Overwriting a vanilla skill will delete every other non-custom skill in the game. Because of this, it's recommended to simply make a modified custom skill and overwrite the personality/abnormalities instead.

  • "skillType" is is used to determine the type of skill this is (aka, is this an EGO Awakening, EGO Corrosion or a regular skill).

  • "skillTier" determines if something is a Skill 1, Skill 2 or a Skill 3. All EGO skills are Skill 3's for example, and defensive skills are always Skill 1's. Most enemy skills are Tier 1, but this is not always the case.

  • "attributeType" is the skill's sin affinity. Most defensive skills will be "Neutral" at Uptie 1 and change this at Uptie 4 (This won't matter in the current skill example, as no uptie level is present.)

  • If you wish to figure out which Sin Affinities are which, go into the attributeList locale file. (or check the below code block)

{
  "dataList": [
    {"id": "CRIMSON", "name": "Wrath"},
    {"id": "SCARLET", "name": "Lust"},
    {"id": "AMBER", "name": "Sloth"},
    {"id": "SHAMROCK", "name": "Glut."},
    {"id": "AZURE", "name": "Gloom"},
    {"id": "INDIGO", "name": "Pride"},
    {"id": "VIOLET", "name": "Envy"},
    {"id": "WHITE", "name": "Mad."},
    {"id": "BLACK", "name": "Angst"}
  ]
}
  • atkType is pretty self-explanatory, this can be either SLASH, PENETRATE or HIT (aka Slash, Pierce or Blunt). If you make a Guard or Evade Skills, leave this at NONE.

  • defType determines whether something is a regular attack (ATTACK), a guard (GUARD), evade (EVADE) or a counter ( COUNTER).

  • Note: Counters still require an atkType to function.

  • Note: Adding an atkType to a Guard or Evade doesn't actually do anything.

  • skillTargetType this determines what type of targeting we use.

  • FRONT is the targeting type that all personality skills use, meaning the skills actually target what we select.

  • NPC skills will typically use RANDOM targeting, which... does what you think it does. This always feels like a bug when we use it because our skills are targeting like an indiscriminate corrosion, so we generally want to change this into FRONT for usable skills

  • targetNum determines how much Atk Weight a skill has, and defaults to 1.

  • mpUsage determines how much SP a skill costs to use.

  • Note: In the games code, the term SP (aka Sanity) is never used. It is always called MP instead.

  • skillLevelCorrection is how much Offense Level (or defensive level) up a skill gains.

  • defaultValue is just a skills base value.

  • Note: While it is theoretically possible to put this into a negative value, in practice this leads to some incredibly weird calculations as Limbus skills will never really go below 0 power. (Here is a showcase of how that turns out)

  • canTeamKill is just a boolean true or false value that's pretty self-explanatory, it determines if something targets indiscriminately or not (aka, if it can target allies or not). This is kept at false for 99% of skills, for pretty self-explanatory skills.

  • Note: This feels really funny to use in combination with FRONT targeting, I recommend trying it out.

  • canDuel is yet another boolean true or false value, that determines if a skill can clash or not. Turning this to false makes a skill unclashable

  • Note: The game always refers to clashes as a "duel" in the games code

  • Note: If you want to make a clashable Guard or Counter, all you need to do is just turn that "false" value into true and it works perfectly.

  • Turning this value to true on an evade does nothing.

  • canChangeTarget is another boolean true or false value that determines if a skill can be redirected or not. Usually this is used on enemies, as it can feel weird when used on a playable character.

  • skillMotion is the animation that this skill uses. Regular skills will use something like S1, S2, S3, S5 etc, while Counter Skills, Guards and Evades will generally just use "Default"

  • viewType is a bit more niche. If you use the viewType BATTLE it will display like a regular skill, while the viewType ENCOUNTER will make it display like a Skill 3. Generally this is something you never touch.

  • range is a weird value that determines at what range your character gets before they start a clash. Kind of a niche thing you don't really touch.

  • parryingCloseType is similar to range. you generally don't really touch it.

Ability Scripts And How They Work

Ability Scripts are all the scripts associated with a skill that aren't on its coins. Stuff like Coin Power conditionals or [Clash Win] effects are a good example of this.

General Guide to Script Modding

Most scripts have self-descriptive names, such as GiveBuffOnUse for example, which we'll be looking at first.

GiveBuffOnUse has the script name and further details on what it effects.

   {
"scriptName": "GiveBuffOnUse",
"buffData": {
    "buffKeyword": "Breath",
    "buffOwner": ""
    "target": "Self",
    "stack": 1,
    "turn": 0,
    "activeRound": 1
 }
}
  • First is the buffKeyWord, which determines which buff it effects. Right now it's set to Breath, but it can be changed to any other status effect in the game

  • Note: If you want to find all the status effects in the game, either go to https://limbus.kusoge.xyz/keyword or to limbus_locale/bufList (yes that is spelled with one F). Remember to press save, to automatically format the document.

  • Next is "target", which determines who is affected. There are a lot of specific examples of this, but the most common ones are Self, Target, EveryAlly, RandomEnemy1, RandomEnemy2, RandomEnemy3, RandomEnemy5 and EveryEnemy. There are some more obscure ones like IfAbnormalityAllPartsOrSelf, or Custom (take a guess where that ones used), but those are generally all you need.

  • buffOwner is not used here, but will be elaborated on for other skills

  • stack just means the Potency of a status effect. Most status effects only have Potency and no count.

  • turn just means the Count of a status effect.

  • activeRound means what turn this status effect is applied. A value of 0 means that is applied this turn, while a value of 1 means it's applied next turn.

Script's are Configurable. Kind Of

If you ever see a Script Name with any numbers inside of it, know that those numbers can be changed. The same can be said for any Sin Affinities inside a script.

This tends to be the case for Status Effects in Script names, but not always. While modifying the buffData of a script always tends to work, changing a script name is pretty variable and really does depend on how hard coded the original script was.

But How Do I Find Scripts???

  • Method 1: Go into skillList in Limbus Locale (once again remember to format by saving) and search for a specific skill description you want. Then go into limbus_data/skill and search for that skill's ID number until you find said skill, then grab the script you want. You can also look through our list of scripts and search for skills that use a script to understand how to implement it.

  • Method 2: This is a bit more cumbersome but can be useful for dealing with crappy, inconsistent localization (thanks Project Moon). Go to BepInEx/unhollowed and open up the Assembly-CSharp.dll file in there using a program like DnSpy or Jetbrains Dotpeak, then search for a specific skill name you need.

Modifying Coins

Now that you understand how to modify AbilityScript's, modifying coins should be pretty simple.

A Skills current coins are a list, with every single entry in said list being its own Coin.

When opening up a Coin we find 3 different values inside of it

  • operatorType determines whether something a coin is positive (ADD), negative (SUB) or Multiply (MUL)

  • scale determines a coins coin power. This has its own weirdness to it if you try and mess with negative multiplication, but don't worry too much about that.

  • abilityScriptList sounds familiar, doesn't it? Yep, this works the exact same as a skills ability script but is located on a coin instead. (This is used for things like on hit effects.)

Adding More Coins

Adding more coins isn't that hard, simply copy and paste a coin already in your list. Important to note though is that, while it's entirely possible to have a skill that rolls more than 10 coins, a skill cannot have more than 10 coins displayed on the skill by base.

Extras

This section includes now outdated information. The items in this section may still prove useful, however, there are modern day solutions that usually replace these items (I.e plugins such as Modular or Bonkgeneral), rendering them mostly pointless.

  • "textID" this is used for localization purposes so that our locale file knows where to point to with our written localization.

  • "iconID" you won't actually see this one very often in vanilla skills. Icons are automatically assigned to a specific skill's ID, which usually works out in vanilla. However, since we are making custom skills with their own ID number, we need to implement "iconID" so we can have skill icons.

  • A skills IconID is always the same as their Skill ID.

  • "gaksungLevel" is what Uptie Level this bracket of information is. If you're working with custom skills you only really need to modify the base information and the Uptie 4 information. (If no gaksung is present, it defaults to 1)

Reminder

Every single skill in this game is located inside limbus_data/skills. If you want to customize a skill of an abnormality, simply search in there, copy and paste the skill, put it in custom_limbus_data/skills and modify it there.

If there is no locale present, the skill will have a placeholder description until you add it. (More on that in the custom locale tab!)