Event modding

From Crusader Kings II Wiki
(Redirected from MTTH)
Jump to navigation Jump to search

Events are powerful for modding and easy to learn.

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

  • Decide for whom 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 prevent the trigger from being evaluated for EVERY single character in the world, which costs a lot of computer power.

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 | edit source]

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 | edit source]

Type[edit | edit source]

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
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 Used for notifications to diplomatic decisions, such as Declare War or Revoke Title. Can only be fired via on_action events. FROM is the character receiving the event, FROMFROM is the person sending the event. ROOT is empty or a third party, new_character is empty or a third party.
Vanilla frames: same as letter_event if associated with hardcoded decisions. Window is hidden otherwise.
unit_event Unit Used to unlock "Viking Raider" achievement. Can only be fired via on_action events. Warning: ROOT is the unit only when the event is fired via on_entering_port. Otherwise it's the owner.
Vanilla frames: same as character_event.
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 | edit source]

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 | edit source]

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 | edit source]

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
     }
}

Since 3.0, you can also have triggers on the pictures themselves, allowing you to define multiple pictures without having to go via event descriptions. Note that event description pictures will still take precedence.

character_event = {
	id = mymod.777
	desc = EVTDESCMYMOD777
	picture = { 
		trigger = { is_female = no } 
		picture = GFX_evt_battle_byzantine
	}
	picture = { 
		trigger = { is_female = yes } 
		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 event picture. To do so, make the picture 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 usually it is best to set it to be the same as the file name for simplicity.

Flags[edit | edit source]

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.
window gui Specifies the name of a GUI window to use, meaning an event can be given virtually any look.
background gfx Used with window. Specifies the background of the event and will also apply that GFX name + "_option" to the option buttons if GFX by that name exists.
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.
portrait character/title/offmap/none Determines which character is shown in the upper-right corner in a (long)_character_event, province_event, narrative_eventor the sole portrait in a letter_event. For an offmap power, will show the ruler of the offmap. Won't show anything if hide_from = yes is used. portrait = none is an alternative to hide_from = yes.
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.
offmap string If allow, the event can fire both for on-map rulers as well as offmap rulers. If only, the event will not fire for on-map rulers and will fire only for offmap rulers. If this flag is omitted, the event will never fire for offmap rulers.
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. Overrides portrait.
hide_new bool Suppresses default behaviour of showing newly created characters and saved event targets in place of ROOT's portrait.
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 | edit source]

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 | edit source]

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 | edit source]

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 and tributaries. 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
in_command bool character Example: in_command = no will make the event only trigger for people not commanding troops (since patch 3.0). Warning: not tested, seems to be buggy right now in_command
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 has_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. Warning: more than 1 has_global_flag pre-trigger raises an error in error.log 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 Checks whether the character belongs/doesn't belong to a society. is_in_society
has_quest_target bool character Yes will restrict the event to people that have a quest with an actual target. No will restrict the event to people that have a quest without a target or don't have a quest. [?]
has_job_title bool character has_job_title

Trigger[edit | edit source]

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 | edit source]

Mean time to happen (MTTH) is a measure of how much time it takes, on average, for a random event to occur. An MTTH of 90 days, for example, means that after 90 days, the probability of the event having been fired is exactly 50%. 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 | edit source]

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 | edit source]

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 | edit source]

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

Fail trigger effect[edit | edit source]

Commands in the fail_trigger_effect = { } block are executed if script attempts to trigger an event, but the trigger isn't fulfilled. Useful for handling things like one character in a chain dying for unrelated reasons partway through the chain.

Options[edit | edit source]

Finally, every event (with the exception of events with the hide_window = yes tag) 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 | edit source]

The option name can be a set localisation key or be 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 | edit source]

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
		}
	}
}

Portraits[edit | edit source]

If you want to show any portraits in options, you can do that by defining a scope in the option.

option = {
	name = EVTOPTXXX
	
	random_consort = {
		character_event = { id = EVTXXX }
	}
}

This code would show a portrait besides the option, and if clicked on it, would execute the event EVTXXX on the random consort of the event-taker. Some consequence must be defined in order for the portrait to show, and it must be defined directly inside the scope of that character, and not inside a subsequent scope. If you have nothing else you want to happen, you can always save the character as an event target that is never checked, which will cause the portrait to appear.

Option availability hint and border color[edit | edit source]

Optionally, an option can specify a border color and a tooltip like "This option is available because...", similar to the events which are available because your character has a special trait.

  • 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
  • tooltip_info = combat_rating : combat icon
  • tooltip_info_custom = <loc_key>

Option trait icons[edit | edit source]

Traits added or removed in the option have their icons shown. To show additional trait icons (e.g. ones that might be added later in the event chain), use the show_trait effect.

Techniques[edit | edit source]

Ping events[edit | edit source]

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)
  • when you want to hide portraits in your event's options. Replace the character scope with a character_event command, then put the original character scope in that new event that pings back. Often used for times when you don't want the player to know which character is getting pinged (e.g. a murder mystery event chain).
# 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 } 
		}
	}
}


# 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 | edit source]

Events have a maximum of 4 options at one time, but 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 | edit source]

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.


Turn by turn interactive event chains[edit | edit source]

