Pathfinder: Kingmaker

Pathfinder: Kingmaker

Not enough ratings
Adding Feats For Dummies
By The Worthless Gamer
A guide on how to add passive feats to your character(s) via save game editing.

Remember to always backup your saves before messing with them!
   
Award
Favorite
Favorited
Unfavorite
Tools of the Trade: Notepad++ and JsTool plugin
Before we begin, you will need the following to edit your save files:
Notepad++: https://notepad-plus-plus.org/download/v7.5.8.html
JsTool plugin (to format the file for easy reading): https://sourceforge.net/projects/jsminnpp/

After installing Notepad++, download JsTool plugin and put the file JSMinNPP.dll into the plugins folder in your Notepad++ directory.


Now when you open up Notepad++, JSTool should show up under plugins!

Oh Save Files, Where art thou?
Now that we have the tools to edit the save files, let's locate the directory where the game stores your save games!

For windows (STEAM version):
%systemdrive%\users\%username%\AppData\LocalLow\Owlcat Games\Pathfinder Kingmaker\Saved Games

Just copy paste the entire string above to your explorer and it will open the folder directly! Now let's take a look at the contents of the folder. Assuming you have already made some saves in the game, you will see files with .zks extension. These are your save files :)


Now let us extract party.json from the save file for editing!
.zks files are actually archive files (similar to a .zip or .rar file) so you can just open them with winzip / winrar / 7-zip etc!


You will see several files inside the .zks file you just opened - let's look for party.json
and extract it to any drive/folder of your choosing.


Now, let's open the extracted party.json file in Notepad++ for editing!




Prepping for Surgery - Identifying where to insert your feat(s)!
Whoa there Dr Frankenstein! Before you start attaching extra feats to your characters there are a few things you need to do!

Formatting the file for easy reading:
In Notepad++ click plugins => JSTool => JSFormat.
You can now see the contents of the file arranged nicely!


Next we need to determine several things before we can start inserting the feats to your character(s).
  • The m_UniqueId of the character you are giving the feat to.
  • The m_OwnerDescriptor of the character you are giving the feat to.
  • Where to insert the feat's code.

There are quite a few ways to identify them but for the purpose of this guide, let's use the JSON viewer that comes with JSTool plugin to do it!

Go to plugins => JSTool => JSONViewer to open it up :)


You should see a new section pop up on the left side of Notepad++.
We will use this to find (m_UniqueId, m_OwnerDescriptor) which we will need to insert new feats. The method to do so is slightly different for your main character (plus custom mercenaries) vs your story companions.

Let's look at how to do it for your main character first!
Search for your character's name in the search bar - in this example our character is named "Aribeth de Tylmarande" so let's go ahead and type "aribeth" into the search bar and look at the results!


From here you can see we have discovered the m_UniqueId and m_OwnerDescriptor for Aribeth (the main character). Now, we want to find out where is the correct spot to insert our new feat(s) for Aribeth!

First, click on the "+" box next to "Progression: [object]".
Then followed by the "+" box next to "Features: [object]".
Next we click on the "+" box next to "m_facts: [Array]".


You will see quite abit of entries as such
+ [0]: [Object]
+ [1]: [Object]
+ [2]: [Object]
and so on... these are all your character's existing feats and traits (including racial bonuses). Lets select and open up the last entry in the list (by clicking the "+" box), which is [77]: [Object].

Click on SourceCutscene: null at the end of list and Notepad++ will jump to (and highlight) it in party.json (shown in the right side panel).
We will insert the code for new feats after the "}" bracket one line below.
This will be covered in the next section of this guide.


Now - let's teach you how to find m_UniqueId and m_OwnerDescriptor for story companions. Unlike your main character or custom mercenaries, you can't search for them by name as the game does not save their names inside party.json!

This can make identifying them a pain, but luckily Spacehamster has us covered with the list of prefab IDs for our story companions here: https://github.com/spacehamster/KingmakerCharacterEditor/blob/feats/src/app/blueprints.ts

For ease of reference, here is the list of codes for each story companion:
Linzi: "77c11edb92ce0fd408ad96b40fd27121"
Tartuccio: "5455cd3cd375d7a459ca47ea9ff2de78"
Valerie: "54be53f0b35bf3c4592a97ae335fe765"
Amiri: "b3f29faef0a82b941af04f08ceb47fa2"
Harrim: "aab03d0ab5262da498b32daa6a99b507"
Jaethal: "32d2801eddf236b499d42e4a7d34de23"
Regongar: "b090918d7e9010a45b96465de7a104c3"
Octavia: "f9161aa0b3f519c47acbce01f53ee217"
Tristian: "f6c23e93512e1b54dba11560446a9e02"
Ekundayo: "d5bc1d94cd3e5be4bbc03f3366f67afc"
Dog: "ef4e6551044872b4cb99dff10f707971"
Jubilost: "3f5777b51d301524c9b912812955ee1e"
Nok-Nok: "f9417988783876044b76f918f8636455"

