Decision modding

From Crusader Kings II Wiki
Jump to navigation Jump to search

Decisions are optional actions that the player or the AI can take, and which appear in diplomacy or intrigue screen (depending on the type).

Decisions are different from events, which trigger outside of the control of the player. Complex decisions will usually trigger a chain of events.

Decisions need to be in the /decisions/ folder.

Decisions[edit]

Decisions in the intrigue screen

Decisions are declared inside a block decisions = { } or plot_decisions = { }, and are shown in the Intrigue view.

They appear in the order they are loaded based on alphabetical file order in decision folder.

Note that decisions are very delicate: any syntax error, or unidentified keyword, will break them and cause section headings to be badly displayed in the intrigue screen.

Special scopes:

  • ROOT is the decision taker

Structure[edit]

<decision_name> = {
  is_high_prio = yes # Will show an alert once decision is enabled
  ai_check_interval = 12 # Determines how seldom the AI checks whether they can and should do the decision, in months. By default 1 (every month).
  potential = {
    #Conditions for the decision to appear
  }
  allow = {
    #Conditions for the decision to be enabled
  }
  effect = {
    #Commands executed when taking the decision
  }
  ai_will_do = {
    #Factors for an AI character to take the decision (1 = 100% chance)
  }
}

Localization[edit]

  • decision_name: label displayed in intrigue tab
  • decision_name_desc: tooltip when hovering the decision
  • decision_name_desc_extra: optional parameter, text shown after the Requirements section in the decision's tooltip

Icon[edit]

To define an icon for the decision, you need a spriteType with name GFX_decision_name in a .gfx file inside interface/ folder.

Vanilla decision icons are 28px x 28px DDS files with transparent background, the icon itself being 24px x 20px with a 2px black border.

spriteTypes = {
  ...
  spriteType = {
    name = "GFX_decision_name"
    texturefile = "gfx\\interface\\decision_icon.dds"
  }
  ...
}

Dynasty and Vassal decisions[edit]


These decisions appear once for every dynasty or vassal in the intrigue menu, they have been made semi-redundant by targeted decisions but one can still use them if they prefer. Keep in mind that vassal does not necessarily mean a direct vassal, it can be anybody at all just, it is like a normal decision but appears once per person.

They are declared inside a block vassal_decisions = { } or dynasty_decisions = { }, and are shown in the Intrigue view.

Special scopes:

  • FROM is the decision taker
  • ROOT is the decision target

Structure[edit]

