Event modding

From Crusader Kings II Wiki
Jump to: navigation, search

Events are both powerful for modding and easy to learn.

When writing an event (or event chain) the steps are usually the following:

  • Decide for who the event should fire: there are often multiple ways to script an event chain, but some are more efficient/simpler!
  • Decide if the event should trigger by itself or be triggered by something else (on action, decision, or other event).
  • If it triggers by itself, use fast triggers to avoid the trigger to be evaluated for EVERY single character in the world, and use sensible mean time to happen so that this evaluation doesn't take place EVERY day.

Once you've finished scripting, usually you'll need to:

  • Run The Validator to make sure there are no syntax errors (it's way faster to catch error this way, as testing in-game is not very efficient)
  • Load the game, and use console commands to meet the conditions of the event (can be seen via testevent <EventID> <CharOrProvID>)
  • Manually fire the event via event <EventID> <CharOrProvID>, to check there are no design errors and verify localizations.


Structure[edit]

Events usually consist of:

  • an initial trigger which fires the event on a character
  • a "mean time to happen"; or average time it takes for the event to fire
  • one or more options which will affect the character in the event-writer's chosen way
namespace = <namespace>
<event_type> = {
  #Basic event information
  id = <namespace>.<id>
  desc = EVTDESC<namespace>.<id>

  #Fast event triggers
  only_playable = yes

  trigger = {
    #Event eligibility condition block
    religion_group = pagan_group
  }
  mean_time_to_happen = {
    #Randomness of the event (not applicable for triggered-only events)
  }
  immediate = {
    #Command block executed once the target is eligible, but before displaying the event
  }
  option = {
    name = EVTOPTA<namespace>.<id>
    trigger = {
      #Option A eligibility condition block
    }
    ai_chance = {
      #Option A modifiers
    }
    #Option A command block
  }
  option = {
    name = EVTOPTB<namespace>.<id>
    trigger = {
      #Option B eligibility condition block
    }
    ai_chance = {
      #Option B modifiers
    }
    #Option B command block
  }
  after = {
     #Command block executed after any option is chosen. It is the counterpart of the immediate block.
  }
}

Basic information[edit]

Type[edit]

There are several types of events:

Type ROOT scope Description
character_event Character Basic character event.
Vanilla frames: GFX_event_normal_frame_diplomacy, GFX_event_normal_frame_war, GFX_event_normal_frame_economy, GFX_event_normal_frame_intrigue, GFX_event_normal_frame_religion, GFX_event_long_frame_diplomacy
long_character_event Character Bigger popup for character events, used in vanilla learning scenario.
Vanilla frames: GFX_event_long_frame_diplomacy, GFX_event_long_frame_war, GFX_event_long_frame_economy, GFX_event_long_frame_intrigue, GFX_event_long_frame_religion.
letter_event Character Shows the sender in-game.
Vanilla frames: GFX_event_letter_frame_diplomacy, GFX_event_letter_frame_war, GFX_event_letter_frame_war_big, GFX_event_letter_frame_economy, GFX_event_letter_frame_intrigue, GFX_event_letter_frame_religion.
narrative_event Character Similar to character_event, but with a large ornamented first letter, fancy frame, and slightly larger window.
Vanilla frames: GFX_event_narrative_frame_diplomacy, GFX_event_narrative_frame_war, GFX_event_narrative_frame_economy, GFX_event_narrative_frame_intrigue, GFX_event_narrative_frame_religion.
province_event Province Basic province event. Warning: fires to the owner of the province, but ROOT is the province!
Vanilla frames: same as character_event.
diploresponse_event Character [Verification needed]
unit_event [Verification needed] Used in one vanilla achievement.
society_quest_event Character Allow to define a quest_target that is determined in the immediate block of the event. For instance quest_target = event_target:infiltration_target

ID and namespace[edit]

Event IDs must be unique, as event collisions can result in bugs and CTDs. To improve compatibility between mods, and reduce the chance of identical IDs, namespaces can (and should!) be used.

Namespaces can be any alphanumeric string (without the '.' character), and are used as prefix in the form <namespace>.<id>. If an event file uses a namespace, it has to be declared at the beginning of the file with namespace = <namespace>. This has to be done for every file the namespace is used in.

At load time, namespaces are resolved to a numeric value. For instance event <namespace>.3132 may be transformed into ID 1403132 (i.e. <namespace> is 1,400,000 or 14). Because of this:

  • event IDs without a namespace must not go over 999,999
  • event IDs with a namespace must not go over 99,999

Below is an example of the use of the namespace "mymod":

namespace = mymod
character_event = {
    id = mymod.0001
    desc = EVTDESCmymod.0001
    option = {
       name = EVTOPTAmymod.0001
    }
}

Note that neither the "EVTDESC" nor "EVTOPT" prefix are required -- nor do the localisation keys even technically need to be related to your namespace at all -- but it is best practice by far to choose a clear and clash-free naming convention based on your mod. Provided the localisation keys exist, the above example would work just as successfully as:

namespace = mymod
character_event = {
    id = mymod.0001
    desc = mymodprefix_event_0001
    option = {
       name = mymodprefix_event_0001A
    }
}

where mymodprefix is a unique prefix you've chosen to distinguish your mod. If you choose to do this, of course, be careful to use prefixes that do not clash with jargon -- nothing would be more embarrassing than choosing a key like "cb_" for your hypothetical mod Crusader Babes, only to find that you are overwriting numerous casus belli keys from the base game. (Nothing more embarrassing, perhaps, with the exception of making the mod in the first place.)

Description[edit]

Descriptions define the text of the event and can either be a fixed localization key or a dynamic block. A fixed localisation key is simply expressed in the form desc = key:

desc = EVTDESC450

A dynamic block is similar but includes a series of trigger conditions that determine whether a description will appear

desc = {
  trigger = {
    #Conditions for 1st description to be chosen
  }
  text = EVTDESC_case1_mymod.0001
}

desc = {
  trigger = {
    #Conditions for 2nd description to be chosen
  }
  text = EVTDESC_case2_mymod.0001
}

If multiple descriptions can appear according to their trigger conditions, a list of all available descriptions will be generated and one of the descriptions will be chosen randomly by the game engine. This can also be done with static localisation keys. For instance:

character_event = {
  id = mymod.733
  desc = EVTDESCmymod.733.1
  desc = EVTDESCmymod.733.2
  desc = EVTDESCmymod.733.3
  desc = EVTDESCmymod.733.4
}

This will randomly display one of the four descriptions provided when the event is triggered. (This feature also works for option descriptions.)

Picture[edit]

Event pictures are the horizontal pictures that appear on the top of an event scroll. Like descriptions they can either be fixed event_pictures or a dynamic block. A fixed localisation key is simply expressed in the form picture = key, for example:

picture = GFX_evt_battle

A dynamic block is similar but includes a series of trigger conditions that determine whether the listed picture will be replaced. Note that the picture has to be defined under the dynamic description block, this is true even if the description is the same throughout with only the picture changing.

character_event = {
     id = mymod.777
     title = TITLE
     picture = GFX_evt_battle # There needs to be a default picture, even if it won't actually show up

     desc = {
       trigger = { condition = yes }
       text = EVTDESC_case1_mymod.777
       picture = GFX_evt_battle_byzantine
     }
     desc = {
       trigger = { condition2 = yes }
       text = EVTDESC_case2_mymod.777
       picture = GFX_evt_mongols_pillage_oldgods
     }
}

Keep in mind that these triggers are resolved after the immediate command block has been run, which you need to take into account if you're using conditionals that get changed in the same event.

It should be noted that the name used to call an event picture is not always the same as the name for the event picture. In the example above: GFX_evt_battle_byzantine doesn't call a file named battle_byzantine, instead it calls the file Battle_Cataphracts_Saracen. This is because in order to call an event picture the event picture needs to be defined in a gfx file in the interface folder, and sometimes the call name differs from the file name. If a call name does not match any text from the gfx file in the interface folder, your event will have the default event picture.

In addition, many event pictures and their defining files are not located in the main event_pictures and interface folders. These are instead found in their corresponding dlc zip folder. For example: the event pictures for the Sunset Invasion DLC and their defining gfx file are located in the dlc/dlc018.zip folder.

You can also create your own even picture, make it a 450 x 150 .dds or .tga file inside of the gfx/event_pictures folder. Then define the file inside of a gfx file inside of the interface folder like so;

spriteTypes = {
     ...
     spriteType = {
          name = "GFX_evt_custompic"
          texturefile = "gfx\\event_pictures\\custompic.tga"
     }
     ...
}

The name calls it and the texture file points to the needed file. You can make name anything you want, but why on earth would you want to make it anything other than the file name?

Flags[edit]

Some flags can be used to configure events:

Flag Type Description
title Localization key Short text that will appear above the picture for standard event, and before the description for narrative_event. This is mandatory for narrative_event to display properly, as the first letter of the title is ornamented.
desc Localization key or clause Main text for the event. Use \n in localization to force a newline.
picture gfx Image that shows up at the top of the event (450x150 px). Not needed in case of hide_window = yes, nor for letter_event. References an entry in interface/*.gfx folder (ex: GFX_evt_council).

Those entries can be overridden by culture and/or religion by defining a gfx entry GFX_<picture>_<religion> or GFX_<picture>_<culture>.

border gfx Frame for the popup. Event types have different matching frames.
major bool If yes, will also appear for other characters, in addition to ROOT. This can be refined via the major_trigger block.

Warning: for events with major = yes, in major_trigger block, event description localization and option blocks, default scope and ROOT scope are different:

  • the default scope ([This.xxx] in localization) is the character that gets notified
  • ROOT is the character or province for which the event originally fires

trigger and immediate blocks are unchanged.

is_friendly bool Always uses compliments in letter events, regardless of opinion.
is_hostile bool Always uses insults in letter events, regardless of opinion.
is_triggered_only bool If yes, event cannot fire by itself and needs to be called from another event, decision or on_action. Note: trigger = { } block will still be evaluated to test if the event should apply or not.
triggered_from_code bool Used for some vanilla tutorial events. These are referenced in NLearningScenario section of defines.
hide_from bool Does not show FROM's portrait on the event, even when it is normally visible.
hide_new bool
hide_window bool Makes the event invisible. Event options will still be evaluated while hidden.
show_root bool Usually used in combination with major = yes
show_from_from bool Overrides default behavior of showing character of FROM scope in the top-right corner.
show_from_from_from bool Overrides default behavior of showing character of FROM scope in the top-right corner.
sound sfx Plays the given sound.
notification bool Adds a notification message. Note: not very nice for province_event, as it will show an empty character portrait in the notification.

Pre-triggers[edit]

Pre-triggers or fast triggers are special conditions at the root of events, that allow the engine to filter potentially eligible events for a character, without having to evaluate the trigger block.[1][2]

There’s no limit to how many pre-triggers, other than there only being one of each (except for DLC checks).

Most pre-triggers only work for character events, but a few can also be used in province events as of patch 2.6.

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

Filtering pre-triggers[edit]

Few pre-triggers are significantly more effective, because they’re kept in separate event lists that are only ever evaluated if a character meets their condition. These can be considered "filtering" pre-triggers since they can completely eliminate events from even preliminary evaluation.

They are, in order of precedence:

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
is_part_of_plot bool character Restricts to characters that are backing or leading a plot. Takes precedence over everything except only_playable, as the number of characters involved in plots is generally lower than the number of rulers. has_plot
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
religion religion character Restricts the event for members of the religion/religion_group. It is mutually exclusive with the other filtering pre-triggers, i.e only_playable and only_rulers both take precedence, so in some cases it might actually be better to just use religion_group = SOME_RARE_GROUP and leave out only_rulers = yes. religion
religion_group religion_group character religion_group

Other pre-triggers[edit]

Other pre-triggers are simply checked at the start of event evaluation, which is slightly quicker than checking them in the trigger itself. All are cheap checks and so should be used as much as possible (but are not worth contorting the logic of events to make them work).

Pre-trigger Type Scope Description Equivalent trigger
min_age int character Minimum age of the character (for this event). age
max_age int character Maximum age of the character (for this event). NOT age
only_independent bool character Excludes vassals. Implies only_playable. independent
only_men bool character is_female = no
only_women bool character is_female = yes
only_capable bool character NOT = { trait = incapable }
capable_only bool character If yes, only picks characters without any incapacitating = yes traits, i.e. the incapable  trait. NOT = { trait = incapable }
lacks_dlc string character/province Will never ever get evaluated if DLC is enabled/disabled by the player (or in the case of multiplayer, the host). Can be applied more than once per event, to filter based on many DLCs. NOT has_dlc
has_dlc string character/province has_dlc
friends bool character Checks whether the character has/doesn't have friends. num_of_friends = 0 or 1
rivals bool character Checks whether the character has/doesn't have rivals. num_of_rivals = 0 or 1
prisoner bool character If no, can't be applied to imprisoned characters. prisoner
ai bool character
  • If yes, will only fire for ai characters.
  • If no, will only fire for the player(s). Implies only_playable = yes.
ai
is_patrician bool character Checks if a character is the head of a Merchant Republic patrician family. Implies only_playable. is_patrician
is_female bool character If yes, will only affect female characters. Warning: now it raises an error in error.log, use only_men/only_women instead of it. is_female
is_married bool character is_married
is_sick bool [?] [?]
has_character_flag flag character Warning: more than 1 character_flag pre-trigger raises an error in error.log has_character_flag
has_global_flag flag character/province Checks whether the global flag has been set. has_global_flag
war bool character Checks whether the character is/isn't at war. war
culture culture character culture
culture_group culture_group character culture_group
is_in_society bool character [?]

Trigger[edit]

The trigger of an event is responsible for making sure the event is fired at the proper time on the proper character. There are many different conditions which can be used under 'trigger'. They all serve the purpose of adding flavor to the game. In some instances events may have the line: is_triggered_only = yes, this means that the event is triggered by the option of another event, therefore it will not fire unless the option in question is chosen by the character.

All events (except those with is_triggered_only = yes) need a trigger section. This defines when the event can trigger, and is where much of the power of event modding lies. Here you can check almost any condition, the only limit is the scopes and conditions you have available, and your creativity.

Below is an example trigger section:

trigger = {
	NOT = { wealth = -50 }
	NOT = { has_character_flag = loan_taken }
	OR = {
		NOT = { has_character_flag = loan_refused }
		had_character_flag = { flag = loan_refused days = 365 }
	}
}

Mean Time to Happen[edit]

Mean time to happen (MTTH) is a measure of how much time it takes, on average, for a random event to occur. The use of the "mean time to happen" value rather than probability allows modders and developers to specify how often they feel an event should occur, independent of the mechanics that make events fire. Thus, it removes the need for calculating probabilities while coding.

Like with the trigger, mean_time_to_happen has to be defined for any event that isn't is_triggered_only = yes. This section determines the average time it takes for an event to happen. This is typically defined in months, but can also be defined in days or years. It can be affected by modifiers depending on virtually any condition.

Below is an example section:

mean_time_to_happen = {
	months = 1
	modifier = {
		factor = 2 # Decreases chances by half
		some_condition = yes
	}
	modifier = {
		factor = 0.5 # Increases chances by half
		some_condition = yes
	}
}

Weight Multiplier[edit]

Weight multiplier is an alternative to mean-time-to-happen required by on_action events, introduced in patch 2.0. It is more efficient to handle by the engine and much faster than using events with a very low mean-time-to-happen to poll for changes. Events called by on_actions must use weight_multiplier instead of mean_time_to_happen. Although the engine does also support the use of weight multipliers for regular events instead of MTTH, it is not recommended for events with a low delay as they will queue up and then fire once per month in a large batch of popups. The Validator will report all such uses as an error.

Weight multiplier modifiers, as used by #on_action events, increase the chance of an event occurring, rather than increase the amount of time the event takes.

For example, this is an event in the game where the factors increase the chance of the event occurring, rather than increasing the amount of time the event takes:

# on_failed_assassination - maimed
character_event = {
	id = 158
	desc = "EVTDESC158"
	picture = "GFX_evt_shadow"
	
	hide_FROM = yes
	
	is_triggered_only = yes
	
	trigger = {
		NOT = { trait = maimed }
	}
	
	weight_multiplier = {
		days = 1
		modifier = {
			factor = 3
			trait = wounded
		}
	}
	
	immediate = {
		FROM = { character_event = { id = 40005 } }
	}

	option = {
		name = "EVTOPTA158"
		add_trait = maimed
	}
}

Immediate[edit]

Commands in the immediate = { } block are executed before the event is displayed (i.e even before description and title localization gets resolved).

Warning: when firing an event with no delay within immediate block, the new event actually uses the original event's scope (sort of like a sub-routine), rather than creating a copy of these scopes. This can lead to unexpected effects when used with event targets[3]

After[edit]

Commands in the after = { } block are executed after an option is selected and run, regardless of which option is chosen.

Options[edit]

Finally, every event needs one or more (maximum 4 eligible) option section. Once an option is selected, the associated effects will be applied.

The options listed in an event are arguably one of the most crucial parts of the event itself. They allow the player to decide upon which option best suites their current needs or wants, as well as occasionally forcing the character to choose an option depending on their traits and/or attributes.

The only requirement for an option is a name, but you'll typically want to define effects, as well as possibly a trigger which determines when the option shows up. Below is an example option section.

option = {
	name = "EVTOPTA38000" # Go to the moneylenders - Favorable terms
	trigger = {
		stewardship = 8
	}
	wealth = 200
	character_event = { id = 38001 days = 1825 tooltip = EVTTOOLTIP38001 }
	set_character_flag = loan_taken
	clr_character_flag = loan_refused
}

Option Name[edit]

The option name can be a set localisation key or dynamic based on meeting certain conditions

name= {
  text = EVTOPTA_case1_mymod.0001
  trigger = {
    #Conditions for 1st name to be chosen
  }
}

name = {
  text = EVTOPTA_case2_mymod.0001
  trigger = {
    #Conditions for 2nd name to be chosen
  }
}

AI chance[edit]

In order to help the AI choose the most rational option, ai_chance modifiers can be used.

Each option is weighted based on a base factor, that can be influenced by modifiers, and the chosen option is picked via a weighted random.

ai_chance = {
	factor = 10
	modifier = {
		factor = 0
		OR = {
			trait = gregarious
			trait = proud
			trait = ambitious
			trait = charitable
		}
	}
}

Type[edit]

Optionally, an option type can be specied via tooltip_info. It gives a colored border to the option, to indicate that it is only available due to specific conditions:

  • tooltip_info = <trait> : yellow border
  • tooltip_info = martial : red border
  • tooltip_info = stewardship : green border
  • tooltip_info = intrigue : purple border
  • tooltip_info = diplomacy : blue border
  • tooltip_info = learning : grey border

Tooltips[edit]

By default the normal tooltip of an option will show its effects. This can be customized with:

  • Hidden tooltips: allows to hide things from the player, typically the firing of an event.
hidden_tooltip = { province_event = { id = CM.1106 } }
  • Custom tooltips: simplifies some complex or hard to read effects, by replacing the tooltip content with a custom localized text.
custom_tooltip = { text = runestone_carved }

Note that both can be combined:

prestige = 50
custom_tooltip = {
	text = EVTTOOLTIPWOL11006
	hidden_tooltip = {
		any_realm_character = {
			opinion = {
				modifier = opinion_ruthless
				who = ROOT
				months = 60
			}
		}
	}
}

Tooltips can seem to be wrong when the event option both sets and reads a flag or updates and reads a variable in the same block. This is because to display the tooltip, the triggers in option block are executed, but not the commands (they will only when the option is actually chosen), so it may be inconsistent. Here is an example where tooltip cannot reflect what will actually happen:

option = {
	set_character_flag = flag_do_something # Not executed to calculate tooltip
	if = {
		limit  = { has_character_flag = flag_do_something } # Executed to calculate tooltip: will be false
		# Do it
	}
}

To resolve this use custom_tooltip, or move the commands that modify flags or variables to the immediate block.

Techniques[edit]

Ping events[edit]

Events with hide_window = yes can be used to get a specific character into the FROM scope (and the character portrait is, by default, the FROM character). So, by sending an event with hide_window = yes to the character you wish to be in the FROM scope (character A), and have that event's option send another event back to the original character B (which would be the FROM of the ping event), you can get A into the FROM scope for B's event. A can now be referenced in localisation and the event code. This can be useful:

  • when you are using any_ or random_ scopes and need to reference the any_ or random_ character in localisation. See the example code below
  • when you want to re-use an event chain, but have it triggered from different sources (for instance: MTTH, decision and on_action)
# Initial event that fires for character A 
# ROOT is character A
character_event = {
	id = 1
	(...)
	option = {
		name = OK
		random_realm_character = {
			# character B
			character_event = { id = 2 } # this is the ping event
		}
	}
}

# Ping event
# ROOT is character B
# FROM is character A
character_event = {
	id = 2
	hide_window = yes # description and portrait don't matter if it's hidden!

	immediate = {
		FROM = { 
			character_event = { id = 3 } 
		}
	}

	option = { name = OK } # must always have an option
}


# ROOT is character A
# FROM is character B
# Note: FROMFROM is character A
character_event = {
	id = 3

	# FROM can be be referenced in localisation and event code
	(...)
}

Many options[edit]

The 4th option of an event can call another event that has more options, allowing more than 4 options. The last option needs to cycle back to the 1st option.

Recursive events[edit]

repeat_event command with the current event ID can be used to fire an event recursively, with a delay. It fires in the specified scope as ROOT, but does not add a FROM to the stack, thus greatly reducing the risk of stack overflow in case of recursions.


On_action events[edit]

Events can be attached to on_action triggers that fire when hardcoded conditions are met. For instance on_marriage fires when two characters marry each other.

This allows to script events that need to happen instantly, and that would otherwise be impossible or very costly to trigger via normal MTTH events. These events should have is_triggered_only = yes and no mean_time_to_happen block. Note that the fast-triggers and the trigger block of these events will still be checked.

On_action event IDs are referenced by adding a new .txt file in common\on_actions folder (vanilla uses 00_on_actions.txt). There are 2 lists:

  • Events that systematically fire
  • Events that randomly fire based on specified default probability, modified by the weight_multiplier of the event.
<on_action_name> = {
	events = {
		#List of events that must always fire. 
		<event1>
		<event2>
	}
	random_events = {
		#List of events that may fire. Weight multiplier of each event will impact the probability of the event being selected.
		100 = <event3>
		50 = <event4>
		1 = <event5>
	}
}


List of on_action triggers[edit]

Name Description and scopes Category
on_startup Fires on game load. Warning: fires for all characters present at game start ! Control
on_yearly_pulse Fires every year Pulse
on_bi_yearly_pulse Fires every 2 years Pulse
on_five_year_pulse Fires every 5 years Pulse
on_decade_pulse Fires every 10 years Pulse
on_yearly_childhood_pulse For characters 2 to 16 years old Pulse
on_childhood_pulse Fires at ages 6 years plus six months, 8 years plus six months and 10 years plus six months Pulse
on_adolescence_pulse Fires at ages 12 years plus six months and 14 years plus six months Pulse
on_focus_pulse Yearly pulse (six months from on_yearly_pulse) intended for Focus events (only fires for characters with a Focus) Pulse
on_province_major_modifier Fires when a province modifier with major = yes is removed. Province
on_outbreak Fires when a new outbreak starts
  • ROOT is the province
  • token_data is the disease name
Province
on_combat_pulse
  • FROM is the opposing army's commander?
  • FROMFROM is the opposing army's liege?
Pulse,War
on_siege_pulse Pulse,War
on_battle_won
  • ROOT is any leader in battle on winning side
  • FROM is the opposing army's leader
War
on_major_battle_won
  • ROOT is any leader in battle on winning side
  • FROM is the opposing army's leader
War
on_battle_won_leader
  • ROOT is winning army leader
  • FROM is opponent army leader
War
on_major_battle_won_leader
  • ROOT is winning army leader
  • FROM is opponent army leader
War
on_battle_won_owner
  • ROOT is winning army owner
  • FROM is opponent army owner
War
on_battle_lost
  • ROOT is any leader in battle on losing side
  • FROM is the opposing army's owner
War
on_major_battle_lost
  • ROOT is any leader in battle on losing side
  • FROM is the opposing army's owner
War
on_battle_lost_leader
  • ROOT is losing army leader
  • FROM is the opposing army's leader
War
on_major_battle_lost_leader
  • ROOT is losing army leader
  • FROM is the opposing army's leader
War
on_battle_lost_owner
  • ROOT is losing army owner
  • FROM is opponent army owner
War
on_siege_won_leader
  • ROOT is the siege attacker
  • FROM is the barony won
War
on_siege_lost_leader
  • ROOT is the siege defender
  • FROM is the barony lost
War
on_siege_over_winner
  • ROOT is the owner of the winning unit
  • FROM is the taken holding title
War
on_siege_over_loc_chars Fires for all characters presumed to be in the Holding at the time.
  • ROOT is the local character
  • FROM is the lost holding title
  • new_character = Siege winner unit owner
War
on_failed_assassination
  • ROOT is the assassination target
  • FROM is the character plotting to assassinate
Plot
on_failed_assassination_disc
  • ROOT is the assassination target
  • FROM is the character plotting to assassinate
Plot
on_assassination
  • ROOT is the assassinated character
  • FROM is the character plotting to assassinate
Plot
on_assassination_disc
  • ROOT is the assassination target
  • FROM is the character plotting to assassinate
Plot
on_birth
  • ROOT is the baby

Note that in case of twin , on_birth events run for both twins, but on_post_birth events only run for the second of the twins (based on the ID number).[4][5]

Character
on_adulthood
  • ROOT is the child
Character
on_post_birth
  • ROOT is the baby

Note: see also on_birth.

Character
on_pregnancy At 2 months of pregnancy.
  • ROOT is the pregnant woman
Character
on_marriage Sent to liege of both spouses:
  • ROOT is the liege of the spouse
  • FROM is the spouse under ROOT liege
  • new_character is the other spouse
Character
on_become_imprisoned_any_reason Triggers when someone gets imprisoned for any reason.
  • ROOT is the prisoner
  • FROM is the imprisoner
Character
on_avoided_imprison_started_war Triggers if someone tries to imprison someone landed and fails. This leads to an automatic war declaration (independence)
  • ROOT is the rebelling character
  • FROM is the ruler who tried to imprison
War
on_became_imprisoned Triggers if someone becomes imprisoned by the diplo-action
  • ROOT is prisoner
  • FROM is imprisoner
Character
on_avoided_imprison_fled_country Triggers if someone tries to imprison someone unlanded and fails. Character is exiled to another country
  • ROOT is the fleeing character
  • FROM is the ruler who tried to imprison
Character
on_released_from_prison Triggers if someone is released from prison
  • ROOT is prisoner
  • FROM is imprisoner
Character
on_executed Triggers if someone is executed. [Executed before on_death?]
  • ROOT is the character executed
  • FROM is the ruler responsible for the execution
Character
on_exiled Triggers if someone is exiled
  • ROOT is the character exiled
Character
on_prepared_invasion_monthly Fires every month for characters who are preparing an invasion.
  • ROOT is the character preparing the invasion
  • FROM is the target character
War
on_prepared_invasion_aborts Fires if a prepared invasion becomes invalid.
  • ROOT is the character that was preparing the invasion
  • FROM is the target character
War
on_prepared_invasion_expires Fires if a prepared invasion expires.
  • ROOT is the character that was preparing the invasion
  • FROM is the target characterv
War
on_death Triggered before succession is dealt with (character still has their relevant flags and titles)
  • ROOT is the dead character
Succession
on_merc_rampage War
on_merc_leave War
on_merc_turn_coat_from War
on_merc_turn_coat_to War
on_holy_order_leave War
on_loot_settlement
  • ROOT is the raiding character
Holding
on_loot_province Fires when someone is looting currently in a province
  • ROOT is the looting character
  • FROM is the province
on_warleader_death Never triggered, but reserved for CB use War
on_approve_law Respond to a proposed change of de facto law
  • ROOT is a ruler in the realm of the title
  • FROM is the title
Realm
on_approve_de_jure_law Respond to a proposed change of de jure law
  • ROOT is a ruler in the de jure realm of the title
  • FROM is the title
Realm
on_rebel_revolt When rebels appear.
  • ROOT is the province
War
on_defect_to_rebels When province defects to rebels
  • ROOT is ?
  • FROM is the province
War
on_defect_from_rebels When rebels disperse
  • ROOT is ?
  • FROM is the province occupied by the rebels.
War
on_crusade_creation
  • ROOT is the religious head
  • FROM is the attacked kingdom title
  • new_character is the targeted enemy
Religion
on_crusade_invalid
  • ROOT is the religious head
  • FROM is the attacked kingdom title
  • new_character is the targeted enemy
Religion
on_crusade_success When a mission succeeds
  • ROOT is the target title
  • FROM is the taker
  • new_character is the Enemy
Religion
on_crusade_failure When a mission fails
  • ROOT is the target title
  • FROM is the head of religion
  • new_character is the Enemy
Religion
on_forced_consort When a pagan ruler forces a prisoner to be his consort
  • ROOT is the prisoner
  • FROM is the ruler
Character
on_reform_religion When a pagan religion is reformed and the old religion has become an heresy.
  • ROOT is the character triggering the reformation
Religion
on_county_religion_change When the religion changes in a county
  • ROOT is the county
Religion
on_vassal_accepts_religious_conversion When a character accepts religious conversion (the diplomatic action). Fires for the vassal and each of his courtiers and vassals.
  • ROOT is the character
  • FROM is the vassal
  • FROMFROM is the demander
Religion
on_heresy_takeover A heresy has become the new norm, replacing the old orthodoxy
  • ROOT is the character
  • FROM is a temporary character with heresy religion
  • FROMFROM is a temporary character with old orthodoxy religion
Religion
on_become_doge Fires for a newly elected Doge.
  • ROOT is the new doge
  • FROM is the previous (dying or abdicating) doge
Succession
on_elective_gavelkind_succession
  • ROOT is the vassal
  • FROM is the new liege
Succession
on_entering_port Fires when a navy moves into a port.
  • ROOT = unit scope
  • FROM = the owner
Units
on_rel_elector_chosen Fires when a cardinal is elected (SoA only).
  • ROOT is the new cardinal
  • FROM is the religious head
Religion
on_rel_head_chosen Fires when a Pope is elected (SoA only)
  • ROOT is the new elected Pope
  • FROM is the previous religious head
Religion
on_settlement_looted
  • ROOT is the looter
  • FROM is the settlement title
Holding
on_navy_returns_with_loot
  • ROOT is the navy's owner
  • FROM is the province
Units
on_create_title
  • ROOT is the creating character
  • FROM is the title
Succession
on_new_holder
  • ROOT is the character
  • FROM is the title
  • FROMFROM is the old holder
Succession
on_new_holder_inheritance
  • ROOT is the character
  • FROM is the title
  • FROMFROM is the old holder
Succession
on_new_holder_usurpation
  • ROOT is the character
  • FROM is the title
  • FROMFROM is the old holder
Succession
on_create_chronicle_if_empty Fires at the end of each year if the chronicle is empty Control
on_chronicle_owner_change Fires when the player changes character
  • FROM is the old character
  • ROOT is the new holder
Control
on_chronicle_start Fires when the game starts (not from saves) Control
on_character_convert_religion Character converts religion, for whatever reason.
  • ROOT is the character after conversion
  • FROM scope has the old religion.
Character,Religion
on_character_convert_culture Character converts culture, for whatever reason.
  • ROOT is the character after conversion
  • FROM scope has the old culture.
Character
on_acquire_nickname
  • ROOT is the character getting the nickname
Character
on_over_vassal_limit_succession Fires for vassals that can become independent as a result of liege being over vassal limit Sucession
on_war_started
  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_victory
  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_invalid
  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_whitepeace
  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_defeat
  • FROM is the attacker
  • ROOT is the defender
War
on_divorce Fires whenever a character gets divorced regardless of the reason:
  • FROM is the divorcer
  • ROOT is the spouse
  • new_character is the religious head, if applicable
Character
on_holding_building_start Fires whenever a character build something in a holding
  • ROOT is the builder
  • FROM is the holding title
Holding
on_settlement_construction_start Fires whenever the "construction" of a new settlement/holding starts
  • FROM is the title
  • ROOT is the builder
Holding
on_settlement_construction_completed Fires whenever the "construction" of a new settlement/holding is finished
  • FROM is the title
  • ROOT is the builder
Holding
on_trade_post_construction_start
  • FROM is the title
  • ROOT is the builder
Holding
on_trade_post_construction_completed
  • FROM is the title
  • ROOT is the builder
Holding
on_fort_construction_start
  • FROM is the title
  • ROOT is the builder
Holding
on_fort_construction_completed
  • FROM is the title
  • ROOT is the builder
Holding
on_feud_started
  • FROM is the target
  • ROOT is the starter
Relations
on_feud_ended
  • FROM is the target
  • ROOT is the ender
Relations
on_blood_brother_death Relations
on_ai_end_raid
  • ROOT is the AI character
Relations
on_mercenary_hired
  • ROOT is the mercenary captain
War
on_mercenary_dismissed
  • ROOT is the mercenary captain
War
on_mercenary_captain_replacement
  • ROOT is the old captain
  • FROM is the instigator
  • FROMFROM is the proposed captain
War
on_enforce_peace Conclave "enforce peace" mechanic Realm
on_enforce_peace_start Conclave "enforce peace" mechanic Realm
on_enforce_peace_six_vassals Conclave "enforce peace" mechanic Realm
on_law_vote_passed Realm
on_law_vote_failed Realm
on_player_mercenary_income Character
on_artifact_inheritance
  • FROMFROM is the predecessor
  • ROOT is the heir
Character

External links[edit]

References[edit]

  1. Forum:611797
  2. Official mod optimization tips
  3. forum:874495/page-22#post-20917926
  4. forum:882867
  5. forum:606906/page-105#post-21811833
Modding
CommandsConditionsScopesModifiersEventsDecisions
Gfx/Sfx/localisation