As an example, let's try to find Jaethal's m_UniqueId and m_OwnerDescriptor.
Since we can't search for Jaethal using her name, we will use her prefab ID instead which is "32d2801eddf236b499d42e4a7d34de23".

Notice that it looks slightly different from our previous example? This is because the game places your companions as objects under your main character (weird!) so we will get the necessary information via Jaethal's feat entries instead!

Same as what we did for the main character, we will
First, click on the "+" box next to "Progression: [object]".
Then followed by the "+" box next to "Features: [object]".
Next we click on the "+" box next to "m_facts: [Array]".


Now once again you will see quite abit of entries such as:
+ [0]: [Object]
+ [1]: [Object]
+ [2]: [Object]

Go to the last entry which is [61]: [Object] in this example and expand it by clicking the "+" next to it.


Phew! With that we managed to get Jaethal's m_UniqueId and m_OwnerDescriptor as well as the location to insert any additional feats for her. Let's move on to the next section where we will finally learn how to add those juicy feats to our character(s)!


Getting our hands dirty - Let's start adding Feats!
By now you should already know the following:
  • The m_UniqueId of the character you are giving the feat to.
  • The m_OwnerDescriptor of the character you are giving the feat to.
  • Where to insert the feat's code.
Next, you will need the code for the feats!
A list which contains most of the feats is maintained by tseblade and neuronek over at the cheat engine forums: http://fearlessrevolution.com/viewtopic.php?f=15&t=7995&start=15#p63801

For our example we will use the feat "Damage Reduction" from the Barbarian archetype "Invulnerable Rager". What this feat does is that it gives the character damage reduction of DR 1/-, meaning any incoming non magical damage to the character gets reduced by 1.