decision_name = {
  is_high_prio = yes # Will show an alert once decision is enabled
  ai_check_interval = 12 # Determines how seldom the AI checks whether they can and should do the decision, in months. By default 1 (every month).
  from_potential = {
    #Conditions on the decision taker for the decision to appear
  potential = {
    #Conditions on the vassal or dynasty member for the decision to appear
  }
  allow = {
    #Conditions for the decision to be enabled
  }
  effect = {
    #Commands executed when taking the decision
  }
  revoke_allowed = {
    always = no #Not used in vanilla
  }
  ai_will_do = {
    #Factors for an AI character to take the decision (1 = 100% chance)
  }
}

Localization[edit]

  • decision_name: label displayed in intrigue tab
  • decision_name_desc: tooltip when hovering the decision

Icon[edit]

To define an icon for the decision, you need a spriteType with name GFX_decision_name in a .gfx file inside interface/ folder.

Vanilla decision icons are 28px x 28px DDS files with transparent background, the icon itself being 24px x 20px with a 2px black border.

spriteTypes = {
  ...
  spriteType = {
    name = "GFX_decision_name"
    texturefile = "gfx\\interface\\decision_icon.dds"
  }
  ...
}

Targeted decisions[edit]

Targeted decisions will appear in a character diplomacy menu

Targeted decisions are declared inside a block targetted_decisions = { }, and are shown in the Diplomacy view. Note that adding targeted decisions with add_decision to a technology within technology.txt seems to make the decision unusable on unlanded characters.

Special scopes:

  • FROM is the decision taker
  • ROOT is the targeted character

In order to limit CPU load, filter and ai_target_filter specify the types of targeted characters (for the player / the AI respectively), for which potential and allow blocks will be evaluated:

  • self: self MUST be set for decisions targeting only the taker
  • spouse: decision taker spouses
  • court: all characters in the decision taker host court, including prisoners, and characters currently away (wards, prisoners, etc.), not including the decision taker
  • home_court: all characters in the decision taker home court, including prisoners, and characters currently away (wards, prisoners, etc.), not including the decision taker
  • liege: direct liege of the decision taker
  • vassals: direct vassal rulers of the decision taker employer
  • sub_realm: all characters below the decision taker employer, not including the decision taker themself
  • realm: all characters in the same top realm as the decision taker, not including the decision taker themself
  • dynasty: all members of the same dynasty, including the dead, not including the decision taker themself
  • close_relatives: Includes children, grandchildren, parents, siblings, and nieces/nephews
  • rivals: decision taker's rivals plus any character that have an opinion modifier with 'crime = yes' set (the same set of characters the 'is_foe' trigger evaluates)
  • friends: decision taker's friends
  • liege: the decision taker's liege, unless independent
  • rel_head: the decision taker's religious head, unless they are the head of their religion
  • society: characters in the same society as the decision taker, not including the decision taker themself.
  • vassal_wars: All vassals' wars
  • independent_rulers: All independent rulers
  • all: all living characters (to be avoided, very CPU heavy !)
  • none: No one. Mainly useful for banning the AI from using a decision

Additionally, all, court, home_court, sub_realm, realm, dynasty, rel_head, independent_rulers and society have "_including_me" versions (e.g. court_including_me) which also include the decision taker.

Structure[edit]

decision_name = {
  is_high_prio = yes # Will show an alert if special action is available
  ai_check_interval = 12 # Determines how seldom the AI checks whether they can and should do the decision, in months. By default 1 (every month).
  filter = sub_realm #Filter characters targeted by the player
  from_potential = {
    #Conditions on the decision taker for the decision to appear. Not taken into account when filter = self, use potential instead.
  }
  potential = {
    #Conditions on the targeted character for the decision to appear
  }
  allow = {
    #Conditions for the decision to be enabled
  }
  effect = {
    #Commands executed when taking the decision
  }
  revoke_allowed = {
    always = no #Not used in vanilla
  }
  ai_will_do = {
    #Factors for an AI character to take the decision (1 = 100% chance every month - for each allowed target!)
  }
  ai_acceptance = {
    # See below  
  }
}

AI acceptance[edit]

AI acceptance is an optional section for targeted decisions to indicate whether the AI will accept the decision. Note that how the AI responds is unaffected by this system; it is meant as a way to communicate the outcome to the player. It is up to the person scripting to make the AI actually act in accordance with the "yes" or "maybe" shown. Only "no" has a mechanical effect, blocking the decision entirely.

If ai_acceptance is defined, AI acceptance will show in the decision, similar to how it shows for many interactions. The "Do It!" button will be greyed out if the score is below or equal to Zero. The exact value will be saved to the local variable local_ai_acceptance_score, similar to how 3rd party score is saved. It will be saved for player-controlled targets as well, even if show_maybe_for_human is used.

An example AI acceptance section:

ai_acceptance = {
	factor = 10 # The base score
	yes_threshold = 50 # At what point to switch from "maybe" to "yes". Defaults to 0, meaning it will never be "maybe"
	show_maybe_for_human = no # Whether to always show "maybe" for human targets (defined as ROOT being controlled by a player). Defaults to "yes"
	additive_modifier = { # Any type of modifier can be used, but "additive" is recommended as it is the most intuitive to the end user. Works same way as MTTHs, ai_will_do, and so on
		value = 10
		always = yes
	}
	additive_modifier = {
		value = -10
		always = yes
	}
	additive_modifier = {
		value = -10
		always = no
	}
	additive_modifier = {
		value = -100
		localisation_key = "REASON_WEALTH"
		wealth = 1000
	}
}

Localization[edit]

  • decision_name: label in diplomacy menu
  • decision_name_named: label displayed when selecting the action. [Root.GetTitledFirstName] can be used to display the target name.

Settlement decisions[edit]

Settlement decisions are possible vs all settlements and are shown in the Settlement Diplomacy view, not the Intrigue view. They are declared inside a block settlement_decisions = { } and use the same structure and localisation as targeted decisions.

Special scopes:

  • FROM is the decision taker
  • ROOT is the targeted settlement

In order to limit CPU load, filter / ai_target_filter specify the types of targeted settlement (for the player / the AI respectively), for which potential and allow blocks will be evaluated:

  • capital: decision taker's capital
  • owned: all settlements owned by the character
  • vassal_owned: all settlements owned by the character's employer's direct vassals
  • sub_realm_owned: all settlements below the character's employer
  • realm_owned: all settlements in the same top realm as the character
  • dynasty_owned: all settlements owned by a character of the same dynasty
  • all: all settlements (to be avoided, very CPU heavy!)

Similarly there are also trade_post_decisions = { }, fort_decisions = { }, and hospital_decisions = { }.

Title decisions[edit]

Title decisions are possible vs all titles and are shown in the Title Diplomacy View, not the Intrigue View. They are declared inside a block title_decisions = { }

Special scopes:

  • FROM is the decision taker
  • ROOT is the targeted title

In order to limit CPU load, filter / ai_target_filter specify the types of targeted settlement (for the player / the AI respectively), for which potential and allow blocks will be evaluated:

  • capital: decision taker's capital
  • primary_title
  • owned: all titles owned by the character
  • vassal_owned: all titles owned by direct vassal rulers of the character's employer
  • sub_realm_owned: all titles below the character's employer
  • realm_owned: all titles in the same top realm as the character
  • dynasty_owned: all titles owned by members of the same dynasty
  • all: all titles (to be avoided, very CPU heavy!)

Society Decisions[edit]

Added in Patch 2.7. Society decisions are declared inside a block society_decisions = { }. They will only be evaluated for characters who are in any society. They can be used to make the same decision available for members of different societies. Apart from this, they are identical to regular Decision.

Offmap Decisions[edit]

In Patch 2.8, offmap powers received decisions which are activated through the unique offmap power interface.

Similar to society decisions, these are surrounded in their own offmap_decisions = { } block, and are virtually identical to standard decisions. However, offmap_decisions also have a single unique parameter, button_name, which corresponds to the name of a button defined in the buttons section of an offmap power:

offmap_decisions = {

<decision_name> = {
	button_name = offmap_gifts
	
	ai_check_interval = 12
	is_high_prio = yes

	potential = {
		#Conditions for the decision to appear
	}
	allow = {
		#Conditions for the decision to be enabled
	}
	effect = {
		#Commands executed when taking the decision
	}
	ai_will_do = {
		#Factors for an AI character to take the decision (1 = 100% chance)
	}
}

}

Button names are localised, but the localisation key must match between all three files: in the offmap power, in the offmap_decision, and in the corresponding GUI file.

Offmap decisions can also take a third party, as detailed below.

Third Parties[edit]

Since Patch 2.8, decisions, which needs a target, can take a second one too, who will be the third party of it. This is possible for targeted, offmap, settlement and title decisions, but usually only used for the first two.

Additional special scope:

  • FROMFROM is the third party

third_party_filter and ai_third_party_filter use the same syntax filter and ai_target_filter in targeted decisions do, as well as an additional artifacts filter.

They can take one more parameter, third_party_score = { }. The scopes will be sorted based on that score and it will be a variable, stored as local_third_party_score. The base value can be defined with factor = #Base value, then it is possible to modify it with modifier = { } and additive_modifier = { }.

Structure[edit]

decision_name = {
  # other parameters
  third_party_filter = court #Filter for applicable third parties
  ai_third_party_filter = court #Filter for third party characters selected by the AI
  third_party = ROOT # Determine which scope the third party should be filtered from.  Defaults to FROM
  show_third_party_potential = yes #Set to show third party requirements in the tooltip. Defaults to no.
  third_party_potential = {
    #Conditions for a third party character to be included in the list
  }
  third_party_allow = {
    #Conditions on the selected third party for the "Send" button to be enabled
  }
  third_party_score = {
    #Factors to determine how "good" a third party character is for the decision.  Determines sorting.
    #This score is stored in the variable "local_third_party_score", so it can be used in triggers and effect
    factor = #Base value
    additive_modifier = {
      value = #Value to add to current
      #Conditions
    }
    #More additive_modifier
    modifier = {
      factor = #Factor to multiply the value
      #Conditions
    }
    #More modifier
  }
  effect = {
    #Commands executed when taking the decision
  }
}

Pre-triggers[edit]

Pre-triggers or fast triggers are special conditions at the root of decisions, that allow the AI to quickly exit evaluation of a decision if it doesn’t meet the pre-trigger, without having to evaluate the trigger block.[1][2] It is recommended that they be used when possible so as to reduce the time spent by the AI evaluating the decision. Note that the pre-trigger currently only applies to the AI, not to the player.

There’s no limit to how many pre-triggers, other than there only being one of each .

Warning: some pre-triggers have a different name than the equivalent normal condition!

The following decision pre-triggers currently exist for decisions:

Pre-trigger Type Scope Description Equivalent trigger
only_playable bool character In script, "playable" does not actually mean that the player can play the character. What it means is: count-tier or above, or a patrician, and is not a landless rebel. Using this pre-trigger completely eliminates evaluation of the event for anyone who does not meet the criteria, meaning that the event is checked for the ~1000 playable characters in the game, rather than all ~20k is_playable
only_rulers bool character Excludes untitled characters. This is a lesser version of only_playable, as it includes barons, rebels, etc. (i.e. anyone holding a title). is_ruler
only_independent bool character Excludes vassals and tributaries. Implies only_playable. independent
is_in_society bool character Excludes characters not belonging to a society (= yes) or belonging to a society (= no). is_in_society
ai = no bool character Excludes the decision from all non-player characters. Added in Patch 2.8. ai = no

See also[edit]