Some restrictions apply when an event chain:

  • must be playable on both sides by 1 player (the chain can be initiated by the player OR the AI)
  • interacts between 2 (or more) players in a multiplayer game

For instance this would apply for an interactive duel by combat, a dice poker mini-game, etc.

The idea is that the result of any action taken by player A must be notified to player B, based on which B takes an action, which is notified to A, etc.

There is a single event chain that alternates between A and B in turns, until the chain reaches an exit condition (for instance a variable counting the number of turns). To reduce the scripting duplication, events may be designed to be re-used for both A and B, if the opponent is always kept into FROM scope (you don't know if ROOT is player A or player B).

Example of interactive loop (not showing the startup and conclusion events):

# Describe the previous action from FROM (if any), and ROOT takes an action
# FROM is the opponent
character_event = {
  id = event.1
  is_triggered_only = yes

  option = {
    name = event.1.a
    repeat_event = { id = event.2 } # use repeat_event to keep opponent as FROM
  }
  (...)
}

# Show result of own action
# FROM is the opponent
character_event = {
  id = event.2
  is_triggered_only = yes

  option = {
    name = event.2.a
    FROM = {
        character_event = { id = event.1 } # It's the opponent turn
    }
  }
  (...)
}

On_action events[edit | edit source]

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 mean-time-to-happen 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 3 lists:

  • Effects that are executed before any events are fired. Use scripted effects if there's any complex logic involved so as to not bloat the on_actions file.
  • Events that systematically fire.
  • Events that randomly fire based on specified default probability, modified by the weight_multiplier of the event. Within this list there can be different named blocks containing events. Only one event per block will be fired, if any. Blocks with the same name in the same on action in different files are merged.

The events and effects fire for the ROOT of the on_action.

The following code example will, for ROOT: execute effect1 before any events are fired; fire event1; fire event2; either fire event3 (50% chance), fire event2 (25% chance) or do nothing (25% chance); and, after 5 days, either fire event5 (50% chance) or do nothing (50% chance):

<on_action_name> = {
	effect = {
		# Effects to happen in the scope the on-action provides. Happens before any events.
		<effect1>
	}
	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, further modified by MTTH modifiers on the event.
		100 = <event3>
		50 = <event4>
		50 = 0 # Setting the right hand to 0 allows for the possibility of no event happening

		arbitrarily_named_block = {
			delay = 5 # How many days to delay the event. Useful to ensure the player doesn't get spammed with a bunch of events at the same time.
			1 = <event5>
			1 = 0
		}
	}
}


List of on_action triggers[edit | edit source]

Name Description and scopes Category
on_letter_event_message Used for hardcoded notification events. Unsynchronised, this message should not execute an event which changes the gamestate to prevent out of sync
on_character_event_message Used for hardcoded notification events. Unsynchronised, this message should not execute an event which changes the gamestate to prevent out of sync
on_startup Fires on game load (game start and loading from saves) for ALL characters (not only the player).

Note: Not called for ruler designed characters. Also see on_chronicle_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_adolescence Checked on 12th birthday Pulse
on_focus_pulse Yearly pulse (six months from on_yearly_pulse) for characters with a selected focus Pulse
on_focus_selected Fires when a character selects a focus
  • ROOT is character
Character
on_province_major_modifier Fires when a province modifier with major = yes is removed
  • ROOT is province
Province
on_outbreak Fires when a new outbreak starts
  • ROOT is the province
  • token_data is the disease name
Province
on_combat_pulse
  • ROOT is a character leading troops
  • FROM is the commander of the opposing side
  • FROMFROM is the liege of the commander of the opposing side
Pulse, war
on_combat_starting
  • ROOT is a character leading troops
  • FROM is the commander of the opposing side
  • FROMFROM is the liege of the commander of the opposing side
Pulse, war
on_siege_pulse Fires for both the attacking and defending siege leaders roughly every 10 days, attacker first
  • ROOT is the appropriate siege leader
  • FROM is empty! Get holding via location = { random_province_holding = { limit = { has_siege = yes } } }
Pulse, war
on_battle_won
  • ROOT is any leader (except the leader) in battle on winning side
  • FROM is the opponent army leader
War
on_major_battle_won
  • ROOT is any leader (except the leader) in battle on winning side
  • FROM is the opponent army leader
War
on_battle_won_leader
  • ROOT is winning army leader
  • FROM is the opponent army leader
War
on_major_battle_won_leader
  • ROOT is winning army leader
  • FROM is the 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 Fires for settlements.
  • ROOT is the siege attacker
  • FROM is the barony won
War
on_siege_won_leader_fort Fires for forts.
  • ROOT is the siege attacker
  • FROM is the fort's province
War
on_siege_won_leader_trade_post Fires for trade posts.
  • ROOT is the siege attacker
  • FROM is the trade post's province
War
on_siege_lost_leader Fires for settlements.
  • ROOT is the siege defender
  • FROM is the barony lost
War
on_siege_lost_leader_fort Fires for forts.
  • ROOT is the siege defender
  • FROM is the fort's province
War
on_siege_lost_leader_trade_post Fires for trade posts.
  • ROOT is the siege defender
  • FROM is the trade post's province