Here is the code for the feat i extracted from a character i made:
{ "$id": "282", "$type": "Kingmaker.UnitLogic.Feature, Assembly-CSharp", "m_Context": { "$id": "283", "m_OwnerDescriptor": { "$ref": "5" }, "m_CasterReference": { "m_UniqueId": "4bda08a5-bd8d-4563-9e00-8f64874cd890" }, "m_Ranks": [1, 0, 0, 0, 0, 0, 0], "m_SharedValues": [0, 0, 0, 0, 0, 0], "m_Params": null, "AssociatedBlueprint": "e71bd204a2579b1438ebdfbf75aeefae", "ParentContext": null, "m_MainTarget": null, "Params": {}, "SpellDescriptor": "None", "SpellSchool": "None", "SpellLevel": 0, "Direction": { "$type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "x": 0.0, "y": 0.0, "z": 0.0 } }, "Blueprint": "e71bd204a2579b1438ebdfbf75aeefae", "m_ComponentsData": [{ "$id": "284", "ComponentName": "$AddDamageResistance$1b270785-807c-4de2-813a-25d627d935e8" } ], "Rank": 1, "Source": null, "Param": null, "IgnorePrerequisites": true, "Owner": { "$ref": "5" }, "Initialized": true, "Active": true, "SourceItem": null, "SourceCutscene": null }

We shall give this feat to our test character Galadriel, who is a level 1 wizard with the following information:
m_UniqueId: "007337a9-9bcc-493b-be93-c0743eddf181"
m_OwnerDescriptor: "5"

Before we transplant the code, we have to change some values in the feat's code!
Firstly, let's change all instances of m_UniqueId and m_OwnerDescriptor found in the feat's code to match our test character's. Luckily, our test character's m_OwnerDescriptor is also "5" so we only need to change the m_UniqueId found in the feat's code to "007337a9-9bcc-493b-be93-c0743eddf181".

Let's look at the top portion of the now edited feat code:
{ "$id": "282", "$type": "Kingmaker.UnitLogic.Feature, Assembly-CSharp", "m_Context": { "$id": "283", "m_OwnerDescriptor": { "$ref": "5" }, "m_CasterReference": { "m_UniqueId": "007337a9-9bcc-493b-be93-c0743eddf181" }, .....

We have changed the "m_UniqueId" to Galadriel's. We did not change "m_OwnerDescriptor" as it is the same as Galadriel's (which is "5"). Now if we were adding this feat to our other companions instead, we would need to change it too.

Next we need to check (and change) the "$id" found throughout the feat's code.
It must meet two criteria:
  • It must not be a duplicate of any $id found in your current party.json
  • It must be in sequential order.

You will notice the first "$id" is "$id": "282". If Galadriel's party.json already contain "$id": "282" and we paste this code in - the save game will fail to load! We shall change the "$id" to another number - let's will assign it a really high value ("$id": "2000") and check if it is safe to use in Galadriel's party.json.


Yay! Looks like it is safe to use "$id": "2000" for this feat.
Let's start renaming all the $id found in the feat's code in sequential order, starting with "2000"!

Here is how the code looks like after we edited the $id.
{ "$id": "2000", "$type": "Kingmaker.UnitLogic.Feature, Assembly-CSharp", "m_Context": { "$id": "2001", "m_OwnerDescriptor": { "$ref": "5" }, "m_CasterReference": { "m_UniqueId": "007337a9-9bcc-493b-be93-c0743eddf181" }, "m_Ranks": [1, 0, 0, 0, 0, 0, 0], "m_SharedValues": [0, 0, 0, 0, 0, 0], "m_Params": null, "AssociatedBlueprint": "e71bd204a2579b1438ebdfbf75aeefae", "ParentContext": null, "m_MainTarget": null, "Params": {}, "SpellDescriptor": "None", "SpellSchool": "None", "SpellLevel": 0, "Direction": { "$type": "UnityEngine.Vector3, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "x": 0.0, "y": 0.0, "z": 0.0 } }, "Blueprint": "e71bd204a2579b1438ebdfbf75aeefae", "m_ComponentsData": [{ "$id": "2002", "ComponentName": "$AddDamageResistance$1b270785-807c-4de2-813a-25d627d935e8" } ], "Rank": 1, "Source": null, "Param": null, "IgnorePrerequisites": true, "Owner": { "$ref": "5" }, "Initialized": true, "Active": true, "SourceItem": null, "SourceCutscene": null }

Now let's paste the code into Galadriel's party.json at the end of her current feat list. (see previous section if you forgot how to find it!)


Save the party.json and package the file back to your .zks save file! (For 7-Zip you can just drag and drop party.json onto the opened .zks file and choose yes to overwrite).

Let's load the save game in Pathfinder Kingmaker now and check if we done everything correct!


Yep! Everything is working fine! If we wish to take this even further, we can change "m_ranks" and "Rank" to a higher number, which will increase the amount of damage reduction Galadriel receives!
Of course this does not work for all feats, only those with scaling ranks such as Sneak Attack.

Do note that for certain feats like Power Attack, Rapid Shot etc which contains an activatable action, you will need to add some extra code to your character's Abilities section. These will not be covered in this guide as i have not done extensive testing on those feats and the code you need to add varies from feat to feat.

And that's all folks! Thank you all for taking the time to read this long-winded guide. This is the first time i written any guides and i apologize if it was badly done! ^____^;
Bonus: Spell Swapping Guide for Dummies
Have you ever wished you could cast Dragonkind III as a draconic bloodine magus / dragon disciple?
Or maybe you just want to be able to toss instant-cast fireballs as first level spells or even cantrips?

Well look no further! It is actually relatively simple so let's dive into it!
For this we will be editing party.json. I am assuming you have already read the earlier portion of this guide and thus know how to extract and open your save file's party.json for editing.

Using the previously explained method on using JSON viewer to find a character's m_UniqueId and m_OwnerDescriptor, find m_OwnerDescriptor of the character that you are going to be swapping spells for.

HINT: If you are swapping spells for your main character, then the m_OwnerDescriptor should be always "5", hence saving you an extra step.

Now let's return to our test character, Galadriel and mess around with her spells. Galadriel's m_OwnerDescriptor is "5" so we will search for "m_Spellbooks" in party.json and you should be getting results like this:


Notice the lines:
"Owner": { "$ref": "5" },
This matches with Galadriel's m_OwnerDescriptor (which is also "5") hence we can be sure we are now looking at Galadriel's spellbook. Before we start swapping spells, lets understand how the game stores spells in the spellbook.

The first part "m_KnownSpells" contains the entire list of spells your character currently knows.
Each tier (or level) of spells is contained within a set of brackets [ ], arranged in ascending order.
Within each set of brackets are you spells.

For e.g. if your character only knows 3 cantrips and learnt two level 1 spells "Magic Missile" and "Shield", the game will store it as:

m_KnownSpells: [[{cantripA},{cantripB},{cantripC}],[{Magic Missile},{Shield}],[],[],[],[],[],[],[],[]]

The empty brackets at the end are actually for level 2,3,4,5,6,7,8,9 spells but since your character does not know any spells of those levels they will be blank.

With this in mind, let's look at a sample arcane spell "Color Spray"
{ "$id": "58", "Blueprint": "91da41b9793a4624797921f221db653c", "Caster": { "$ref": "5" }, "Fact": null, "m_ConvertedFrom": null, "DecorationColorNumber": -1, "DecorationBorderNumber": -1, "m_SpellbookBlueprint": "5a38c9ac8607890409fcb8f6342da6f4", "IsSpellCopy": false, "MetamagicData": null }

Now let's swap the Color Spray spell in Galadriel's spellbook into Wail of the Banshee by replacing the "Blueprint" of the spell from "91da41b9793a4624797921f221db653c" to "b24583190f36a8442b212e45226c54fc". Simple!

Next, we want to give Galadriel a quicken empowered Tsunami spell. In order to bypass the annoying $id renumbering, we will use first use Galadriel to create a quicken empowered Burning Hands which will show up under m_CustomSpells like this:
{ "$id": "64", "Blueprint": "4783c3709a74a794dbe7c8e7e0b1b038", "Caster": { "$ref": "5" }, "Fact": null, "m_ConvertedFrom": null, "DecorationColorNumber": -1, "DecorationBorderNumber": -1, "m_SpellbookBlueprint": "5a38c9ac8607890409fcb8f6342da6f4", "IsSpellCopy": false, "MetamagicData": { "$id": "65", "MetamagicMask": "Empower, Quicken", "SpellLevelCost": 6, "HeightenLevel": 0 } }

Now we swap the spell's blueprint "4783c3709a74a794dbe7c8e7e0b1b038" with Tsunami's blueprint which is "d8144161e352ca846a73cf90e85bf9ac". On top of that, in order to let this spell be casted using a level 1 spell slot, we will change "SpellLevelCost": 6, to "SpellLevelCost": 0, and move the spell's code into the correct set of brackets [ ].

Last but not least, let's try to swap one of Galadriel's cantrips "Flare" into Cloudkill.
This is the code for the cantrip "Flare":
{ "$id": "56", "Blueprint": "f0f8e5b9808f44e4eadd22b138131d52", "Caster": { "$ref": "5" }, "Fact": null, "m_ConvertedFrom": null, "DecorationColorNumber": -1, "DecorationBorderNumber": -1, "m_SpellbookBlueprint": "5a38c9ac8607890409fcb8f6342da6f4", "IsSpellCopy": false, "MetamagicData": null }
We will simply swap the blueprint again, changing "f0f8e5b9808f44e4eadd22b138131d52" to "548d339ba87ee56459c98e80167bdf10".

One extra step as cantrips will not update in your spellbook hotbar if you swapped them, is to add the cantrip to your ability hotbar. Do a search in Notepad++ using the cantrip blueprint "f0f8e5b9808f44e4eadd22b138131d52" and click "Find all in current document". You should have three hits, one under "m_knownspells" and two under "Abiliites".

Proceed to replace all instances of "f0f8e5b9808f44e4eadd22b138131d52" with "548d339ba87ee56459c98e80167bdf10" and you will be good to go!

Now let's save and update the party.json inside the save file and load it up to test!
Mmmm infinite cloudkills as a cantrip yikes!


An empowered, quickened Tsunami? Level 9 spells? Oh my!


Seems like it works :3 Let's have a live fire test to wrap things up ♪
Oops! RIP Tartuccio, Valerie and Amiri. You will not be missed :D


Dear Assassin, when i say “Get out of my room”, I mean it!


All right! That's all from me for now - peace out and hope this guide will help you all have more fun with the game! :)
9 Comments
Coffeepyromaniac Feb 8, 2022 @ 2:24am 
Update from 2022: in the current Notepad version, you have to create a subfolder in plugins called "JSMinNPP" and put the JSMinNPP.dll in for it to actually show under plugins
Dusk Nov 15, 2018 @ 7:55am 
Thank you for the guide, amazingly helpful even for someone who has not done this sort of thing for a very long time. Some feats are giving me issues, outlfank, power attack and the other actionable feats but in general it is working great.
Happihour Nov 9, 2018 @ 1:35pm 
Is there a resource for a json list of spells and feats to add?
The Worthless Gamer  [author] Oct 30, 2018 @ 5:33pm 
Simply search for experience in party.json.
For values of exp needed to reach certain levels, check the exp value under medium in the table on https://www.d20pfsrd.com/classes/character-advancement/

P.S. 3.6mil is the exp you need for level 20.
LordSerion Oct 30, 2018 @ 9:19am 
Can someone please tell me where can I edit the XP value?
Soldier4Christ83 Oct 26, 2018 @ 6:40pm 
I want to add a diety to my character without taking a level in Paladin or Cleric. I looked in the feat list and I could not find deity selection. I pulled up a cleric's player and party jpsons and neither made reference to it. I want to add Gorum. Thank you for any help you can provide.
dkerensky Oct 22, 2018 @ 10:12am 
Clear and concise guide, definitely not as hard to read what you do when you use that plugin.
The Worthless Gamer  [author] Oct 18, 2018 @ 9:19pm 
The portrait artwork is by Yujin Kim.
Here is the Artstation link: https://www.artstation.com/artwork/oNxLO
Si Cwan Oct 18, 2018 @ 6:10pm 
Nice Guide!! Where did you get that wiz portrait?