• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.
On Paradox Mods, how does one add a version changelog note ?
 
OK, I'm doing localization for my events now and I ran into an issue. The events in question are about about flipping certain areas to be De Jure territory of Empire of Slavia, one area after the other, depending on what you control.

So, one of the events in question is flipping the historical region of Bavaria Slavica (in-game duchies of Nordgau and East Franconia) to the Kingdom of Bohemia (which itself is a vassal of the Empire of Slavia at this point). You can either agree to do that or not.

And after that, if you own the entirety of the Kingdom of Bavaria (but don't own all the non-Bavarian land required to form the Kingdom of Carantania, which I also added in my mod, but it's not relevant here), you get a choice to flip Bavaria itself to the Empire of Slavia.

Which is where the issue with localization begins. Because depending on what you conquered before forming Slavia and on the choices you made in the earlier events in the chain, there are three different scenarios:
  1. you had the opportunity to add Bavaria Slavica (i.e. the duchies of Nordgau and East Franconia to Bohemia) and did just that;
  2. you had the opportunity to add Bavaria Slavica, but chose not to;
  3. you didn't have the opportunity to add Bavaria Slavica to Bohemia, but you do have the opportunity to add the Kingdom of Bavaria to the Empire of Slavia (i.e. you control the Duchy of Nordgau, together with the rest of the Kingdom of Bavaria, but you don not control the Duchy of East Franconia).
Which warrants three different (slightly, but still) descriptions of the event pertaining to the Kingdom of Bavaria.

Given that Nordgau is by default part of the Kingdom of Bavaria, at least before the Bavaria Slavica event, the deciding factor here is the Duchy of East Franconia and whether or not:
  1. you control it in the first place and;
  2. it's De Jure liege is the Kingdom of Bohemia or not.
Which is what I chose to check for when making the event decide which description to trigger.

Which makes the Kingdom of Bavaria event not trigger and outright breaks all later events in the file... Even though the piece of code that allows to do dynamic event descriptions depending on circumstances has been covered in a dev diary on modding events and appears to be pretty straightforward. The line is first_valid

After I ran into issues I even decided to check for whether I just control East Franconia itself, leaving the issue of its relation to Bohemia aside for awhile, to see what I'm doing wrong.

So, I tried this code:
Code:
    desc = {
        first_valid = {
            triggered_desc = {
                trigger = {
                    title:d_east_franconia = {
                        target_is_de_facto_liege_or_above = title:e_slavia
                    }
                }
                desc = great_slavia.0011.desc.refused_bavaria_slavica
            }
            great_slavia.0011.desc
        }
    }

Still nothing, still breaks the reminder of the file. I tried flipping things around and using:
Code:
trigger = {
    title:e_slavia = {
        is_de_facto_liege_or_above_target = title:d_east_franconia
    }
}

Same result. I tried moving the specifics of the trigger into a scripted trigger - scripted_trigger refused_bavaria_slavica = - (with both is_de_facto_liege_or_above_target and target_is_de_facto_liege_or_above variants) defined before the event and then making the trigger in the event:
Code:
trigger = {
    scripted_trigger = { refused_bavaria_slavica = yes }
}

Again. Nothing. I've even tried the de_jure variants of both of those lines for k_bohemia and e_slavia and tried to check things by triggering the Bavaria event from console (as such, because of bypassing the initial decision, Bohemia wouldn't be De Jure of the Empire of Slavia), to same effect.

So I don't know what I'm doing wrong. Both is_de_facto_liege_or_above_target and target_is_de_facto_liege_or_above are listed on the page for triggers on the CKIII wiki, so they should work when I'm writing a trigger. I've even found examples of some of those pieces of code being used in the same exact manner (albeit in a limit rather than a trigger).

EDIT: I even just used the target_is_de_jure_liege_or_above in a limit in an earlier event in the chain where I realized it made more sense than what I previously did and it works just fine. So I guess those lines work for limits, but not triggers? Or am I missing something here? And if I'm not, how do I then achieve what I want to achieve here?
 
Last edited:
This is probably a bit too deep for me, but I did notice that I would have used an additional "desc =" in the last line of your first code block. Maybe I am using it unnecessarily, but if not then it might help.
 
  • 1Like
