Crusader Kings II

Crusader Kings II

41 ratings
Sinful CK2 Modding Guide
By SinStar87 (He/Him)
Guide of almost none of my knowledge but rather answering questions and giving examples of CK2 modding. So if you have a question about modding, post it and I'll do my best to answer it in a detailed manner within the guide.
   
Award
Favorite
Favorited
Unfavorite
Intro
Hello I've been asked to write a guide, so here it is. Struture will probably be odd because rather than a comprehensive explanation of everything I know(since that's pretty well laid out in the CKIIWiki), it'll be more bits and pieces as I answer questions. As such, it'll be updated in bursts as they come in.
Basic Modding Knowledge
So you want to mod CK2? Well, let us assume you have an idea for a mod.

First you need to know what all is involved. The best thing to do is read the stuff here[www.ckiiwiki.com] and decide if it's worth it. :)

Then next you need to familarize yourself with the mechanisms involved with creating a mod, best way I've found to do this is look over smaller mods(I did not start this way :P) and see how they function. I have a few you can look over.

For In-depthness' sake, I'll be using my Goshen Sagas mod for examples in the guide, since basically everything I know how to do has gone into it.
Event Chains
Alright, this section, aptly named if I do say so myself, will explain event chains. For an example we'll be using maintenance from Goshen Sagas, specifically events goshen_maintenance_events.1 and goshen_maintenance_events.10.

So firstly, we will explain the relevant code. Events use specific code for what it is fired on, characters get character_event, provinces get province_event, etc but in addition to defining the what the event does these are also used to fire said events when used inside an code's effect section(immediate, option, effect).

Code:
*_event - sets the nature of the event you are firing, if the event is a province_event then you use province_event, etc, the event fires on the currently scoped item

id - the code for the event to be fired

days - how long after this event the new event will fire

random - how many days added or subtracted from the days that the game can take away to add a bit of randomness to the event popping up.

So let's look at the example, you'll see this code.


character_event = {
id = goshen_maintenance_events.1
k_gawei = {
holder_scope = {
character_event = { id = goshen_maintenance_events.10 days = 1 }
}
}
}
This code shows the title of k_gawei, and scopes to it's holder via holder_scope, then it sets to fire event goshen_maintenance_events.10 1 day after. So this code fires goshen_maintenance_events.10 on whoever is currently holding the Gawei Kingdom and it appears for them the next day.

Alright, hopefully you understand event chains a bit better now, give it a try yourself.

Excerpted code:
character_event = {
id = goshen_maintenance_events.1
is_triggered_only = yes
hide_window = yes

trigger = {
OR = {
trait = gawei_sword_1
trait = gawei_sword_2
trait = gawei_sword_3
trait = gawei_sword_4
trait = gawei_sword_5
trait = gawei_sword_6
trait = gawei_sword_7
trait = gawei_sword_8
trait = gawei_sword_9
}
}

immediate = {
primary_title = {
heir_under_primogeniture_law = {
IF = {
limit = {
dynasty = ROOT
ROOT = { trait = gawei_sword_1 }
}
add_trait = gawei_sword_1
}
...
}
}
k_gawei = {
holder_scope = {
character_event = { id = goshen_maintenance_events.10 days = 1 }
}
}
}
}
character_event = {
id = goshen_maintenance_events.10
desc = EVTDESCgoshen_maintenance_events.10
picture = GFX_evt_castle_construction
is_triggered_only = yes

immediate = {
IF = {
limit = {
NOT = {
gawei_sword_1 = {
is_alive = yes
}
}
}
add_trait = gawei_sword_1
}
...
}

option = {
name = EVTOPTAgoshen_maintenance_events.10
}
}
Basic Scoping
Alright, first question is the various basic scopes.

What's the proper use of ROOT/ FROM/ PREV?
Ok, first let me explain these scopes;
  • ROOT, by and large, is the object that the event is affecting.
  • FROM, again for the most part, is the object that sent the previous event.
  • PREV, looks at the previous scope in a scope chain, though there are some scopes that aren't counted in a chain, like ROOT and FROM.

For examples, we'll look at goshen_personality_events.txt, specifically events goshen_personality_events.1 and goshen_personality_events.11;
Now, hopefully event chains are clear from your reading of the wiki linked to in the modding basics section. In goshen_personaility_events.1 ROOT is the character that goshen_personality_events.1 was fired on. In goshen_personality_events.1, you see it has a code that fires event goshen_personality_events.11 on the employer of ROOT.

Ok, now hopefully that's clear, we'll move to goshen_personality_events.11 here we see our first FROM scope, specifically setting character flags on it. In this event, ROOT is the character that goshen_personality_events.1 fired on(the employer of the ROOT from goshen_personality_events.1) FROM, in this instance, is the ROOT of goshen_personality_events.1.