War
on_siege_over_winner Fires for settlements.
  • ROOT is the owner of the winning unit
  • FROM is the taken holding title
War
on_siege_over_winner_fort Fires for forts.
  • ROOT is the owner of the winning unit
  • FROM is the fort's province
War
on_siege_over_winner_trade_post Fires for trade posts.
  • ROOT is the owner of the winning unit
  • FROM is the trade post's province
War
on_siege_over_loc_chars Fires for all characters presumed to be in a settlement at the time.
  • ROOT is the local character
  • FROM is the lost holding title
  • new_character = Siege winner unit owner
War
on_siege_over_loc_chars_fort Fires for all characters presumed to be in the fort's province at the time.
  • ROOT is the local character
  • FROM is the fort's province
  • new_character = Siege winner unit owner
War
on_siege_over_loc_chars_trade_post Fires for all characters presumed to be in a trade post's province at the time.
  • ROOT is the local character
  • FROM is the trade post's province
  • 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
Character
on_post_birth_stillbirth
  • ROOT is the mother
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_betrothal Sent to liege of both betrothed
  • ROOT is the liege of the betrothed
  • FROM is the betrothed under ROOT liege
  • new_character is the other betrothed
Character
on_become_imprisoned_any_reason Fires when someone gets imprisoned for any reason
  • ROOT is the prisoner
  • FROM is the imprisoner
Character
on_avoided_imprison_started_war Fires 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 Fires if someone becomes imprisoned by the diplo-action
  • ROOT is prisoner
  • FROM is imprisoner
Character
on_avoided_imprison_fled_country Fires 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 Fires if someone is released from prison
  • ROOT is prisoner
  • FROM is imprisoner
Character
on_executed Fires if someone is executed. [Executed before on_death?]
  • ROOT is the character executed
  • FROM is the ruler responsible for the execution
Character
on_exiled Fires 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 Fires just before a character dies (character still has their relevant flags and titles)
  • ROOT is the dead character
Character
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 Fires when a holding is burned down
  • ROOT is the raiding character
  • FROM is the looted settlement
Holding
on_loot_province Fires when someone is looting currently in a province
  • ROOT is the looting character
  • FROM is the province
Holding
on_settlement_looted
  • ROOT is the looter
  • FROM is the settlement title
Holding
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 Fires when a province rebels
  • ROOT is the province
War
on_defect_to_rebels Fires when province defects to rebels. Fires for any ruler owning a holding in the province.
  • ROOT is the local ruler
  • FROM is the province
War
on_defect_from_rebels Fires when province defects to rebels. Fires for any ruler owning a holding in the province.
  • ROOT is the local ruler
  • FROM is the province occupied by the rebels
War
on_crusade_creation Fires when a crusade war is declared
  • ROOT is the religious head
  • FROM is the attacked kingdom title
  • new_character is the targeted enemy
Religion
on_crusade_invalid Fires when a crusade war is invalidated
  • ROOT is the religious head
  • FROM is the attacked kingdom title
  • new_character is the targeted enemy
Religion
on_crusade_success Fires when a crusade war ends in victory
  • ROOT is the target title
  • FROM is the taker
  • new_character is the Enemy
Religion
on_crusade_failure Fires when a crusade war ends in defeat
  • 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 the new heresy religion scope
  • FROMFROM is the new parent religion scope
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 Fires when secondary heirs become vassals to a sibling due to 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_navy_returns_with_loot
  • ROOT is the navy's owner
  • FROM is the province
Units
on_create_title Fires whenever a title is created by a character
  • ROOT is the creating character
  • FROM is the title
TItles
on_new_holder Fires whenever a title changes holder other than by inheritance and usurpation
  • ROOT is the character
  • FROM is the title
  • FROMFROM is the old holder
TItles
on_new_holder_inheritance Fires whenever a title changes holder by inheritance
  • ROOT is the character
  • FROM is the title
  • FROMFROM is the old holder
TItles
on_new_holder_usurpation Fires whenever a title changes holder by usurpation
  • ROOT is the character
  • FROM is the title
  • FROMFROM is the old holder
TItles
on_unlanded Fires when a character loses their last landed title (barony or county). Character may still be a landless ruler!
  • ROOT is unlanded character
TItles
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 a new game starts. Does not require Charlemagne DLC.

Note: For ruler designed characters, fires twice (for the historical character and player ruler designed character).

  • ROOT is player character
Control
on_character_convert_religion Character converts religion, for whatever reason
  • ROOT is the character after conversion
  • FROM is the old religion.
Character, religion
on_character_convert_secret_religion Character converts to their secret religion
  • ROOT is the character after conversion
  • FROM is the old religion.
Character, religion
on_character_convert_culture Character converts culture, for whatever reason
  • ROOT is the character after conversion
  • FROM is 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 Fires whenever a war is started
  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_victory

Fires whenever a war ends in victory for the attacker

  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_invalid Fires whenever a war ends inconclusively due to unmet <code>is_valid(_title)</code> triggers
  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_whitepeace

Fires whenever a war ends in white peace

  • FROM is the attacker
  • ROOT is the defender
War
on_war_ended_defeat

Fires whenever a war ends in defeat for the attacker

  • 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 starts construction of a building 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 completed
  • FROM is the title
  • ROOT is the builder