Reactions:
This is probably a bit too deep for me, but I did notice that I would have used an additional "desc =" in the last line of your first code block. Maybe I am using it unnecessarily, but if not then it might help.

Goddamnit, how could I have missed that... Yes, that solved the issue -.- Oh, well, at least my logic was correct. Only a few issues remaining to figure out, but I'll get there when I'll get there.
 
Last question for tonight. I'm now playing around with lists, picking a character from the list, saving them as a scope and using that scope for localization and showing that character in the event screen.

Now, in most of my events the left_portrait character is me while the right_portrait character is some councilor and, if I use a scoped character from the list, they'll appear in the bottom row.

Code:
immediate = {
    play_music_cue = "mx_cue_epic_sacral_moment"
    save_scope_as = scoped_ruler
    every_vassal_or_below = {
        limit = {
            has_culture = culture:bosnian
        }
        add_to_list = serbian_vassals
    }
    random_in_list = {
        list = serbian_vassals
        save_scope_as = serbian_representative
    }
}

A simple example I'm using for testing.

And, from my testing, it appears that if there's no scoped character because the list came up with no results (which is why I'm currently looking for Bosnian vassals or sub-vassals for a position of a Serbian representatives, as I have none of those), the scoped character simply will not appear in the selected bottom row portrait with no issues that I can see.

But for one or two events that I have planned I want the scoped character to be the one on the right with no councilor as a third character. Unless the list comes up empty. In that case I want the councilor to be picked as the right portrait character as a fallback option. Having the councilor to be the one showing in the bottom row portrait was no go, because I don't want him to be in the event if there is a scoped character at all. On top of that, if there is no scoped character I'd have the councilor portrait in the bottom while the right portrait would remain empty, which would look kinda bad.

I tried the following:
Code:
right_portrait = {
    first_valid = {
        limit = {
            exists = scope:serbian_representative
        }
        character = scope:serbian_representative
        animation = beg
    }
    character = cp:councillor_chancellor
    animation = personality_rational
}
Code:
right_portrait = {
    if = {
        limit = {
            exists = scope:serbian_representative
        }
        character = scope:serbian_representative
        animation = beg
    }
    else = {
        character = cp:councillor_chancellor
        animation = personality_rational
    }
}
Code:
if = {
    limit = {
        exists = scope:serbian_representative
    }
    right_portrait = {
        character = scope:serbian_representative
        animation = beg
    }
}
else = {
    right_portrait = {
        character = cp:councillor_chancellor
        animation = personality_rational
    }
}

EDIT: Although, to think of it, I guess you could achieve that with adding the councilor to the list and then using alternative_limit = { always = yes } in the scoped character selection for random lists, or adding a big value modifier for culture (following my example) in an ordered list, with the councilor being picked with the base value + whatever else they may get. But I'll have to test that tomorrow.

Plus that seems like a roundabout solution. And this way you won't be able to choose a different animation if the councilor is picked, which is something I'd like. And, to think of it, it would also maybe mess with localization, since I was planning on having different event description depending on whether there is a scoped character or the event falls back to the councilor. Although that could likely be solved with is_councilor And if you can make some conditions for at least the animation of the portrait, this would work and possibly achieve everything I want this to do. Again, something to test tomorrow.

So if this is possible to achieve in a non-roundabout way, I'd still appreciate any help.
 
Last edited:
Something like this should do the trick, adjusted as necessary.

Code:
any_realm_county = {
    count >= 30
    faith = faith:bosnian_church
}
Okay, update on this, I was wrong to dismiss it as it does work fine, but the text in the decision window is not particularly clear. I guess I need a custom description here... oh god, I'll need to go into customizable_localization, won't I? WHY MUST IT TORMENT ME SO?

EDIT:

(voiceover) It didn't.
 
Last edited:
  • 1Haha
Reactions:
Hey guys this is a noob question but i wanted to add a new armor with no legwear underneath it, is it sufficient to add the regular no_legwear gene to the armor or do i have to create a new 01_custom_legwear.txt in gfx/portraits/portrait_modifiers? That folder seems to have different modifiers for game usage like 01_clothes.txt and customization usage like 01_custom_clothes.txt.
However by default there is no 01_custom_legwear.txt so maybe that is why my code doesn't work atm?
 