So hopefully ROOT and FROM, in most instances, are clear to you. Now to PREV, rather than pulling another example, I'll continue with the personality events;
So, let's look back at goshen_personality_events.1 and that employer scope in it. If we were to use a PREV scope inside it, like so;
immediate = {
employer = {
PREV = {
character_event = { id = goshen_personality_events.11 }
}
}
}
PREV in this instance would now fire goshen_personality_events.11 on ROOT rather than ROOT's employer.

Alright, I think that's all the basics of these 3 scopes, though there are some instances, such as on_action events, where these scopes will look to difference characters. So try them out in game and see how they work for you.



For those that don't want to download my Goshen Sagas mod... :(
Originally posted by "Cody Collins":
character_event = {
id = goshen_personality_events.1
is_triggered_only = yes
hide_window = yes

trigger = {
NOR = {
has_character_flag = child_martial_training
has_character_flag = child_intrigue_training
has_character_flag = child_steward_training
has_character_flag = child_random_training
}
}

immediate = {
employer = {
character_event = { id = goshen_personality_events.11 }
}
}
}
Originally posted by "Cody Collins":
character_event = {
id = goshen_personality_events.11
desc = EVTDESCgoshen_personality_events.11
picture = GFX_evt_castle_construction
is_triggered_only = yes

option = {
name = EVTOPTAgoshen_personality_events.11
trigger = {
wealth = 50
}
wealth = -50
FROM = { set_character_flag = child_martial_training }
}
option = {
name = EVTOPTBgoshen_personality_events.11
trigger = {
wealth = 50
}
wealth = -50
FROM = { set_character_flag = child_intrigue_training }
}
option = {
name = EVTOPTCgoshen_personality_events.11
trigger = {
wealth = 50
}
wealth = -50
FROM = { set_character_flag = child_steward_training }
}
option = {
name = EVTOPTDgoshen_personality_events.11
FROM = { set_character_flag = child_random_training }
}
}
Spawn Unit
Surprisingly I have no spawn units commands in Goshen, so we'll make use of the code posted below by Tasty Wheaties(fixed up a bit) in an event called example_events.0

First, an explanation of spawn_unit.
This command creates event troops for characters, common event troops in vanilla are the raiders for the various Pagan religions. They can be called from just about any effect section(such as in decisions or immediate/option sections in events)

Ok, so lets look at the code, the first things we see are the 2 establishing condtions; owner and province.
Owner
is a scope to who will control the created unit, in this case, the newly created character.
Province
is a scope/id for where the unit will spawn, in this case, the holder of Rome's capital.
spawn_unit = {
owner = THIS
province = PREV
}

Next we have the troop code, which in this example uses the match code but can also use the troops code, which I'll example shortly. the match_* codes look to the levies of the scoped character for what troops are to be spawned in the unit and augments its size.

Ok, to the accompanying event which has fired on the holder of c_roma(Rome in the game), as we learned in the Basic Scoping section is ROOT. Therefore this unit is matching its troops against the holder of Rome's levies and doing so at a 1.1/1 amount. So for each troop and type in Rome's Holder's personal levies this unit is spawning 1.1.
spawn_unit = {
match_character = ROOT
match_mult = 1.1
}

Now to the troops section for more established spawns, below is a spawn unit code that creates pikemen but can be any troop type that is established in game.
You see the 2 numbers inside the pikemen section, these are the strengths, the first is the max strength and the second is the strength when created. Which it will slowly grow toward the max if reinforcing is turned on for the unit.(more on this shortly) So this code would spawn 500 pikemen in Rome for the new character.
spawn_unit = {
troops = {
pikemen = { 500 500 }
}
}

And finally the special conditions. Here we have; attrition, is_looter, can_toggle_looting, cannot_inherit, and earmark. Some other interesting ones are reinforces, reinforce_rate_multiplier, disband_on_peace, and maintenance_multiplier.
spawn_unit = {
attrition = 0
is_looter = yes
can_toggle_looting = no
cannot_inherit = yes
earmark = mystery_raiders
}

So let's explain these;
attrition, this is what percent of the normal attrition rates from things like being in enemy territory or over the supply limit this unit will suffer. In this example, the unit won't suffer any.

is_looter, this determines if the unit will loot provinces or not.

can_toggle_looting, this determines if the owner can turn the looting on and off.

cannot_inherit, this determines if the unit passes on to a new holder of the title or not.

reinforces, this determines if the unit rebuilds towards max strength or not, vanilla event troops don't.