Holding
on_trade_post_construction_start Fires when construction of a trade post is started
  • FROM is the title
  • ROOT is the builder
Holding
on_trade_post_construction_completed Fires when construction of a trade post is completed
  • FROM is the title
  • ROOT is the builder
Holding
on_fort_construction_start Fires when construction of a fort is started
  • FROM is the title
  • ROOT is the builder
Holding
on_fort_construction_completed Fires when construction of a fort is completed
  • FROM is the title
  • ROOT is the builder
Holding
on_hospital_construction_start Fires when construction of a hospital is started
  • ROOT is builder
  • FROM is province
on_hospital_construction_completed Fires when construction of a hospital is started
  • ROOT is builder
  • FROM is province
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
  • ROOT is surviving blood brother
  • FROM is dead blood brother
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 Fires when realm peace is announced
  • ROOT is primary title of liege
Realm
on_enforce_peace_start Fires when realm peace is enforced
  • ROOT is primary title of liege
Realm
on_enforce_peace_six_vassals Fires when a ruler enforces peace for at least six vassals simultaneously. Only used for the related achievement.
  • ROOT is character enforcing peace
Realm
on_law_vote_passed Fires whenever a council vote is passed
  • ROOT is the title holder that had a law pass, and the token for the law
  • FROM is the character who started the vote
  • FROMFROM is the title itself
Realm
on_law_vote_failed Fires whenever a council vote is rejected
  • ROOT is the title holder that had a law pass, and the token for the law
  • FROM is the character who started the vote
  • FROMFROM is the title itself
Realm
on_player_mercenary_income Fires whenever a player receives income from a created and controlled mercenary band
  • ROOT is player who received income from assembled mercenary band
Character
on_artifact_inheritance Fired whenever a character receives an artifact (one for each artifact)
  • ROOT is the character
  • FROM is the artifact
  • FROMFROM is the old artifact holder
Character
on_character_ask_to_join_society Fires when a player asks to join a society
  • ROOT is character
  • FROM is society
Society
on_character_join_society Fires when a character joins a society. <code>has_game_started</code> can be useful to avoid firing events from auto-assignment of characters at game start
  • ROOT is character
  • FROM is society
Society
on_character_kicked_from_society Fires when a character is removed from society for failing the <code>potential</code> trigger
  • ROOT is character
  • FROM is society
Society
on_character_leave_society Fires when a character leaves or is forced to leave a society
  • ROOT is character
  • FROM is society
Society
on_character_society_rank_down Fires when a character ranks down in their society
  • ROOT is character
  • FROM is society
Society
on_character_society_rank_up Fires when a character ranks up in their society, or becomes grandmaster
  • ROOT is character
  • FROM is society
Society
on_character_stop_showing_interest A character stops showing interest in a society for failing the <code>can_join_society</code> trigger.
  • ROOT is character
  • FROM is society
Society
on_character_switch_society_interest Fires when a character has switched their society interest
  • ROOT is character
  • FROM is society
Society
on_society_bi_yearly_pulse Fires every two years for characters who are members of any society Pulse, society
on_society_created Fires when someone joins a society with no members.
  • ROOT is the character
  • FROM is the society
Society
on_society_destroyed Fires when the last member of a society leaves the society and is not replaced
  • ROOT is the character
  • FROM is the society
Society
on_society_failed_to_find_new_leader Fires when a indestructable society fails to find a new leader from existing characters.
  • ROOT is the society
  • FROM is the society's previous leader
Society
on_society_progress_full Fires when a society's progress is increased/set to the value 100.
  • ROOT is the society's leader
  • FROM is the society
Society
on_society_progress_zero Fires when a society's progress is decreased/set to the value 0.
  • ROOT is the society's leader
  • FROM is the society
Society
on_quest_success A character succeeds in a quest. This happens just before the quest disappears, so you can access the quest itself. Only invoked when a quest is cleared via script. E.G., does not happen on death
  • ROOT is character
on_quest_failure A character fails a quest. This happens just before the quest disappears, so you can access the quest itself. Only invoked when a quest is cleared via script. E.G., does not happen on death
  • ROOT is character
on_offmap_policy_changed Fires for an offmap power's governor when the power changes its policy.
  • ROOT is the governor
  • FROM is the offmap
Offmap
on_offmap_status_changed Fires for an offmap power's governor when the power changes its status.
  • ROOT is the governor
  • FROM is the offmap
Offmap
on_offmap_governor_changed Fires for an offmap power's new governor when the power changes its governor.
  • ROOT is the new governor
  • FROM is the old governor
  • FROMFROM is the offmap
Offmap
on_offmap_ruler_changed Fires for an offmap power's new ruler when the power changes its ruler.
  • ROOT is the new ruler
  • FROM is the old ruler
  • FROMFROM is the offmap
Offmap
on_offmap_monthly_pulse Fires for an offmap power's governor once per month on a random day.
  • ROOT is the governer
  • FROM is the offmap
Offmap
on_offmap_yearly_pulse Fires for an offmap power's governor once per year during a random monthly update.
  • ROOT is the governer
  • FROM is the offmap