I'm trying to get the coat of arms for the Danelaw to switch based on character religion just like England does for culture. In testing it doesn't automatically switch but will switch before the title is created if you convert to Christianity and then create k_danelaw. It just then won't switch back and forth if you reconvert to Asatru / Christianity. It also works when calling the event coa.1 manually.

These are my triggers:

Code:
coa_switch_to_asatru_trigger = {
    has_religion = religion:germanic_religion
}
coa_switch_to_christian_trigger = {
    has_religion = religion:christianity_religion
}

This is the event code:

Code:
coa.1 = {
    type = character_event
    hidden = yes
    trigger = {
        is_ruler = yes
    }
    immediate = {
        trigger_event = coa.10 # England
        trigger_event = coa.11 # Normans, Welsh, Saxons
        trigger_event = coa.12 # Danelaw
    }
}

...

coa.12 = {
    type = character_event
    hidden = yes
    trigger = {
        any_held_title = { this = title:k_danelaw }
    }
    immediate = {
        if = {
            limit = { coa_switch_to_asatru_trigger = yes }
            title:k_danelaw = { set_coa = k_danelaw } # reset
        }
        
        if = {
            limit = { coa_switch_to_christian_trigger = yes }
            title:k_danelaw = { set_coa = k_danelaw_christian }
        }
    }
}

I then added coa.1 to the religion_on_actions file:

Code:
on_character_faith_change = {
    effect = {
        check_for_equal_doctrine_effect = yes
    }
    events = {
        faith_conversion.0002 # Remove obsolete modifiers
        faith_conversion.0004 # Convert Theocracies
        faith_conversion.0005 # Update marriage opinions
        great_holy_war.0025 # Replace Recipient for ongoing GHW
        great_holy_war.0029 # Beneficiary converted, remove and replace.
        great_holy_war.0059 # Clear Crusader traits on conversion.
        great_holy_war.0084 # Replace fallback ghw recipient
        great_holy_war.0085 # Remove pledged vassals upon conversion of their liege.
        false_conversion.0001    # Flag possible false conversions.
        war_event.3100        # Handles invalidation of religious wars
        coa.1 # check if title Coat of Arms should change.
    }
}

I don't see anything in error.log about this. Anyone able to help debug?
 
Hey guys this is a noob question but i wanted to add a new armor with no legwear underneath it, is it sufficient to add the regular no_legwear gene to the armor or do i have to create a new 01_custom_legwear.txt in gfx/portraits/portrait_modifiers? That folder seems to have different modifiers for game usage like 01_clothes.txt and customization usage like 01_custom_clothes.txt.
However by default there is no 01_custom_legwear.txt so maybe that is why my code doesn't work atm?
I'm not sure what you mean by 'add the regular no_legwear gene to the armor.' My thought is that you might need to create a custom no_legwear rule, as you suggested (or completely overwrite the default 01_legwear.txt file, but that's obviously not as desirable).

I'm trying to get the coat of arms for the Danelaw to switch based on character religion just like England does for culture. In testing it doesn't automatically switch but will switch before the title is created if you convert to Christianity and then create k_danelaw. It just then won't switch back and forth if you reconvert to Asatru / Christianity. It also works when calling the event coa.1 manually.

These are my triggers:

Code:
coa_switch_to_asatru_trigger = {
    has_religion = religion:germanic_religion
}
coa_switch_to_christian_trigger = {
    has_religion = religion:christianity_religion
}

This is the event code:

Code:
coa.1 = {
    type = character_event
    hidden = yes
    trigger = {
        is_ruler = yes
    }
    immediate = {
        trigger_event = coa.10 # England
        trigger_event = coa.11 # Normans, Welsh, Saxons
        trigger_event = coa.12 # Danelaw
    }
}

...