reinforce_rate_multiplier, this is the percentage of the normal unit rate that the spawned troops will reinforce.

disband_on_peace, this code will determine if the troops continue to exist after all wars the holder is in end. If it's used when outside a war, the troops will quickly disband.

maintenance_multiplier, this is the percentage of normal unit maintenance that the owner will pay for have these troops.

Full code
character_event = {
id = example_events.0
is_triggered_only = yes
hide_window = yes

trigger = {
has_landed_title = c_roma
}

immediate = {
capital_scope = {
create_random_soldier = {
random_traits = yes
religion = ROOT
culture = ROOT
dynasty = random
}
new_character = {
wealth = 50
create_title = {
tier = DUKE
name = "MYSTERY_RAIDERS"
holder = THIS
culture = ROOT
adventurer = yes
landless = yes
}
set_defacto_liege = THIS
spawn_unit = {
owner = THIS
home = PREV
province = PREV
match_character = ROOT
match_mult = 1.1
attrition = 0
is_looter = yes
can_toggle_looting = no
cannot_inherit = yes
earmark = mystery_raiders
}
}
}
}}
Creating Characters(commands)
Alrighty, there are 2 main ways to add characters into CK2; writing history and the create_* commands. This section will deal with the latter.
Ok, so first up, we'll be looking at my Goshen Sagas code, specifically events goshen_maintenance_events.0 and goshen_maintenance_events.30.

Next we'll talk about the relevant codes. There are 6 commands to create characters, they are;
create_random_diplomat, this will create a random character with a diplomacy-based education
create_random_soldier, this will create a random character with a martial-based education
create_random_steward, this will create a random character with a stewardship-based education
create_random_intriguer, this will create a random character with an intrigue-based education
create_random_priest, this will create a random character with a learning-based education
create_character, this will create a more specific character

Now let's look at an example in goshen_maintenance_events.0, here we are creating a random character with a learning education in a ruler's court.
any_independent_ruler = {
limit = {
NOT = { any_courtier = { trait = is_medicus } }
}
create_random_priest = {
random_traits = yes
trait = is_medicus
age = 40
health = 5
fertility = 0.5
culture = THIS
religion = THIS
}
...
}
In addition to these codes, there's some other important items, such as attributes(shown in the example at the end), name, dynasty, father, and mother(I'll explain these shortly). Now, for items that go inside the create_* section, you can fill them in in a few ways, as above, some are specific values(age, health, fertility, specific traits), some are bool(yes/no/true/false) and others are scopes(ROOT/FROM/PREV/THIS) or specific codes(old_saxon, french, catholic, orthodox).

Quick list of these items;
attributes, as shown in the below example, this will set how many stat points the character gets(stats are martial, diplomacy, intrigue, stewardship, learning.)
random_traits, if the character will get randomly assigned traits, use this if you aren't setting them yourself otherwise the character will only have an education trait.
trait, use this to give the character specific traits(CK2 will eventually randomly remove personality traits if you have more than 4)
age, set how old the character will be on spawning
health, how much health the character will have, 5 is the average for CK2.
fertility, how likely the character is to impregnant the opposite sex, 1 = 100%
culture, character's culture, as said, can be a specific culture or a scope
religion, character's religion, same as culture
name, what first name the character will have, if it isn't a single name you need to use "", e.g. instead of Sin Star you'd use "Sin Star"
dynasty, character's dynasty, this will be a numerical value of one of those listed in common/dynasties
father, a scope to the character that'll be the character's father
mother, a scope to the character that'll be the character's mother

Alright, hopefully this helps you.



id = goshen_maintenance_events.0
create_random_priest = {
random_traits = yes
trait = is_medicus
age = 40
health = 5
fertility = 0.5
culture = THIS
religion = THIS
}
id = goshen_maintenance_events.30
create_character = {
name = ""
culture = dying_lands
religion = dying_lands_rel
dynasty = NONE
attributes = {
martial = 0
diplomacy = 0
intrigue = 0
stewardship = 0
learning = 0
}
trait = dyinglands_trait
}
How to be Dependent, a Step by Step Guide
More detail in the comments by QuinoaFalafel
Every CK2 mod has a director file called .mod, it directs ck2 to the mod files and has a couple of other instructions. Important for this guide, dependencies = {} which tells the game what mods are required to activate the mod, it also acts as a mod orderer preventing overhaul mods from overwriting the files of a smaller mod.
I get asked how to add one often enough. So let's add a dependency. We'll use agot and my latest mod, Well-Rounded Mod as examples.

Dependencies are established by the name of the .mod of the required mod, in this example it is A Game of Thrones.mod. So the dependency will look like this.

dependencies={ "A Game of Thrones" }