Offmap
on_eu4_conversion_start Fires for the player (or a random character if in observe mode) just prior to the EU4 converter converting the game. Can be used to prepare the gamestate for EU4 conversion, then restore the original state.
  • ROOT is the character
EU4 Converter
on_eu4_conversion_done Fires for the player (or a random character if in observe mode) just after the EU4 converter is done converting the game.
  • ROOT is the character
EU4 Converter
on_tyranny_gained Fires for every character that gets the tyrant opinion penalty towards the tyrant when tyranny is caused by the code rather than script. Won't fire if you use add_opinion_modifer to add tyrrany.
  • ROOT is the upset character
  • FROM is the tyrant
Character
on_tyranny_gained_tyrant_only Fires once for the tyrant when tyranny is caused by the code rather than script. Won't fire if you use add_opinion_modifer to add tyrrany.
  • ROOT is the tyrant
Character
on_revoke_attempted_started_war Fires for the character refusing a revoke title attempt and declaring war over it.
  • ROOT is the character declaring the war
  • FROM is the revoker
  • FROMFROM is the title being revoked
War
on_retract_vassal_attempted_started_war Fires for the character refusing a retract vassalage attempt and declaring war over it.
  • ROOT is the character declaring the war
  • FROM is the revoker
  • FROMFROM is the vassal title being retracted
War
on_absorb_clan_attempted_started_war Fires for the character refusing an absorb clan attempt and declaring war over it.
  • ROOT is the character declaring the war
  • FROM is the absorber
War
on_split_clan_attempted_started_war Fires for the character refusing a split clan attempt and declaring war over it.
  • ROOT is the character declaring the war
  • FROM is the splitter
War
on_unit_entering_province Fires for all characters in a unit (leading a flank or subunit) when it enters a province.
  • ROOT is the character
War
on_command_unit Fires for a character when they are put in command of a flank.
  • ROOT is the character
War
on_command_sub_unit Fires for a character when they are put in command of a subunit.
  • ROOT is the character
War
on_alternate_start Fires for the very first character generated in a Random/Shattered World at the end of game setup (just before the Welcome screen is shown).
  • ROOT is the very first character created
Alternate Start
on_crusade_preparation_starts Fires when a Crusade begins preparation. Fires for all Crusades/Jihads/GHWs regardless if they have a preparation phase - use uses_new_crusade = yes trigger to limit effects.
  • ROOT is the religious head
War, Crusade
on_crusade_preparation_ends Fires when a Crusade ends preparation.
  • ROOT is the religious head
War, Crusade
on_crusade_canceled Fires when a Crusade is canceled.
  • ROOT is the religious head
War, Crusade
on_crusade_monthly Fires once a month while a Crusade is preparing or active.
  • ROOT is the religious head