coa.12 = {
    type = character_event
    hidden = yes
    trigger = {
        any_held_title = { this = title:k_danelaw }
    }
    immediate = {
        if = {
            limit = { coa_switch_to_asatru_trigger = yes }
            title:k_danelaw = { set_coa = k_danelaw } # reset
        }
     
        if = {
            limit = { coa_switch_to_christian_trigger = yes }
            title:k_danelaw = { set_coa = k_danelaw_christian }
        }
    }
}

I then added coa.1 to the religion_on_actions file:

Code:
on_character_faith_change = {
    effect = {
        check_for_equal_doctrine_effect = yes
    }
    events = {
        faith_conversion.0002 # Remove obsolete modifiers
        faith_conversion.0004 # Convert Theocracies
        faith_conversion.0005 # Update marriage opinions
        great_holy_war.0025 # Replace Recipient for ongoing GHW
        great_holy_war.0029 # Beneficiary converted, remove and replace.
        great_holy_war.0059 # Clear Crusader traits on conversion.
        great_holy_war.0084 # Replace fallback ghw recipient
        great_holy_war.0085 # Remove pledged vassals upon conversion of their liege.
        false_conversion.0001    # Flag possible false conversions.
        war_event.3100        # Handles invalidation of religious wars
        coa.1 # check if title Coat of Arms should change.
    }
}

I don't see anything in error.log about this. Anyone able to help debug?

coa.1 isn't called by default on conversion—if you let your game run for up to a year, it should change over when it's fired from the yearly_playable_pulse. Alternatively, to ensure it fires immediately, you could set up custom calls in common\on_action for either on_faith_conversion, on_character_faith_change, or both, depending on your needs. Be aware that if you want to call it as an event from these on_actions, you will need to completely copy the vanilla event calls, as your modded events block will overwrite those in common/on_action/religion_on_actions.txt. To avoid this, I'd set up a custom on action and call it from those triggers instead, since they don't have an on_actions block that can be overwritten:—

Code:
# common/on_action/danelaw_on_actions.txt

danelaw_conversion = {
    events = {
        coa.1
    }
}

on_faith_conversion = {
    on_actions = {
        danelaw_conversion
    }
}

on_character_faith_change = {
    on_actions = {
        danelaw_conversion
    }
}
 
  • 1Like
Reactions:
Hi, can someone explain the duel = { ... } stuff ? I have two script_values i want to use for success outcome, but I don't find explanations to duels and compare_modifiers. One of my script_values are the requirement/base value for success, the other one is calculated based on a character trait. i want to compare both numbers and make the success/fail outcome.

Perl:
    option = {
        name = ctda_activity_practice_necromancy_events.1.a
        duel = {
            value = ctda_necromancer_skill_req_novice # for me it is the base value to check against

            compare_modifier = {
                value = ctda_necromancer_skill_value # for me it is the character's skill value
                multiplier = 1 # i don't use it because i calculate success chance within ctda_necromancer_skill_value
            }
        }
    }

here are all the script_values with some explanation, in case my question is not clear enough.
Perl:
#########################################################################################################################
# Required base values for skilled actions per expert level.
# The character's necromancer trait level determines the success chance for activities on equal expert level.
# Novice    : 55 %
# Apprentice: 65 %
# Adept     : 75 %
# Exoert    : 85 %
# Master    : 95 %
#########################################################################################################################
ctda_necromancer_skill_req_novice = 5
ctda_necromancer_skill_req_apprentice = 10
ctda_necromancer_skill_req_adept = 15
ctda_necromancer_skill_req_expert = 20
ctda_necromancer_skill_req_master = 25
ctda_necromancer_success_chance_novice = 0.55
ctda_necromancer_success_chance_apprentice = 0.65
ctda_necromancer_success_chance_adept = 0.75
ctda_necromancer_success_chance_expert = 0.85
ctda_necromancer_success_chance_master = 0.95
 
I'm trying to get the coat of arms for the Danelaw to switch based on character religion just like England does for culture. In testing it doesn't automatically switch but will switch before the title is created if you convert to Christianity and then create k_danelaw. It just then won't switch back and forth if you reconvert to Asatru / Christianity. It also works when calling the event coa.1 manually.

These are my triggers:

