事件模组制作

本页面所适用的版本可能已经过时,最后更新于2.7
(重定向自事件模组修改


事件不仅功能强大,而且易于学习。

编写事件(或事件链)时,步骤通常如下:

  • 决定事件应该触发的对象:通常有多种方法来编写事件链脚本,但有些方法更高效/更简单!
  • 确定事件是自行触发还是由其他事件触发(根据On_action决议或其他事件)。
  • 如果它自行触发,请使用快速触发,以避免触发器为世界上的每一个角色进行评估。

完成脚本编写后,通常需要:

  • 运行The Validator以确保没有语法错误(以这种方式捕获错误要快得多,因为在游戏中测试效率不是很高)
  • 加载游戏,并使用控制台指令满足事件条件(可通过testevent <EventID> <CharOrProvID>查看)
  • 通过event <EventID> <CharOrProvID>手动触发该事件,以检查是否存在设计错误并验证本地化。

Structure

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

Type

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

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

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

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

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

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

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

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.png 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

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

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

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

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

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

Fail trigger effect

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

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

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

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

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

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

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

Ping events

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

	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

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

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

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

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

Name Description and scopes Category
on_startup Fires on game load (game start and loading from saves) for ALL characters (not only the player). BUG (as of version 3.2.1): at the start of the new game, it does not fire for courtiers that are not defined in the history files. It will fire for these character upon loading a save.

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_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_combat_starting
  • FROM is the character who is the commander of the opposing side
  • FROMFROM is the character who 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.png, 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_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 Fired 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
  • 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
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 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
  • 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 for the player character, when the game starts (but not when loading from saves). Also works when Charlemagne DLC is not active.

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

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_secret_religion Character converts to their secret religion.
  • 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

Offensive War 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

Offensive War Whitepeace

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

Offensive War 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 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_society_bi_yearly_pulse Bi-yearly pulse intended for Society events (only fires for characters in a 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_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_subunit 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_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 = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_destroyed Triggers when a wonder is destroyed.
  • ROOT = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_loot_start Triggers when looting of a wonder starts
  • ROOT = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_owner_change Triggers when a character becomes the owner of a wonder.
  • ROOT = new owner
  • FROM = wonder
  • FROMFROM = previous owner
  • FROMFROMFROM = province wonder is in
Wonder
on_wonder_renamed Triggers when a wonder is renamed
  • ROOT = owner
  • FROM = upgrade
  • FROMFROM = wonder
  • FROMFROMFROM = province (location of wonder)
Wonder
on_Wonder_restore_finish Triggers when resotration of a wonder finishes
  • ROOT = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_restore_start Triggers when resotration of a wonder starts
  • ROOT = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_stage_finish Triggers when a wonder finishes building a stage.
  • ROOT = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_stage_loot_finish Triggers when looting of a wonder stage finishes
  • ROOT = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_stage_loot_start Triggers when looting of a new wonder stage starts
  • ROOT = owner
  • FROM = wonder
  • FROMFROM = province (location of wonder)
Wonder
on_wonder_upgrade_destroyed Triggers when an upgrade is destroyed in a wonder.
  • ROOT = owner
  • FROM = upgrade
  • FROMFROM = wonder
  • FROMFROMFROM = province (location of wonder)
Wonder
on_wonder_upgrade_finish Triggers when a wonder upgrade finishes construction.
  • ROOT = owner
  • FROM = upgrade
  • FROMFROM = wonder
  • FROMFROMFROM = province (location of wonder)
Wonder
on_wonder_upgrade_start Triggers when construction of an upgrade begins in a wonder.
  • ROOT = owner
  • FROM = upgrade
  • FROMFROM = wonder
  • FROMFROMFROM = province (location of wonder)
Wonder

External links

References