War, Crusade
on_crusade_target_changes Fires when the target of a Crusade chages (either through script or invalidation, or the target's heir inheriting). Happens immediately after the crusade_target_char and crusade_target_title scopes are updated).
  • ROOT is the religious head
  • FROM is the previous target character
  • FROMFROM is the previous target title
  • FROMFROMFROM is the character who made the change, if via diplomatic action; otherwise undefined
War, Crusade
on_crusade_launches Fires when Crusade preparation ends
  • ROOT is the religious head
War, Crusade
on_pledge_crusade_participation Fires when a character pledges their participation, even if the war has started. Does not fire when the character is auto-pledged due to joining the war.
  • ROOT is the character
War, Crusade
on_pledge_crusade_defense Fires when a character pledges their defense of the crusade target, even if the war has started. Does not fire when the character is auto-pledged due to joining the war.
  • ROOT is the character
War, Crusade
on_unpledge_crusade_participation Fires when a character unpledges their participation, including the automatic unpledging on death and conversion.
  • ROOT is the character
War, Crusade
on_unpledge_crusade_defense Fires when a character unpledges their defense, including the automatic unpledging on death and conversion.
  • ROOT is the character
War, Crusade
on_excommunicate_interaction Fires when someone is excommunicated via the hardcoded diplomatic interaction.
  • ROOT is the excommunicated character
  • FROM is the asker
  • FROMFROM is the Pope
Religion
on_character_renamed Fires when a player renames a character. This includes the "newborn" event.
  • ROOT is the renamed character
Control
on_title_renamed Fires when a player renames a title. This includes renaming via the title screen.
  • ROOT is the renamed title
Control
on_province_renamed Fires when a player renames a province. This includes renaming via the province view.
  • ROOT is the renamed province
Control
on_artifact_renamed Fires when a player renames an artifact.
  • ROOT is the renamed artifact
Control
on_bloodline_renamed Fires when a player renames a bloodline.
  • ROOT is the renamed bloodline
Control
on_employer_change Fires when a change of employer has been detected. With trigger = { FROM = { character = no } } this can be used to fire an event for any newly-spawned character, but not necessarily those created through hardcoded means.
  • ROOT is the character that got a new employer
  • FROM is the previous employer; if newly created, undefined
  • FROMFROM is the new employer
Character
on_host_change Fires when a change of host has been detected. on_employer_change is fired first if a character has had both their employer and host changed since the last check was made. With trigger = { FROM = { character = no } } this can be used to fire an event for any newly-spawned character, including those created through hardcoded means.
  • ROOT is the character that got a new host
  • FROM is the previous host; if newly created, undefined
  • FROMFROM is the new host
Character
on_wonder_construction_start Triggers when a wonder begins construction of any stage.
  • ROOT is owner
  • FROM is wonder
  • FROMFROM is province (location of wonder)
Wonder
on_wonder_destroyed Triggers when a wonder is destroyed.
  • ROOT is owner
  • FROM is wonder
  • FROMFROM is province (location of wonder)
Wonder
on_wonder_loot_start Triggers when looting of a wonder starts
  • ROOT is owner
  • FROM is wonder
  • FROMFROM is province (location of wonder)
Wonder
on_wonder_owner_change Triggers when a character becomes the owner of a wonder.
  • ROOT is new owner
  • FROM is wonder
  • FROMFROM is previous owner
  • FROMFROMFROM is province (location of wonder)
Wonder
on_wonder_renamed Triggers when a wonder is renamed
  • ROOT is owner
  • FROM is upgrade
  • FROMFROM is wonder
  • FROMFROMFROM is province (location of wonder)
Wonder
on_wonder_restore_finish Triggers when restoration of a wonder finishes
  • ROOT is owner
  • FROM is wonder
  • FROMFROM =isprovince (location of wonder)
Wonder
on_wonder_restore_start Triggers when restoration of a wonder starts
  • ROOT is owner
  • FROM is wonder
  • FROMFROM is province (location of wonder)
Wonder
on_wonder_stage_finish Triggers when a wonder finishes building a stage.
  • ROOT is owner
  • FROM is wonder
  • FROMFROM is province (location of wonder)
Wonder
on_wonder_stage_loot_finish Triggers when looting of a wonder stage finishes
  • ROOT is owner
  • FROM is wonder
  • FROMFROM is province (location of wonder)
Wonder
on_wonder_stage_loot_start Triggers when looting of a new wonder stage starts
  • ROOT is owner
  • FROM is wonder
  • FROMFROM is province (location of wonder)
Wonder
on_wonder_upgrade_destroyed Triggers when an upgrade is destroyed in a wonder.
  • ROOT is owner
  • FROM is upgrade
  • FROMFROM is wonder
  • FROMFROMFROM is province (location of wonder)
Wonder
on_wonder_upgrade_finish Triggers when a wonder upgrade finishes construction.
  • ROOT is owner
  • FROM is upgrade
  • FROMFROM is wonder
  • FROMFROMFROM is province (location of wonder)
Wonder
on_wonder_upgrade_start Triggers when construction of an upgrade begins in a wonder.
  • ROOT is owner
  • FROM is upgrade
  • FROMFROM is wonder
  • FROMFROMFROM is province (location of wonder)
Wonder

Additionally, all hardcoded diplomatic interactions come with associated on_actions. For most of these, the following information applies, but there rare exceptions. Always test if fired events function correctly!

  • Starting scope is the same character as FROMFROM
  • FROM is the character recieving the event
  • FROMFROM is the person sending the event
  • ROOT is empty or a third party
  • new_character is empty or a third party
ABANDON_AMBITION_INTERACTION_ACCEPT_EVENT
ABANDON_AMBITION_INTERACTION_DECLINE_EVENT
ABSORB_CLAN_INTERACTION_ACCEPT_EVENT
ABSORB_CLAN_INTERACTION_DECLINE_EVENT
APPOINT_COMMANDER_INTERACTION_ACCEPT_EVENT
APPOINT_TO_OFFICE_INTERACTION_ACCEPT_EVENT
APPOINT_TO_OFFICE_INTERACTION_DECLINE_EVENT
ARRANGE_BETROTHAL_INTERACTION_ACCEPT_EVENT
ARRANGE_BETROTHAL_INTERACTION_DECLINE_EVENT
ARRANGE_SUCC_BETROTHAL_INTERACTION_ACCEPT_EVENT
ARRANGE_SUCC_BETROTHAL_INTERACTION_DECLINE_EVENT
ASK_COUNCIL_POSITION_INTERACTION_ACCEPT_EVENT
ASK_COUNCIL_POSITION_INTERACTION_DECLINE_EVENT
ASK_FOR_CLAIM_INTERACTION_ACCEPT_EVENT
ASK_FOR_CLAIM_INTERACTION_DECLINE_EVENT
ASK_FOR_CRUSADE_INTERACTION_ACCEPT_EVENT
ASK_FOR_CRUSADE_INTERACTION_DECLINE_EVENT
ASK_FOR_DIVORCE_INTERACTION_ACCEPT_EVENT
ASK_FOR_DIVORCE_INTERACTION_DECLINE_EVENT
ASK_FOR_EXCOMMUNICATION_INTERACTION_ACCEPT_EVENT
ASK_FOR_EXCOMMUNICATION_INTERACTION_DECLINE_EVENT
ASK_FOR_INVASION_INTERACTION_ACCEPT_EVENT
ASK_FOR_INVASION_INTERACTION_DECLINE_EVENT
ASK_FOR_MONEY_INTERACTION_ACCEPT_EVENT
ASK_FOR_MONEY_INTERACTION_DECLINE_EVENT
ASK_FOR_VASSALIZATION_INTERACTION_ACCEPT_EVENT
ASK_FOR_VASSALIZATION_INTERACTION_DECLINE_EVENT
ASK_REALM_PEACE_INTERACTION_ACCEPT_EVENT
ASK_REALM_PEACE_INTERACTION_DECLINE_EVENT
ASK_TO_DECLARE_WAR_INTERACTION_ACCEPT_EVENT
ASK_TO_DECLARE_WAR_INTERACTION_DECLINE_EVENT
ASK_TO_EMBARGO_INTERACTION_ACCEPT_EVENT
ASK_TO_EMBARGO_INTERACTION_DECLINE_EVENT
ASK_TO_JOIN_AMBITION_INTERACTION_ACCEPT_EVENT
ASK_TO_JOIN_AMBITION_INTERACTION_DECLINE_EVENT
ASK_TO_JOIN_WAR_INTERACTION_ACCEPT_EVENT
ASK_TO_JOIN_WAR_INTERACTION_DECLINE_EVENT
ASK_TO_LIFT_EXCOMMUNICATION_INTERACTION_ACCEPT_EVENT
ASK_TO_LIFT_EXCOMMUNICATION_INTERACTION_DECLINE_EVENT
ASK_TO_RANSOM_CHARACTER_INTERACTION_ACCEPT_EVENT
ASK_TO_RANSOM_CHARACTER_INTERACTION_DECLINE_EVENT
ASSIGN_VOTER_TITLE_INTERACTION_ACCEPT_EVENT
AWARD_HONORARY_TITLE_INTERACTION_ACCEPT_EVENT
BREAK_BETROTHAL_INTERACTION_ACCEPT_EVENT
BUY_FAVOR_INTERACTION_ACCEPT_EVENT
BUY_FAVOR_INTERACTION_DECLINE_EVENT
CALL_ALLY_INTERACTION_ACCEPT_EVENT
CALL_ALLY_INTERACTION_DECLINE_EVENT
CALL_IN_FAVOR_INTERACTION_ACCEPT_EVENT
CALL_IN_FAVOR_SUCCESSION_VOTE_ACCEPT_EVENT
CHANGE_CRUSADE_TARGET_INTERACTION_ACCEPT_EVENT
councilor_on_approve_law
DECLARE_WAR_INTERACTION_ACCEPT_EVENT
DEMAND_RELIGIOUS_CONVERSION_INTERACTION_ACCEPT_EVENT
DEMAND_RELIGIOUS_CONVERSION_INTERACTION_DECLINE_EVENT
DISMISS_CONSORT_INTERACTION_ACCEPT_EVENT
DISSOLVE_ALLIANCE_INTERACTION_ACCEPT_EVENT
DISSOLVE_ALLIANCE_INTERACTION_DECLINE_EVENT
DIVORCE_INTERACTION_ACCEPT_EVENT
EDUCATE_CHARACTER_INTERACTION_ACCEPT_EVENT
EDUCATE_CHARACTER_INTERACTION_DECLINE_EVENT
EXECUTE_IMPRISONED_INTERACTION_ACCEPT_EVENT
EXILE_IMPRISONED_INTERACTION_ACCEPT_EVENT
FORCE_JOIN_FACTION_INTERACTION_ACCEPT_EVENT
FORCE_JOIN_FACTION_INTERACTION_DECLINE_EVENT
FORM_ALLIANCE_INTERACTION_ACCEPT_EVENT
FORM_ALLIANCE_INTERACTION_DECLINE_EVENT
FORM_BLOOD_OATH_INTERACTION_ACCEPT_EVENT
FORM_BLOOD_OATH_INTERACTION_DECLINE_EVENT
FORM_NON_AGGRESSION_PACT_INTERACTION_ACCEPT_EVENT
FORM_NON_AGGRESSION_PACT_INTERACTION_DECLINE_EVENT
GIVE_ARTIFACT_INTERACTION_ACCEPT_EVENT
GRANT_LANDED_TITLE_INTERACTION_ACCEPT_EVENT
GRANT_VICE_ROYALTY_INTERACTION_ACCEPT_EVENT
IMPRISON_INTERACTION_ACCEPT_EVENT
INVITE_TO_COURT_INTERACTION_ACCEPT_EVENT
INVITE_TO_COURT_INTERACTION_DECLINE_EVENT
JOIN_AMBITION_INTERACTION_ACCEPT_EVENT
JOIN_AMBITION_INTERACTION_DECLINE_EVENT
LEAVE_COALITION_ACCEPT_EVENT
MAKE_CONSORT_INTERACTION_ACCEPT_EVENT
MAKE_CONSORT_INTERACTION_DECLINE_EVENT
NOMINATE_BISHOP_TO_POPE_INTERACTION_ACCEPT_EVENT
NOMINATE_BISHOP_TO_POPE_INTERACTION_DECLINE_EVENT
OFFER_CONSORT_INTERACTION_ACCEPT_EVENT
OFFER_MARRIGE_INTERACTION_ACCEPT_EVENT
OFFER_MARRIGE_INTERACTION_DECLINE_EVENT
OFFER_PEACE_INTERACTION_ACCEPT_EVENT
OFFER_PEACE_INTERACTION_DECLINE_EVENT
OFFER_SUCCESSION_MARRIGE_INTERACTION_ACCEPT_EVENT
OFFER_SUCCESSION_MARRIGE_INTERACTION_DECLINE_EVENT
OFFER_VASSALIZATION_INTERACTION_ACCEPT_EVENT
OFFER_VASSALIZATION_INTERACTION_DECLINE_EVENT
PREPARE_INVASION_INTERACTION_ACCEPT_EVENT
RANSOM_CHARACTER_INTERACTION_ACCEPT_EVENT
RANSOM_CHARACTER_INTERACTION_DECLINE_EVENT
RELEASE_FROM_PRISON_INTERACTION_ACCEPT_EVENT
RELEASE_VASSAL_INTERACTION_ACCEPT_EVENT
REPLACE_MERCENARY_CAPTAIN_INTERACTION_ACCEPT_EVENT
REQUEST_SUPPORT_INTERACTION_ACCEPT_EVENT
REQUEST_SUPPORT_INTERACTION_DECLINE_EVENT
RESIGN_AS_COMMANDER_INTERACTION_ACCEPT_EVENT
RESIGN_COMMANDER_INTERACTION_ACCEPT_EVENT
RESIGN_FROM_OFFICE_INTERACTION_ACCEPT_EVENT
RETRACT_VASSAL_INTERACTION_ACCEPT_EVENT
RETRACT_VASSAL_INTERACTION_DECLINE_EVENT
REVOKE_HONORARY_TITLE_INTERACTION_ACCEPT_EVENT
REVOKE_TITLE_INTERACTION_ACCEPT_EVENT
REVOKE_TITLE_INTERACTION_DECLINE_EVENT
REVOKE_VOTER_TITLE_INTERACTION_ACCEPT_EVENT
SEND_ASSASSIN_INTERACTION_ACCEPT_EVENT
SEND_GIFT_INTERACTION_ACCEPT_EVENT
SEND_GIFT_INTERACTION_DECLINE_EVENT
SETTLE_ADVENTURER_INTERACTION_ACCEPT_EVENT
SETTLE_ADVENTURER_INTERACTION_DECLINE_EVENT
SETTLE_FEUD_INTERACTION_ACCEPT_EVENT
SETTLE_FEUD_INTERACTION_DECLINE_EVENT
SPLIT_CLAN_INTERACTION_ACCEPT_EVENT
SPLIT_CLAN_INTERACTION_DECLINE_EVENT
START_COALITION_ACCEPT_EVENT
STOP_BACKING_AMBITION_INTERACTION_ACCEPT_EVENT
STOP_BACKING_AMBITION_INTERACTION_DECLINE_EVENT
STOP_ENFORCE_PEACE_INTERACTION_ACCEPT_EVENT
TRANSFER_VASSAL_INTERACTION_ACCEPT_EVENT

Date calculations for time based pulses like "on_yearly_pulse"[edit | edit source]

[6]

The date when the time based pulses fire for a specific character seem to be dependent on the <Character ID> of the character the pulse fires for and the <Year> the pulse fires in. These seem to be the respective formulas:

on_year_pulse:
day: ((<Character ID>) mod 28) + 1 ; month: ((<Character ID> + <Year>) mod 12) + 1

on_focus_pulse:
day: ((<Character ID>) mod 28) + 1 ; month : ((<Character ID> + <Year> + 6) mod 12) + 1

on_bi_yearly_pulse:
day: ((<Character ID>) mod 28) + 1 ; month : ((<Character ID> + <Year> + 6) mod 12) + 1

on_five_year_pulse:
day: ((<Character ID>) mod 28) + 1 ; month: ((<Character ID> + <Year>) mod 12) + 1

on_decade_pulse:
day: ((<Character ID>) mod 28) + 1 ; month: ((<Character ID> + <Year> + 3) mod 12) + 1

on_society_bi_yearly_pulse:
day: ((<Character ID>) mod 28) + 1 ; month: ((<Character ID> + <Year> + 8) mod 12) + 1

on_yearly_childhood_pulse:
day: ((<Character ID>) mod 28) + 1 ; month: ((<Character ID> + <Year> + 11) mod 12) + 1

Where day: 1, month: 1 means 1st of January; day: 5, month: 2 means 5th of February; day: 28, month: 11 means 28th of November and so on.

Note that "on_yearly_childhood_pulse" fires only for characters within a certain age-range (cf. Crusader Kings II/common/on_actions/00_on_actions.txt )


The years in which the non-yearly pulses fire seem to be determined by the following rules:

on_bi_yearly_pulse:
(<Character ID> - <Year>) mod 2 == 0

on_society_bi_yearly_pulse:
(<Character ID> - <Year>) mod 2 == 1

on_five_year_pulse:
(<Character ID> - <Year>) mod 5 == 0

on_decade_pulse:
(<Character ID> - <Year>) mod 10 == 0

That means for "on_bi_yearly_pulse" the difference between the <Character ID> and the <Year> needs to be divisible by 2, for "on_five_yearly_pulse" the difference between the <Character ID> and the <Year> needs to be divisible by 5, and for "on_decade_pulse" the difference between the <Character ID> and the <Year> needs to be divisible by 10.

External links[edit | edit source]

References[edit | edit source]