Code:
coa_switch_to_asatru_trigger = {
    has_religion = religion:germanic_religion
}
coa_switch_to_christian_trigger = {
    has_religion = religion:christianity_religion
}

This is the event code:

Code:
coa.1 = {
    type = character_event
    hidden = yes
    trigger = {
        is_ruler = yes
    }
    immediate = {
        trigger_event = coa.10 # England
        trigger_event = coa.11 # Normans, Welsh, Saxons
        trigger_event = coa.12 # Danelaw
    }
}

...

coa.12 = {
    type = character_event
    hidden = yes
    trigger = {
        any_held_title = { this = title:k_danelaw }
    }
    immediate = {
        if = {
            limit = { coa_switch_to_asatru_trigger = yes }
            title:k_danelaw = { set_coa = k_danelaw } # reset
        }
       
        if = {
            limit = { coa_switch_to_christian_trigger = yes }
            title:k_danelaw = { set_coa = k_danelaw_christian }
        }
    }
}

I then added coa.1 to the religion_on_actions file:

Code:
on_character_faith_change = {
    effect = {
        check_for_equal_doctrine_effect = yes
    }
    events = {
        faith_conversion.0002 # Remove obsolete modifiers
        faith_conversion.0004 # Convert Theocracies
        faith_conversion.0005 # Update marriage opinions
        great_holy_war.0025 # Replace Recipient for ongoing GHW
        great_holy_war.0029 # Beneficiary converted, remove and replace.
        great_holy_war.0059 # Clear Crusader traits on conversion.
        great_holy_war.0084 # Replace fallback ghw recipient
        great_holy_war.0085 # Remove pledged vassals upon conversion of their liege.
        false_conversion.0001    # Flag possible false conversions.
        war_event.3100        # Handles invalidation of religious wars
        coa.1 # check if title Coat of Arms should change.
    }
}

I don't see anything in error.log about this. Anyone able to help debug?

I am more familiar with stellaris, but maybe it is valid here. The check is a trigger right ? so it needs to be in trigger and not in effect (?)
 
I'm not sure what you mean by 'add the regular no_legwear gene to the armor.' My thought is that you might need to create a custom no_legwear rule, as you suggested (or completely overwrite the default 01_legwear.txt file, but that's obviously not as desirable).


I was thinking of adding
mode = add
gene = legwear
template = no_legwear
value = 0

from the no_legwear section directly into the armor as an additional dna modifier like this