Now that we have the dependency, travel to the dependent mod's .mod. Mods are likely located here.
*\Documents\Paradox Interactive\Crusader Kings II\mod
In this example, it will be Well-Rounded.mod.

Now you need to use a text editor to open this file, right click the file, then open with... notepad. You can use other editors, but I use notepad. Now a new text file wil open and look like;
name = "Well-Rounded" path = "mod/Well-Rounded" picture = "SinStar87.jpg"
If you are using the workshop version, which breaks these things, it'll probably look more like;
name="Well-Rounded" archive="mod/Well-Rounded" picture="SinStar87.jpg" }
In which case, make it look more like the previous. Anyway, you now want to add the dependency line somewhere into the file, I tend to add it after the path/archive. So it will look like this.
name = "Well-Rounded" path = "mod/Well-Rounded" dependencies = { "A Game of Thrones" } picture = "SinStar87.jpg"
All done, save the file. Congrats, you've made a mod dependent.
Copyright
Copyright 2017 Cody Collins

This may be not be reproduced under any circumstances except for personal,
private use. It may not be placed on any web site or otherwise distributed
publicly without advance written permission.
Use of this guide on any other web site
or as a part of any public display is strictly prohibited,
and a violation of copyright.
All trademarks and copyrights contained in this
document are owned by their respective trademark and copyright holders.
37 Comments
SinStar87 (He/Him)  [author] 5 Feb, 2023 @ 1:31am 
@theragfromthecrag Well I have a custom AGOT dynasty mod, not sure what' you're looking for but it's got the code required to put in a new historic character and dynasty. https://www.dropbox.com/s/utnwg9vsck6ayuv/Collins%20Dynasty%20AGOT.7z?dl=0
TheRagFromTheCrag 4 Feb, 2023 @ 10:25pm 
Honest imma just going to try and clone a character ID and hope gor the best, especially since no one seems to be willing to give me a script necessary for a custom character.

This was informative but not by much...having said that though ... thanks anyway
SinStar87 (He/Him)  [author] 20 Dec, 2022 @ 1:17am 
Sorry you had trouble, I've added a note to the dependencies section to look to your comments.
QuinoaFalafel 19 Dec, 2022 @ 3:23pm 
While the .mod file is named "ck2plus.mod.mod", the name inside the file is actually "CK2Plus". So the dependency should actually look like

dependencies={ "CK2Plus" }

As a final note, the structure is different depending on whether you are using the mod personally/sharing a manual download vs uploading it to the Steam Workshop. The manual version doesn't need quotation marks if the mod name doesn't have spaces, but quotations are necessary before uploading to Steam. Additionally, if the mod does have spaces in the name, you need to add escaped quotes before uploading. For example, for the AGOT example, you would format it as:

dependencies={ "\"A Game of Thrones\"" }
QuinoaFalafel 19 Dec, 2022 @ 3:23pm 
For example, let's take Ck2+. If you download it from the workshop, the .mod file is named "ck2plus.mod.mod". Following the instructions listed above, one would assume that the dependency should be listed as

dependencies={ "ck2plus.mod" }

or maybe

dependencies={ "ck2plus" }.


However, that's incorrect, and wouldn't work. Looking inside the .mod file, we see this:

name="CK2Plus"
archive="mod/ck2plus.zip"
dependencies=
{
CleanSlate
}
replace_path="history/provinces"
replace_path="history/titles"
replace_path="history/wars"
replace_path="common/buildings"
replace_path="common/trade_routes"
picture="ck2plus.jpg"
QuinoaFalafel 19 Dec, 2022 @ 3:20pm 
The section here on dependencies isn't entirely accurate, and caused me a lot of frustration when trying to figure out how to get them to work. So here are some corrections.

First, a clarification: dependencies are not technically dependencies. That's to say, you don't need to have all dependencies in order for a mod to work. Dependencies are just rules telling the game to load those mods before another.

Second, and most importantly, dependencies are NOT "established by the name of the .mod of the required mod". They are established by the NAME of the relevant mod, as established WITHIN the .mod file. In the Game of Thrones mod example, that didn't matter, because both are the same, but that's not always the case.
talesofwill 19 Oct, 2020 @ 10:18pm 
to create a new retinue do i just make a new template in the retinue_subunits folder?
SinStar87 (He/Him)  [author] 3 May, 2020 @ 8:09pm 
@ck_thegreat far as I can guess, dependency makes it load after the mod it's dependent on.
@renoraider great :)
renoraider 2 May, 2020 @ 5:42pm 
Thanks! Got it working.
ck_thegreat 2 May, 2020 @ 2:12pm 
when adding depenencies, would that stop the mod from working well with other conversion mods?