byzantine_war = {
dna_modifiers = {
accessory = {
mode = add
gene = clothes
template = byzantine_war_nobility_clothes
range = { 0 1 } # For the randomness to work correctly
}
dna_modifiers = {
accessory = {
mode = add
gene = legwear
template = no_legwear
value = 0
}
morph = {
mode = modify_multiply
gene = gene_bs_bust
value = 1.0
template = bust_clothes
}
morph = {
mode = modify_multiply
gene = gene_bs_body_shape
value = 1.0
template = body_shape_average_clothed
}
}
weight = {
base = 0
modifier = {
add = 100
portrait_wear_armor_trigger = yes
portrait_byzantine_clothing_trigger = yes
}
}
}



SRY i suck at formatting i just started my modding career 2 days ago XD
 
To answer my own question from yesterday, you can modify what animation a portrait in an event uses depending on circumstances. The line to do so is triggered_animation.

To use my example:
Code:
triggered_animation = {
    trigger = {
        scope:serbian_representative = {
            has_culture = culture:serbian
        }
    }
    animation = beg
}
triggered_animation = {
    trigger = {
        scope:serbian_representative = {
            is_councillor_of = scope:scoped_ruler
        }
    }
    animation = personality_rational
}

The way it works is similar to first_valid for variable descriptions. If a trigger for a given triggered animation is not met, the event will go to the next triggered animation and continue to do so until a triggered animation's conditions are met, at which point it picks that one and ignores the rest. So put your preferred animation on top and the fallback options below.
 
Last edited:
  • 1
Reactions:
Im trying to change the convert culture action such that the AI will only convert counties if one of the following is true :

-they own the county directly

-the county holder is a direct vassal of the councillor's liege AND it is the vassal's capital county

How do you do the trigger for this?

I tried this, but it does not work (the AI always refuses to convert culture) :

Code:
if = {
            # If not holder, only convert the capitals of direct vassals
            limit = {
                NOR = {
                    scope:county.holder = scope:councillor_liege #checks if the liege owns it directly
                 
                    scope:county.holder = {
                        is_vassal_of = scope:councillor_liege #checks if the holder is a direct vassal of the liege
                    }

                    scope:county.holder.capital_county = scope:county # checks if the holder's capital_county is scope:county
                }
            }     
            multiply = 0
        }

Edit : I can confirm that this doesnt work at least :

Code:
scope:county.holder = {
                        is_vassal_of = scope:councillor_liege #checks if the holder is a direct vassal of the liege
                    }

Its supposed to check if the county.holder is a vassal of councillor_liege, but its not doing that. I dont understand, whats wrong with it?

Edit 2 : I think scope:county doesnt work in ai_will_do. Going to try moving it to potential_county instead.
 
Last edited:
Have you looked in the error.log in .../Documents/Paradox Interactive/Crusader Kings III/logs? Also in _council_tasks.info, ai_will_do is not listed, so it probably doesn't exist there. I'd definitely put it in potential_county
Code:
potential_county = {
    scope:county = {
        NOT = { culture = scope:councillor_liege.culture }
    }
    trigger_if = {
        limit = {
            scope:councillor_liege = { is_ai = yes }
        }
        scope:county = {
            OR = {
                holder = scope:councillor_liege
                holder = {
                    is_vassal_of = scope:councillor_liege
                    capital_county = scope:county
                }
            }
        }
        OR = {...
        }
        OR = {...
        }
    }
}
Note: as you were only talking about limiting the AI, the code above would'nt limit a player
 
Quick question regarding localization: I managed to get my own armor into the game but can't get the game to use the regular localization path so i can set different names for the male and female version of the armor.
These are the regular paths i've seen the game use for localization:

PORTRAIT_MODIFIER_custom_clothes_male_clothes_secular_modded_myarmor_01:1 "Myarmor Male"
PORTRAIT_MODIFIER_custom_clothes_female_clothes_secular_modded_myarmor_01:1 "Myarmor female"

but for whatever reason the path my armor gets its localization from is instead.

PORTRAIT_MODIFIER_custom_clothes_modded_myarmor:1 "Myarmor Male"
Do you have any idea what i didn't set up correctly that causes this?
 
I am trying to create a letter event to trigger if there is a high prowess prisoner in my dungeons, to use as a cheap source of knights. I want to limit it to adults and male only. I mistakenly thought I could use the following script, which is wrong. I am struggling to think of an elegant way of doing it. Any suggestions would be most welcome.
Code:
TOMSprisoner.0100 = {
    hidden = yes
    
    trigger = {
        is_at_war = no
        is_ai = no
        any_prisoner = {
            is_female = no
            age >= 18
            age <= 45
            prowess >= 14
        }
    }
    immediate = {
        ordered_prisoner = {
            is_female = no
            age >= 18
            age <= 45
            prowess >= 14
            save_scope_as = prisoner_knight
            
            order_by = {
                value = 5
                add = prowess
            }
        }
 
I am trying to create a letter event to trigger if there is a high prowess prisoner in my dungeons, to use as a cheap source of knights. I want to limit it to adults and male only. I mistakenly thought I could use the following script, which is wrong. I am struggling to think of an elegant way of doing it. Any suggestions would be most welcome.
Code:
TOMSprisoner.0100 = {
    hidden = yes
  
    trigger = {
        is_at_war = no
        is_ai = no
        any_prisoner = {
            is_female = no
            age >= 18
            age <= 45
            prowess >= 14
        }
    }

First of all, if you're just looking for adults, is_adult = yes would achieve that by itself. Moving on, I think your code for the immediate area should look like this:

Code:
immediate = {
    ordered_prisoner = {
        limit = {
            is_female = no
            age >= 18
            age <= 45
            prowess >= 14
        }
        order_by = prowess
        if = {
            limit = {
                NOT = { exists = scope:prisoner_knight }
            }
            save_scope_as = prisoner_knight
        }
    }
}